jquery-ui.custom.js 134 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785
  1. /*! jQuery UI - v1.10.4 - 2014-04-08
  2. * http://jqueryui.com
  3. * Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.button.js, jquery.ui.slider.js, jquery.ui.spinner.js
  4. * Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
  5. (function( $, undefined ) {
  6. var uuid = 0,
  7. runiqueId = /^ui-id-\d+$/;
  8. // $.ui might exist from components with no dependencies, e.g., $.ui.position
  9. $.ui = $.ui || {};
  10. $.extend( $.ui, {
  11. version: "1.10.4",
  12. keyCode: {
  13. BACKSPACE: 8,
  14. COMMA: 188,
  15. DELETE: 46,
  16. DOWN: 40,
  17. END: 35,
  18. ENTER: 13,
  19. ESCAPE: 27,
  20. HOME: 36,
  21. LEFT: 37,
  22. NUMPAD_ADD: 107,
  23. NUMPAD_DECIMAL: 110,
  24. NUMPAD_DIVIDE: 111,
  25. NUMPAD_ENTER: 108,
  26. NUMPAD_MULTIPLY: 106,
  27. NUMPAD_SUBTRACT: 109,
  28. PAGE_DOWN: 34,
  29. PAGE_UP: 33,
  30. PERIOD: 190,
  31. RIGHT: 39,
  32. SPACE: 32,
  33. TAB: 9,
  34. UP: 38
  35. }
  36. });
  37. // plugins
  38. $.fn.extend({
  39. focus: (function( orig ) {
  40. return function( delay, fn ) {
  41. return typeof delay === "number" ?
  42. this.each(function() {
  43. var elem = this;
  44. setTimeout(function() {
  45. $( elem ).focus();
  46. if ( fn ) {
  47. fn.call( elem );
  48. }
  49. }, delay );
  50. }) :
  51. orig.apply( this, arguments );
  52. };
  53. })( $.fn.focus ),
  54. scrollParent: function() {
  55. var scrollParent;
  56. if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) {
  57. scrollParent = this.parents().filter(function() {
  58. return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
  59. }).eq(0);
  60. } else {
  61. scrollParent = this.parents().filter(function() {
  62. return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
  63. }).eq(0);
  64. }
  65. return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent;
  66. },
  67. zIndex: function( zIndex ) {
  68. if ( zIndex !== undefined ) {
  69. return this.css( "zIndex", zIndex );
  70. }
  71. if ( this.length ) {
  72. var elem = $( this[ 0 ] ), position, value;
  73. while ( elem.length && elem[ 0 ] !== document ) {
  74. // Ignore z-index if position is set to a value where z-index is ignored by the browser
  75. // This makes behavior of this function consistent across browsers
  76. // WebKit always returns auto if the element is positioned
  77. position = elem.css( "position" );
  78. if ( position === "absolute" || position === "relative" || position === "fixed" ) {
  79. // IE returns 0 when zIndex is not specified
  80. // other browsers return a string
  81. // we ignore the case of nested elements with an explicit value of 0
  82. // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
  83. value = parseInt( elem.css( "zIndex" ), 10 );
  84. if ( !isNaN( value ) && value !== 0 ) {
  85. return value;
  86. }
  87. }
  88. elem = elem.parent();
  89. }
  90. }
  91. return 0;
  92. },
  93. uniqueId: function() {
  94. return this.each(function() {
  95. if ( !this.id ) {
  96. this.id = "ui-id-" + (++uuid);
  97. }
  98. });
  99. },
  100. removeUniqueId: function() {
  101. return this.each(function() {
  102. if ( runiqueId.test( this.id ) ) {
  103. $( this ).removeAttr( "id" );
  104. }
  105. });
  106. }
  107. });
  108. // selectors
  109. function focusable( element, isTabIndexNotNaN ) {
  110. var map, mapName, img,
  111. nodeName = element.nodeName.toLowerCase();
  112. if ( "area" === nodeName ) {
  113. map = element.parentNode;
  114. mapName = map.name;
  115. if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
  116. return false;
  117. }
  118. img = $( "img[usemap=#" + mapName + "]" )[0];
  119. return !!img && visible( img );
  120. }
  121. return ( /input|select|textarea|button|object/.test( nodeName ) ?
  122. !element.disabled :
  123. "a" === nodeName ?
  124. element.href || isTabIndexNotNaN :
  125. isTabIndexNotNaN) &&
  126. // the element and all of its ancestors must be visible
  127. visible( element );
  128. }
  129. function visible( element ) {
  130. return $.expr.filters.visible( element ) &&
  131. !$( element ).parents().addBack().filter(function() {
  132. return $.css( this, "visibility" ) === "hidden";
  133. }).length;
  134. }
  135. $.extend( $.expr[ ":" ], {
  136. data: $.expr.createPseudo ?
  137. $.expr.createPseudo(function( dataName ) {
  138. return function( elem ) {
  139. return !!$.data( elem, dataName );
  140. };
  141. }) :
  142. // support: jQuery <1.8
  143. function( elem, i, match ) {
  144. return !!$.data( elem, match[ 3 ] );
  145. },
  146. focusable: function( element ) {
  147. return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
  148. },
  149. tabbable: function( element ) {
  150. var tabIndex = $.attr( element, "tabindex" ),
  151. isTabIndexNaN = isNaN( tabIndex );
  152. return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
  153. }
  154. });
  155. // support: jQuery <1.8
  156. if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
  157. $.each( [ "Width", "Height" ], function( i, name ) {
  158. var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
  159. type = name.toLowerCase(),
  160. orig = {
  161. innerWidth: $.fn.innerWidth,
  162. innerHeight: $.fn.innerHeight,
  163. outerWidth: $.fn.outerWidth,
  164. outerHeight: $.fn.outerHeight
  165. };
  166. function reduce( elem, size, border, margin ) {
  167. $.each( side, function() {
  168. size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
  169. if ( border ) {
  170. size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
  171. }
  172. if ( margin ) {
  173. size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
  174. }
  175. });
  176. return size;
  177. }
  178. $.fn[ "inner" + name ] = function( size ) {
  179. if ( size === undefined ) {
  180. return orig[ "inner" + name ].call( this );
  181. }
  182. return this.each(function() {
  183. $( this ).css( type, reduce( this, size ) + "px" );
  184. });
  185. };
  186. $.fn[ "outer" + name] = function( size, margin ) {
  187. if ( typeof size !== "number" ) {
  188. return orig[ "outer" + name ].call( this, size );
  189. }
  190. return this.each(function() {
  191. $( this).css( type, reduce( this, size, true, margin ) + "px" );
  192. });
  193. };
  194. });
  195. }
  196. // support: jQuery <1.8
  197. if ( !$.fn.addBack ) {
  198. $.fn.addBack = function( selector ) {
  199. return this.add( selector == null ?
  200. this.prevObject : this.prevObject.filter( selector )
  201. );
  202. };
  203. }
  204. // support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
  205. if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
  206. $.fn.removeData = (function( removeData ) {
  207. return function( key ) {
  208. if ( arguments.length ) {
  209. return removeData.call( this, $.camelCase( key ) );
  210. } else {
  211. return removeData.call( this );
  212. }
  213. };
  214. })( $.fn.removeData );
  215. }
  216. // deprecated
  217. $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
  218. $.support.selectstart = "onselectstart" in document.createElement( "div" );
  219. $.fn.extend({
  220. disableSelection: function() {
  221. return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
  222. ".ui-disableSelection", function( event ) {
  223. event.preventDefault();
  224. });
  225. },
  226. enableSelection: function() {
  227. return this.unbind( ".ui-disableSelection" );
  228. }
  229. });
  230. $.extend( $.ui, {
  231. // $.ui.plugin is deprecated. Use $.widget() extensions instead.
  232. plugin: {
  233. add: function( module, option, set ) {
  234. var i,
  235. proto = $.ui[ module ].prototype;
  236. for ( i in set ) {
  237. proto.plugins[ i ] = proto.plugins[ i ] || [];
  238. proto.plugins[ i ].push( [ option, set[ i ] ] );
  239. }
  240. },
  241. call: function( instance, name, args ) {
  242. var i,
  243. set = instance.plugins[ name ];
  244. if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
  245. return;
  246. }
  247. for ( i = 0; i < set.length; i++ ) {
  248. if ( instance.options[ set[ i ][ 0 ] ] ) {
  249. set[ i ][ 1 ].apply( instance.element, args );
  250. }
  251. }
  252. }
  253. },
  254. // only used by resizable
  255. hasScroll: function( el, a ) {
  256. //If overflow is hidden, the element might have extra content, but the user wants to hide it
  257. if ( $( el ).css( "overflow" ) === "hidden") {
  258. return false;
  259. }
  260. var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
  261. has = false;
  262. if ( el[ scroll ] > 0 ) {
  263. return true;
  264. }
  265. // TODO: determine which cases actually cause this to happen
  266. // if the element doesn't have the scroll set, see if it's possible to
  267. // set the scroll
  268. el[ scroll ] = 1;
  269. has = ( el[ scroll ] > 0 );
  270. el[ scroll ] = 0;
  271. return has;
  272. }
  273. });
  274. })( jQuery );
  275. (function( $, undefined ) {
  276. var uuid = 0,
  277. slice = Array.prototype.slice,
  278. _cleanData = $.cleanData;
  279. $.cleanData = function( elems ) {
  280. for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
  281. try {
  282. $( elem ).triggerHandler( "remove" );
  283. // http://bugs.jquery.com/ticket/8235
  284. } catch( e ) {}
  285. }
  286. _cleanData( elems );
  287. };
  288. $.widget = function( name, base, prototype ) {
  289. var fullName, existingConstructor, constructor, basePrototype,
  290. // proxiedPrototype allows the provided prototype to remain unmodified
  291. // so that it can be used as a mixin for multiple widgets (#8876)
  292. proxiedPrototype = {},
  293. namespace = name.split( "." )[ 0 ];
  294. name = name.split( "." )[ 1 ];
  295. fullName = namespace + "-" + name;
  296. if ( !prototype ) {
  297. prototype = base;
  298. base = $.Widget;
  299. }
  300. // create selector for plugin
  301. $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
  302. return !!$.data( elem, fullName );
  303. };
  304. $[ namespace ] = $[ namespace ] || {};
  305. existingConstructor = $[ namespace ][ name ];
  306. constructor = $[ namespace ][ name ] = function( options, element ) {
  307. // allow instantiation without "new" keyword
  308. if ( !this._createWidget ) {
  309. return new constructor( options, element );
  310. }
  311. // allow instantiation without initializing for simple inheritance
  312. // must use "new" keyword (the code above always passes args)
  313. if ( arguments.length ) {
  314. this._createWidget( options, element );
  315. }
  316. };
  317. // extend with the existing constructor to carry over any static properties
  318. $.extend( constructor, existingConstructor, {
  319. version: prototype.version,
  320. // copy the object used to create the prototype in case we need to
  321. // redefine the widget later
  322. _proto: $.extend( {}, prototype ),
  323. // track widgets that inherit from this widget in case this widget is
  324. // redefined after a widget inherits from it
  325. _childConstructors: []
  326. });
  327. basePrototype = new base();
  328. // we need to make the options hash a property directly on the new instance
  329. // otherwise we'll modify the options hash on the prototype that we're
  330. // inheriting from
  331. basePrototype.options = $.widget.extend( {}, basePrototype.options );
  332. $.each( prototype, function( prop, value ) {
  333. if ( !$.isFunction( value ) ) {
  334. proxiedPrototype[ prop ] = value;
  335. return;
  336. }
  337. proxiedPrototype[ prop ] = (function() {
  338. var _super = function() {
  339. return base.prototype[ prop ].apply( this, arguments );
  340. },
  341. _superApply = function( args ) {
  342. return base.prototype[ prop ].apply( this, args );
  343. };
  344. return function() {
  345. var __super = this._super,
  346. __superApply = this._superApply,
  347. returnValue;
  348. this._super = _super;
  349. this._superApply = _superApply;
  350. returnValue = value.apply( this, arguments );
  351. this._super = __super;
  352. this._superApply = __superApply;
  353. return returnValue;
  354. };
  355. })();
  356. });
  357. constructor.prototype = $.widget.extend( basePrototype, {
  358. // TODO: remove support for widgetEventPrefix
  359. // always use the name + a colon as the prefix, e.g., draggable:start
  360. // don't prefix for widgets that aren't DOM-based
  361. widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
  362. }, proxiedPrototype, {
  363. constructor: constructor,
  364. namespace: namespace,
  365. widgetName: name,
  366. widgetFullName: fullName
  367. });
  368. // If this widget is being redefined then we need to find all widgets that
  369. // are inheriting from it and redefine all of them so that they inherit from
  370. // the new version of this widget. We're essentially trying to replace one
  371. // level in the prototype chain.
  372. if ( existingConstructor ) {
  373. $.each( existingConstructor._childConstructors, function( i, child ) {
  374. var childPrototype = child.prototype;
  375. // redefine the child widget using the same prototype that was
  376. // originally used, but inherit from the new version of the base
  377. $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
  378. });
  379. // remove the list of existing child constructors from the old constructor
  380. // so the old child constructors can be garbage collected
  381. delete existingConstructor._childConstructors;
  382. } else {
  383. base._childConstructors.push( constructor );
  384. }
  385. $.widget.bridge( name, constructor );
  386. };
  387. $.widget.extend = function( target ) {
  388. var input = slice.call( arguments, 1 ),
  389. inputIndex = 0,
  390. inputLength = input.length,
  391. key,
  392. value;
  393. for ( ; inputIndex < inputLength; inputIndex++ ) {
  394. for ( key in input[ inputIndex ] ) {
  395. value = input[ inputIndex ][ key ];
  396. if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
  397. // Clone objects
  398. if ( $.isPlainObject( value ) ) {
  399. target[ key ] = $.isPlainObject( target[ key ] ) ?
  400. $.widget.extend( {}, target[ key ], value ) :
  401. // Don't extend strings, arrays, etc. with objects
  402. $.widget.extend( {}, value );
  403. // Copy everything else by reference
  404. } else {
  405. target[ key ] = value;
  406. }
  407. }
  408. }
  409. }
  410. return target;
  411. };
  412. $.widget.bridge = function( name, object ) {
  413. var fullName = object.prototype.widgetFullName || name;
  414. $.fn[ name ] = function( options ) {
  415. var isMethodCall = typeof options === "string",
  416. args = slice.call( arguments, 1 ),
  417. returnValue = this;
  418. // allow multiple hashes to be passed on init
  419. options = !isMethodCall && args.length ?
  420. $.widget.extend.apply( null, [ options ].concat(args) ) :
  421. options;
  422. if ( isMethodCall ) {
  423. this.each(function() {
  424. var methodValue,
  425. instance = $.data( this, fullName );
  426. if ( !instance ) {
  427. return $.error( "cannot call methods on " + name + " prior to initialization; " +
  428. "attempted to call method '" + options + "'" );
  429. }
  430. if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
  431. return $.error( "no such method '" + options + "' for " + name + " widget instance" );
  432. }
  433. methodValue = instance[ options ].apply( instance, args );
  434. if ( methodValue !== instance && methodValue !== undefined ) {
  435. returnValue = methodValue && methodValue.jquery ?
  436. returnValue.pushStack( methodValue.get() ) :
  437. methodValue;
  438. return false;
  439. }
  440. });
  441. } else {
  442. this.each(function() {
  443. var instance = $.data( this, fullName );
  444. if ( instance ) {
  445. instance.option( options || {} )._init();
  446. } else {
  447. $.data( this, fullName, new object( options, this ) );
  448. }
  449. });
  450. }
  451. return returnValue;
  452. };
  453. };
  454. $.Widget = function( /* options, element */ ) {};
  455. $.Widget._childConstructors = [];
  456. $.Widget.prototype = {
  457. widgetName: "widget",
  458. widgetEventPrefix: "",
  459. defaultElement: "<div>",
  460. options: {
  461. disabled: false,
  462. // callbacks
  463. create: null
  464. },
  465. _createWidget: function( options, element ) {
  466. element = $( element || this.defaultElement || this )[ 0 ];
  467. this.element = $( element );
  468. this.uuid = uuid++;
  469. this.eventNamespace = "." + this.widgetName + this.uuid;
  470. this.options = $.widget.extend( {},
  471. this.options,
  472. this._getCreateOptions(),
  473. options );
  474. this.bindings = $();
  475. this.hoverable = $();
  476. this.focusable = $();
  477. if ( element !== this ) {
  478. $.data( element, this.widgetFullName, this );
  479. this._on( true, this.element, {
  480. remove: function( event ) {
  481. if ( event.target === element ) {
  482. this.destroy();
  483. }
  484. }
  485. });
  486. this.document = $( element.style ?
  487. // element within the document
  488. element.ownerDocument :
  489. // element is window or document
  490. element.document || element );
  491. this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
  492. }
  493. this._create();
  494. this._trigger( "create", null, this._getCreateEventData() );
  495. this._init();
  496. },
  497. _getCreateOptions: $.noop,
  498. _getCreateEventData: $.noop,
  499. _create: $.noop,
  500. _init: $.noop,
  501. destroy: function() {
  502. this._destroy();
  503. // we can probably remove the unbind calls in 2.0
  504. // all event bindings should go through this._on()
  505. this.element
  506. .unbind( this.eventNamespace )
  507. // 1.9 BC for #7810
  508. // TODO remove dual storage
  509. .removeData( this.widgetName )
  510. .removeData( this.widgetFullName )
  511. // support: jquery <1.6.3
  512. // http://bugs.jquery.com/ticket/9413
  513. .removeData( $.camelCase( this.widgetFullName ) );
  514. this.widget()
  515. .unbind( this.eventNamespace )
  516. .removeAttr( "aria-disabled" )
  517. .removeClass(
  518. this.widgetFullName + "-disabled " +
  519. "ui-state-disabled" );
  520. // clean up events and states
  521. this.bindings.unbind( this.eventNamespace );
  522. this.hoverable.removeClass( "ui-state-hover" );
  523. this.focusable.removeClass( "ui-state-focus" );
  524. },
  525. _destroy: $.noop,
  526. widget: function() {
  527. return this.element;
  528. },
  529. option: function( key, value ) {
  530. var options = key,
  531. parts,
  532. curOption,
  533. i;
  534. if ( arguments.length === 0 ) {
  535. // don't return a reference to the internal hash
  536. return $.widget.extend( {}, this.options );
  537. }
  538. if ( typeof key === "string" ) {
  539. // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
  540. options = {};
  541. parts = key.split( "." );
  542. key = parts.shift();
  543. if ( parts.length ) {
  544. curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
  545. for ( i = 0; i < parts.length - 1; i++ ) {
  546. curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
  547. curOption = curOption[ parts[ i ] ];
  548. }
  549. key = parts.pop();
  550. if ( arguments.length === 1 ) {
  551. return curOption[ key ] === undefined ? null : curOption[ key ];
  552. }
  553. curOption[ key ] = value;
  554. } else {
  555. if ( arguments.length === 1 ) {
  556. return this.options[ key ] === undefined ? null : this.options[ key ];
  557. }
  558. options[ key ] = value;
  559. }
  560. }
  561. this._setOptions( options );
  562. return this;
  563. },
  564. _setOptions: function( options ) {
  565. var key;
  566. for ( key in options ) {
  567. this._setOption( key, options[ key ] );
  568. }
  569. return this;
  570. },
  571. _setOption: function( key, value ) {
  572. this.options[ key ] = value;
  573. if ( key === "disabled" ) {
  574. this.widget()
  575. .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
  576. .attr( "aria-disabled", value );
  577. this.hoverable.removeClass( "ui-state-hover" );
  578. this.focusable.removeClass( "ui-state-focus" );
  579. }
  580. return this;
  581. },
  582. enable: function() {
  583. return this._setOption( "disabled", false );
  584. },
  585. disable: function() {
  586. return this._setOption( "disabled", true );
  587. },
  588. _on: function( suppressDisabledCheck, element, handlers ) {
  589. var delegateElement,
  590. instance = this;
  591. // no suppressDisabledCheck flag, shuffle arguments
  592. if ( typeof suppressDisabledCheck !== "boolean" ) {
  593. handlers = element;
  594. element = suppressDisabledCheck;
  595. suppressDisabledCheck = false;
  596. }
  597. // no element argument, shuffle and use this.element
  598. if ( !handlers ) {
  599. handlers = element;
  600. element = this.element;
  601. delegateElement = this.widget();
  602. } else {
  603. // accept selectors, DOM elements
  604. element = delegateElement = $( element );
  605. this.bindings = this.bindings.add( element );
  606. }
  607. $.each( handlers, function( event, handler ) {
  608. function handlerProxy() {
  609. // allow widgets to customize the disabled handling
  610. // - disabled as an array instead of boolean
  611. // - disabled class as method for disabling individual parts
  612. if ( !suppressDisabledCheck &&
  613. ( instance.options.disabled === true ||
  614. $( this ).hasClass( "ui-state-disabled" ) ) ) {
  615. return;
  616. }
  617. return ( typeof handler === "string" ? instance[ handler ] : handler )
  618. .apply( instance, arguments );
  619. }
  620. // copy the guid so direct unbinding works
  621. if ( typeof handler !== "string" ) {
  622. handlerProxy.guid = handler.guid =
  623. handler.guid || handlerProxy.guid || $.guid++;
  624. }
  625. var match = event.match( /^(\w+)\s*(.*)$/ ),
  626. eventName = match[1] + instance.eventNamespace,
  627. selector = match[2];
  628. if ( selector ) {
  629. delegateElement.delegate( selector, eventName, handlerProxy );
  630. } else {
  631. element.bind( eventName, handlerProxy );
  632. }
  633. });
  634. },
  635. _off: function( element, eventName ) {
  636. eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
  637. element.unbind( eventName ).undelegate( eventName );
  638. },
  639. _delay: function( handler, delay ) {
  640. function handlerProxy() {
  641. return ( typeof handler === "string" ? instance[ handler ] : handler )
  642. .apply( instance, arguments );
  643. }
  644. var instance = this;
  645. return setTimeout( handlerProxy, delay || 0 );
  646. },
  647. _hoverable: function( element ) {
  648. this.hoverable = this.hoverable.add( element );
  649. this._on( element, {
  650. mouseenter: function( event ) {
  651. $( event.currentTarget ).addClass( "ui-state-hover" );
  652. },
  653. mouseleave: function( event ) {
  654. $( event.currentTarget ).removeClass( "ui-state-hover" );
  655. }
  656. });
  657. },
  658. _focusable: function( element ) {
  659. this.focusable = this.focusable.add( element );
  660. this._on( element, {
  661. focusin: function( event ) {
  662. $( event.currentTarget ).addClass( "ui-state-focus" );
  663. },
  664. focusout: function( event ) {
  665. $( event.currentTarget ).removeClass( "ui-state-focus" );
  666. }
  667. });
  668. },
  669. _trigger: function( type, event, data ) {
  670. var prop, orig,
  671. callback = this.options[ type ];
  672. data = data || {};
  673. event = $.Event( event );
  674. event.type = ( type === this.widgetEventPrefix ?
  675. type :
  676. this.widgetEventPrefix + type ).toLowerCase();
  677. // the original event may come from any element
  678. // so we need to reset the target on the new event
  679. event.target = this.element[ 0 ];
  680. // copy original event properties over to the new event
  681. orig = event.originalEvent;
  682. if ( orig ) {
  683. for ( prop in orig ) {
  684. if ( !( prop in event ) ) {
  685. event[ prop ] = orig[ prop ];
  686. }
  687. }
  688. }
  689. this.element.trigger( event, data );
  690. return !( $.isFunction( callback ) &&
  691. callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
  692. event.isDefaultPrevented() );
  693. }
  694. };
  695. $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
  696. $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
  697. if ( typeof options === "string" ) {
  698. options = { effect: options };
  699. }
  700. var hasOptions,
  701. effectName = !options ?
  702. method :
  703. options === true || typeof options === "number" ?
  704. defaultEffect :
  705. options.effect || defaultEffect;
  706. options = options || {};
  707. if ( typeof options === "number" ) {
  708. options = { duration: options };
  709. }
  710. hasOptions = !$.isEmptyObject( options );
  711. options.complete = callback;
  712. if ( options.delay ) {
  713. element.delay( options.delay );
  714. }
  715. if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
  716. element[ method ]( options );
  717. } else if ( effectName !== method && element[ effectName ] ) {
  718. element[ effectName ]( options.duration, options.easing, callback );
  719. } else {
  720. element.queue(function( next ) {
  721. $( this )[ method ]();
  722. if ( callback ) {
  723. callback.call( element[ 0 ] );
  724. }
  725. next();
  726. });
  727. }
  728. };
  729. });
  730. })( jQuery );
  731. (function( $, undefined ) {
  732. var mouseHandled = false;
  733. $( document ).mouseup( function() {
  734. mouseHandled = false;
  735. });
  736. $.widget("ui.mouse", {
  737. version: "1.10.4",
  738. options: {
  739. cancel: "input,textarea,button,select,option",
  740. distance: 1,
  741. delay: 0
  742. },
  743. _mouseInit: function() {
  744. var that = this;
  745. this.element
  746. .bind("mousedown."+this.widgetName, function(event) {
  747. return that._mouseDown(event);
  748. })
  749. .bind("click."+this.widgetName, function(event) {
  750. if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
  751. $.removeData(event.target, that.widgetName + ".preventClickEvent");
  752. event.stopImmediatePropagation();
  753. return false;
  754. }
  755. });
  756. this.started = false;
  757. },
  758. // TODO: make sure destroying one instance of mouse doesn't mess with
  759. // other instances of mouse
  760. _mouseDestroy: function() {
  761. this.element.unbind("."+this.widgetName);
  762. if ( this._mouseMoveDelegate ) {
  763. $(document)
  764. .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
  765. .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
  766. }
  767. },
  768. _mouseDown: function(event) {
  769. // don't let more than one widget handle mouseStart
  770. if( mouseHandled ) { return; }
  771. // we may have missed mouseup (out of window)
  772. (this._mouseStarted && this._mouseUp(event));
  773. this._mouseDownEvent = event;
  774. var that = this,
  775. btnIsLeft = (event.which === 1),
  776. // event.target.nodeName works around a bug in IE 8 with
  777. // disabled inputs (#7620)
  778. elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
  779. if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
  780. return true;
  781. }
  782. this.mouseDelayMet = !this.options.delay;
  783. if (!this.mouseDelayMet) {
  784. this._mouseDelayTimer = setTimeout(function() {
  785. that.mouseDelayMet = true;
  786. }, this.options.delay);
  787. }
  788. if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
  789. this._mouseStarted = (this._mouseStart(event) !== false);
  790. if (!this._mouseStarted) {
  791. event.preventDefault();
  792. return true;
  793. }
  794. }
  795. // Click event may never have fired (Gecko & Opera)
  796. if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
  797. $.removeData(event.target, this.widgetName + ".preventClickEvent");
  798. }
  799. // these delegates are required to keep context
  800. this._mouseMoveDelegate = function(event) {
  801. return that._mouseMove(event);
  802. };
  803. this._mouseUpDelegate = function(event) {
  804. return that._mouseUp(event);
  805. };
  806. $(document)
  807. .bind("mousemove."+this.widgetName, this._mouseMoveDelegate)
  808. .bind("mouseup."+this.widgetName, this._mouseUpDelegate);
  809. event.preventDefault();
  810. mouseHandled = true;
  811. return true;
  812. },
  813. _mouseMove: function(event) {
  814. // IE mouseup check - mouseup happened when mouse was out of window
  815. if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
  816. return this._mouseUp(event);
  817. }
  818. if (this._mouseStarted) {
  819. this._mouseDrag(event);
  820. return event.preventDefault();
  821. }
  822. if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
  823. this._mouseStarted =
  824. (this._mouseStart(this._mouseDownEvent, event) !== false);
  825. (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
  826. }
  827. return !this._mouseStarted;
  828. },
  829. _mouseUp: function(event) {
  830. $(document)
  831. .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
  832. .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
  833. if (this._mouseStarted) {
  834. this._mouseStarted = false;
  835. if (event.target === this._mouseDownEvent.target) {
  836. $.data(event.target, this.widgetName + ".preventClickEvent", true);
  837. }
  838. this._mouseStop(event);
  839. }
  840. return false;
  841. },
  842. _mouseDistanceMet: function(event) {
  843. return (Math.max(
  844. Math.abs(this._mouseDownEvent.pageX - event.pageX),
  845. Math.abs(this._mouseDownEvent.pageY - event.pageY)
  846. ) >= this.options.distance
  847. );
  848. },
  849. _mouseDelayMet: function(/* event */) {
  850. return this.mouseDelayMet;
  851. },
  852. // These are placeholder methods, to be overriden by extending plugin
  853. _mouseStart: function(/* event */) {},
  854. _mouseDrag: function(/* event */) {},
  855. _mouseStop: function(/* event */) {},
  856. _mouseCapture: function(/* event */) { return true; }
  857. });
  858. })(jQuery);
  859. (function( $, undefined ) {
  860. $.widget("ui.draggable", $.ui.mouse, {
  861. version: "1.10.4",
  862. widgetEventPrefix: "drag",
  863. options: {
  864. addClasses: true,
  865. appendTo: "parent",
  866. axis: false,
  867. connectToSortable: false,
  868. containment: false,
  869. cursor: "auto",
  870. cursorAt: false,
  871. grid: false,
  872. handle: false,
  873. helper: "original",
  874. iframeFix: false,
  875. opacity: false,
  876. refreshPositions: false,
  877. revert: false,
  878. revertDuration: 500,
  879. scope: "default",
  880. scroll: true,
  881. scrollSensitivity: 20,
  882. scrollSpeed: 20,
  883. snap: false,
  884. snapMode: "both",
  885. snapTolerance: 20,
  886. stack: false,
  887. zIndex: false,
  888. // callbacks
  889. drag: null,
  890. start: null,
  891. stop: null
  892. },
  893. _create: function() {
  894. if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) {
  895. this.element[0].style.position = "relative";
  896. }
  897. if (this.options.addClasses){
  898. this.element.addClass("ui-draggable");
  899. }
  900. if (this.options.disabled){
  901. this.element.addClass("ui-draggable-disabled");
  902. }
  903. this._mouseInit();
  904. },
  905. _destroy: function() {
  906. this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
  907. this._mouseDestroy();
  908. },
  909. _mouseCapture: function(event) {
  910. var o = this.options;
  911. // among others, prevent a drag on a resizable-handle
  912. if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
  913. return false;
  914. }
  915. //Quit if we're not on a valid handle
  916. this.handle = this._getHandle(event);
  917. if (!this.handle) {
  918. return false;
  919. }
  920. $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
  921. $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>")
  922. .css({
  923. width: this.offsetWidth+"px", height: this.offsetHeight+"px",
  924. position: "absolute", opacity: "0.001", zIndex: 1000
  925. })
  926. .css($(this).offset())
  927. .appendTo("body");
  928. });
  929. return true;
  930. },
  931. _mouseStart: function(event) {
  932. var o = this.options;
  933. //Create and append the visible helper
  934. this.helper = this._createHelper(event);
  935. this.helper.addClass("ui-draggable-dragging");
  936. //Cache the helper size
  937. this._cacheHelperProportions();
  938. //If ddmanager is used for droppables, set the global draggable
  939. if($.ui.ddmanager) {
  940. $.ui.ddmanager.current = this;
  941. }
  942. /*
  943. * - Position generation -
  944. * This block generates everything position related - it's the core of draggables.
  945. */
  946. //Cache the margins of the original element
  947. this._cacheMargins();
  948. //Store the helper's css position
  949. this.cssPosition = this.helper.css( "position" );
  950. this.scrollParent = this.helper.scrollParent();
  951. this.offsetParent = this.helper.offsetParent();
  952. this.offsetParentCssPosition = this.offsetParent.css( "position" );
  953. //The element's absolute position on the page minus margins
  954. this.offset = this.positionAbs = this.element.offset();
  955. this.offset = {
  956. top: this.offset.top - this.margins.top,
  957. left: this.offset.left - this.margins.left
  958. };
  959. //Reset scroll cache
  960. this.offset.scroll = false;
  961. $.extend(this.offset, {
  962. click: { //Where the click happened, relative to the element
  963. left: event.pageX - this.offset.left,
  964. top: event.pageY - this.offset.top
  965. },
  966. parent: this._getParentOffset(),
  967. relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
  968. });
  969. //Generate the original position
  970. this.originalPosition = this.position = this._generatePosition(event);
  971. this.originalPageX = event.pageX;
  972. this.originalPageY = event.pageY;
  973. //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
  974. (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
  975. //Set a containment if given in the options
  976. this._setContainment();
  977. //Trigger event + callbacks
  978. if(this._trigger("start", event) === false) {
  979. this._clear();
  980. return false;
  981. }
  982. //Recache the helper size
  983. this._cacheHelperProportions();
  984. //Prepare the droppable offsets
  985. if ($.ui.ddmanager && !o.dropBehaviour) {
  986. $.ui.ddmanager.prepareOffsets(this, event);
  987. }
  988. this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
  989. //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
  990. if ( $.ui.ddmanager ) {
  991. $.ui.ddmanager.dragStart(this, event);
  992. }
  993. return true;
  994. },
  995. _mouseDrag: function(event, noPropagation) {
  996. // reset any necessary cached properties (see #5009)
  997. if ( this.offsetParentCssPosition === "fixed" ) {
  998. this.offset.parent = this._getParentOffset();
  999. }
  1000. //Compute the helpers position
  1001. this.position = this._generatePosition(event);
  1002. this.positionAbs = this._convertPositionTo("absolute");
  1003. //Call plugins and callbacks and use the resulting position if something is returned
  1004. if (!noPropagation) {
  1005. var ui = this._uiHash();
  1006. if(this._trigger("drag", event, ui) === false) {
  1007. this._mouseUp({});
  1008. return false;
  1009. }
  1010. this.position = ui.position;
  1011. }
  1012. if(!this.options.axis || this.options.axis !== "y") {
  1013. this.helper[0].style.left = this.position.left+"px";
  1014. }
  1015. if(!this.options.axis || this.options.axis !== "x") {
  1016. this.helper[0].style.top = this.position.top+"px";
  1017. }
  1018. if($.ui.ddmanager) {
  1019. $.ui.ddmanager.drag(this, event);
  1020. }
  1021. return false;
  1022. },
  1023. _mouseStop: function(event) {
  1024. //If we are using droppables, inform the manager about the drop
  1025. var that = this,
  1026. dropped = false;
  1027. if ($.ui.ddmanager && !this.options.dropBehaviour) {
  1028. dropped = $.ui.ddmanager.drop(this, event);
  1029. }
  1030. //if a drop comes from outside (a sortable)
  1031. if(this.dropped) {
  1032. dropped = this.dropped;
  1033. this.dropped = false;
  1034. }
  1035. //if the original element is no longer in the DOM don't bother to continue (see #8269)
  1036. if ( this.options.helper === "original" && !$.contains( this.element[ 0 ].ownerDocument, this.element[ 0 ] ) ) {
  1037. return false;
  1038. }
  1039. 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))) {
  1040. $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
  1041. if(that._trigger("stop", event) !== false) {
  1042. that._clear();
  1043. }
  1044. });
  1045. } else {
  1046. if(this._trigger("stop", event) !== false) {
  1047. this._clear();
  1048. }
  1049. }
  1050. return false;
  1051. },
  1052. _mouseUp: function(event) {
  1053. //Remove frame helpers
  1054. $("div.ui-draggable-iframeFix").each(function() {
  1055. this.parentNode.removeChild(this);
  1056. });
  1057. //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
  1058. if( $.ui.ddmanager ) {
  1059. $.ui.ddmanager.dragStop(this, event);
  1060. }
  1061. return $.ui.mouse.prototype._mouseUp.call(this, event);
  1062. },
  1063. cancel: function() {
  1064. if(this.helper.is(".ui-draggable-dragging")) {
  1065. this._mouseUp({});
  1066. } else {
  1067. this._clear();
  1068. }
  1069. return this;
  1070. },
  1071. _getHandle: function(event) {
  1072. return this.options.handle ?
  1073. !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
  1074. true;
  1075. },
  1076. _createHelper: function(event) {
  1077. var o = this.options,
  1078. helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element);
  1079. if(!helper.parents("body").length) {
  1080. helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
  1081. }
  1082. if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
  1083. helper.css("position", "absolute");
  1084. }
  1085. return helper;
  1086. },
  1087. _adjustOffsetFromHelper: function(obj) {
  1088. if (typeof obj === "string") {
  1089. obj = obj.split(" ");
  1090. }
  1091. if ($.isArray(obj)) {
  1092. obj = {left: +obj[0], top: +obj[1] || 0};
  1093. }
  1094. if ("left" in obj) {
  1095. this.offset.click.left = obj.left + this.margins.left;
  1096. }
  1097. if ("right" in obj) {
  1098. this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
  1099. }
  1100. if ("top" in obj) {
  1101. this.offset.click.top = obj.top + this.margins.top;
  1102. }
  1103. if ("bottom" in obj) {
  1104. this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
  1105. }
  1106. },
  1107. _getParentOffset: function() {
  1108. //Get the offsetParent and cache its position
  1109. var po = this.offsetParent.offset();
  1110. // This is a special case where we need to modify a offset calculated on start, since the following happened:
  1111. // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
  1112. // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
  1113. // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
  1114. if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
  1115. po.left += this.scrollParent.scrollLeft();
  1116. po.top += this.scrollParent.scrollTop();
  1117. }
  1118. //This needs to be actually done for all browsers, since pageX/pageY includes this information
  1119. //Ugly IE fix
  1120. if((this.offsetParent[0] === document.body) ||
  1121. (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
  1122. po = { top: 0, left: 0 };
  1123. }
  1124. return {
  1125. top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
  1126. left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
  1127. };
  1128. },
  1129. _getRelativeOffset: function() {
  1130. if(this.cssPosition === "relative") {
  1131. var p = this.element.position();
  1132. return {
  1133. top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
  1134. left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
  1135. };
  1136. } else {
  1137. return { top: 0, left: 0 };
  1138. }
  1139. },
  1140. _cacheMargins: function() {
  1141. this.margins = {
  1142. left: (parseInt(this.element.css("marginLeft"),10) || 0),
  1143. top: (parseInt(this.element.css("marginTop"),10) || 0),
  1144. right: (parseInt(this.element.css("marginRight"),10) || 0),
  1145. bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
  1146. };
  1147. },
  1148. _cacheHelperProportions: function() {
  1149. this.helperProportions = {
  1150. width: this.helper.outerWidth(),
  1151. height: this.helper.outerHeight()
  1152. };
  1153. },
  1154. _setContainment: function() {
  1155. var over, c, ce,
  1156. o = this.options;
  1157. if ( !o.containment ) {
  1158. this.containment = null;
  1159. return;
  1160. }
  1161. if ( o.containment === "window" ) {
  1162. this.containment = [
  1163. $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
  1164. $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
  1165. $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
  1166. $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
  1167. ];
  1168. return;
  1169. }
  1170. if ( o.containment === "document") {
  1171. this.containment = [
  1172. 0,
  1173. 0,
  1174. $( document ).width() - this.helperProportions.width - this.margins.left,
  1175. ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
  1176. ];
  1177. return;
  1178. }
  1179. if ( o.containment.constructor === Array ) {
  1180. this.containment = o.containment;
  1181. return;
  1182. }
  1183. if ( o.containment === "parent" ) {
  1184. o.containment = this.helper[ 0 ].parentNode;
  1185. }
  1186. c = $( o.containment );
  1187. ce = c[ 0 ];
  1188. if( !ce ) {
  1189. return;
  1190. }
  1191. over = c.css( "overflow" ) !== "hidden";
  1192. this.containment = [
  1193. ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
  1194. ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ) ,
  1195. ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - this.helperProportions.width - this.margins.left - this.margins.right,
  1196. ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - this.helperProportions.height - this.margins.top - this.margins.bottom
  1197. ];
  1198. this.relative_container = c;
  1199. },
  1200. _convertPositionTo: function(d, pos) {
  1201. if(!pos) {
  1202. pos = this.position;
  1203. }
  1204. var mod = d === "absolute" ? 1 : -1,
  1205. scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent;
  1206. //Cache the scroll
  1207. if (!this.offset.scroll) {
  1208. this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};
  1209. }
  1210. return {
  1211. top: (
  1212. pos.top + // The absolute mouse position
  1213. this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
  1214. this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border)
  1215. ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) * mod )
  1216. ),
  1217. left: (
  1218. pos.left + // The absolute mouse position
  1219. this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
  1220. this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border)
  1221. ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) * mod )
  1222. )
  1223. };
  1224. },
  1225. _generatePosition: function(event) {
  1226. var containment, co, top, left,
  1227. o = this.options,
  1228. scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent,
  1229. pageX = event.pageX,
  1230. pageY = event.pageY;
  1231. //Cache the scroll
  1232. if (!this.offset.scroll) {
  1233. this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};
  1234. }
  1235. /*
  1236. * - Position constraining -
  1237. * Constrain the position to a mix of grid, containment.
  1238. */
  1239. // If we are not dragging yet, we won't check for options
  1240. if ( this.originalPosition ) {
  1241. if ( this.containment ) {
  1242. if ( this.relative_container ){
  1243. co = this.relative_container.offset();
  1244. containment = [
  1245. this.containment[ 0 ] + co.left,
  1246. this.containment[ 1 ] + co.top,
  1247. this.containment[ 2 ] + co.left,
  1248. this.containment[ 3 ] + co.top
  1249. ];
  1250. }
  1251. else {
  1252. containment = this.containment;
  1253. }
  1254. if(event.pageX - this.offset.click.left < containment[0]) {
  1255. pageX = containment[0] + this.offset.click.left;
  1256. }
  1257. if(event.pageY - this.offset.click.top < containment[1]) {
  1258. pageY = containment[1] + this.offset.click.top;
  1259. }
  1260. if(event.pageX - this.offset.click.left > containment[2]) {
  1261. pageX = containment[2] + this.offset.click.left;
  1262. }
  1263. if(event.pageY - this.offset.click.top > containment[3]) {
  1264. pageY = containment[3] + this.offset.click.top;
  1265. }
  1266. }
  1267. if(o.grid) {
  1268. //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
  1269. top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
  1270. pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
  1271. left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
  1272. pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
  1273. }
  1274. }
  1275. return {
  1276. top: (
  1277. pageY - // The absolute mouse position
  1278. this.offset.click.top - // Click offset (relative to the element)
  1279. this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent
  1280. this.offset.parent.top + // The offsetParent's offset without borders (offset + border)
  1281. ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top )
  1282. ),
  1283. left: (
  1284. pageX - // The absolute mouse position
  1285. this.offset.click.left - // Click offset (relative to the element)
  1286. this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent
  1287. this.offset.parent.left + // The offsetParent's offset without borders (offset + border)
  1288. ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left )
  1289. )
  1290. };
  1291. },
  1292. _clear: function() {
  1293. this.helper.removeClass("ui-draggable-dragging");
  1294. if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
  1295. this.helper.remove();
  1296. }
  1297. this.helper = null;
  1298. this.cancelHelperRemoval = false;
  1299. },
  1300. // From now on bulk stuff - mainly helpers
  1301. _trigger: function(type, event, ui) {
  1302. ui = ui || this._uiHash();
  1303. $.ui.plugin.call(this, type, [event, ui]);
  1304. //The absolute position has to be recalculated after plugins
  1305. if(type === "drag") {
  1306. this.positionAbs = this._convertPositionTo("absolute");
  1307. }
  1308. return $.Widget.prototype._trigger.call(this, type, event, ui);
  1309. },
  1310. plugins: {},
  1311. _uiHash: function() {
  1312. return {
  1313. helper: this.helper,
  1314. position: this.position,
  1315. originalPosition: this.originalPosition,
  1316. offset: this.positionAbs
  1317. };
  1318. }
  1319. });
  1320. $.ui.plugin.add("draggable", "connectToSortable", {
  1321. start: function(event, ui) {
  1322. var inst = $(this).data("ui-draggable"), o = inst.options,
  1323. uiSortable = $.extend({}, ui, { item: inst.element });
  1324. inst.sortables = [];
  1325. $(o.connectToSortable).each(function() {
  1326. var sortable = $.data(this, "ui-sortable");
  1327. if (sortable && !sortable.options.disabled) {
  1328. inst.sortables.push({
  1329. instance: sortable,
  1330. shouldRevert: sortable.options.revert
  1331. });
  1332. sortable.refreshPositions(); // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).
  1333. sortable._trigger("activate", event, uiSortable);
  1334. }
  1335. });
  1336. },
  1337. stop: function(event, ui) {
  1338. //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
  1339. var inst = $(this).data("ui-draggable"),
  1340. uiSortable = $.extend({}, ui, { item: inst.element });
  1341. $.each(inst.sortables, function() {
  1342. if(this.instance.isOver) {
  1343. this.instance.isOver = 0;
  1344. inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
  1345. this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
  1346. //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid"
  1347. if(this.shouldRevert) {
  1348. this.instance.options.revert = this.shouldRevert;
  1349. }
  1350. //Trigger the stop of the sortable
  1351. this.instance._mouseStop(event);
  1352. this.instance.options.helper = this.instance.options._helper;
  1353. //If the helper has been the original item, restore properties in the sortable
  1354. if(inst.options.helper === "original") {
  1355. this.instance.currentItem.css({ top: "auto", left: "auto" });
  1356. }
  1357. } else {
  1358. this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
  1359. this.instance._trigger("deactivate", event, uiSortable);
  1360. }
  1361. });
  1362. },
  1363. drag: function(event, ui) {
  1364. var inst = $(this).data("ui-draggable"), that = this;
  1365. $.each(inst.sortables, function() {
  1366. var innermostIntersecting = false,
  1367. thisSortable = this;
  1368. //Copy over some variables to allow calling the sortable's native _intersectsWith
  1369. this.instance.positionAbs = inst.positionAbs;
  1370. this.instance.helperProportions = inst.helperProportions;
  1371. this.instance.offset.click = inst.offset.click;
  1372. if(this.instance._intersectsWith(this.instance.containerCache)) {
  1373. innermostIntersecting = true;
  1374. $.each(inst.sortables, function () {
  1375. this.instance.positionAbs = inst.positionAbs;
  1376. this.instance.helperProportions = inst.helperProportions;
  1377. this.instance.offset.click = inst.offset.click;
  1378. if (this !== thisSortable &&
  1379. this.instance._intersectsWith(this.instance.containerCache) &&
  1380. $.contains(thisSortable.instance.element[0], this.instance.element[0])
  1381. ) {
  1382. innermostIntersecting = false;
  1383. }
  1384. return innermostIntersecting;
  1385. });
  1386. }
  1387. if(innermostIntersecting) {
  1388. //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
  1389. if(!this.instance.isOver) {
  1390. this.instance.isOver = 1;
  1391. //Now we fake the start of dragging for the sortable instance,
  1392. //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
  1393. //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)
  1394. this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true);
  1395. this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
  1396. this.instance.options.helper = function() { return ui.helper[0]; };
  1397. event.target = this.instance.currentItem[0];
  1398. this.instance._mouseCapture(event, true);
  1399. this.instance._mouseStart(event, true, true);
  1400. //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
  1401. this.instance.offset.click.top = inst.offset.click.top;
  1402. this.instance.offset.click.left = inst.offset.click.left;
  1403. this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
  1404. this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
  1405. inst._trigger("toSortable", event);
  1406. inst.dropped = this.instance.element; //draggable revert needs that
  1407. //hack so receive/update callbacks work (mostly)
  1408. inst.currentItem = inst.element;
  1409. this.instance.fromOutside = inst;
  1410. }
  1411. //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
  1412. if(this.instance.currentItem) {
  1413. this.instance._mouseDrag(event);
  1414. }
  1415. } else {
  1416. //If it doesn't intersect with the sortable, and it intersected before,
  1417. //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
  1418. if(this.instance.isOver) {
  1419. this.instance.isOver = 0;
  1420. this.instance.cancelHelperRemoval = true;
  1421. //Prevent reverting on this forced stop
  1422. this.instance.options.revert = false;
  1423. // The out event needs to be triggered independently
  1424. this.instance._trigger("out", event, this.instance._uiHash(this.instance));
  1425. this.instance._mouseStop(event, true);
  1426. this.instance.options.helper = this.instance.options._helper;
  1427. //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
  1428. this.instance.currentItem.remove();
  1429. if(this.instance.placeholder) {
  1430. this.instance.placeholder.remove();
  1431. }
  1432. inst._trigger("fromSortable", event);
  1433. inst.dropped = false; //draggable revert needs that
  1434. }
  1435. }
  1436. });
  1437. }
  1438. });
  1439. $.ui.plugin.add("draggable", "cursor", {
  1440. start: function() {
  1441. var t = $("body"), o = $(this).data("ui-draggable").options;
  1442. if (t.css("cursor")) {
  1443. o._cursor = t.css("cursor");
  1444. }
  1445. t.css("cursor", o.cursor);
  1446. },
  1447. stop: function() {
  1448. var o = $(this).data("ui-draggable").options;
  1449. if (o._cursor) {
  1450. $("body").css("cursor", o._cursor);
  1451. }
  1452. }
  1453. });
  1454. $.ui.plugin.add("draggable", "opacity", {
  1455. start: function(event, ui) {
  1456. var t = $(ui.helper), o = $(this).data("ui-draggable").options;
  1457. if(t.css("opacity")) {
  1458. o._opacity = t.css("opacity");
  1459. }
  1460. t.css("opacity", o.opacity);
  1461. },
  1462. stop: function(event, ui) {
  1463. var o = $(this).data("ui-draggable").options;
  1464. if(o._opacity) {
  1465. $(ui.helper).css("opacity", o._opacity);
  1466. }
  1467. }
  1468. });
  1469. $.ui.plugin.add("draggable", "scroll", {
  1470. start: function() {
  1471. var i = $(this).data("ui-draggable");
  1472. if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
  1473. i.overflowOffset = i.scrollParent.offset();
  1474. }
  1475. },
  1476. drag: function( event ) {
  1477. var i = $(this).data("ui-draggable"), o = i.options, scrolled = false;
  1478. if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
  1479. if(!o.axis || o.axis !== "x") {
  1480. if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
  1481. i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
  1482. } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) {
  1483. i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
  1484. }
  1485. }
  1486. if(!o.axis || o.axis !== "y") {
  1487. if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
  1488. i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
  1489. } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) {
  1490. i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
  1491. }
  1492. }
  1493. } else {
  1494. if(!o.axis || o.axis !== "x") {
  1495. if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
  1496. scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
  1497. } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
  1498. scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
  1499. }
  1500. }
  1501. if(!o.axis || o.axis !== "y") {
  1502. if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
  1503. scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
  1504. } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
  1505. scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
  1506. }
  1507. }
  1508. }
  1509. if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
  1510. $.ui.ddmanager.prepareOffsets(i, event);
  1511. }
  1512. }
  1513. });
  1514. $.ui.plugin.add("draggable", "snap", {
  1515. start: function() {
  1516. var i = $(this).data("ui-draggable"),
  1517. o = i.options;
  1518. i.snapElements = [];
  1519. $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
  1520. var $t = $(this),
  1521. $o = $t.offset();
  1522. if(this !== i.element[0]) {
  1523. i.snapElements.push({
  1524. item: this,
  1525. width: $t.outerWidth(), height: $t.outerHeight(),
  1526. top: $o.top, left: $o.left
  1527. });
  1528. }
  1529. });
  1530. },
  1531. drag: function(event, ui) {
  1532. var ts, bs, ls, rs, l, r, t, b, i, first,
  1533. inst = $(this).data("ui-draggable"),
  1534. o = inst.options,
  1535. d = o.snapTolerance,
  1536. x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
  1537. y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
  1538. for (i = inst.snapElements.length - 1; i >= 0; i--){
  1539. l = inst.snapElements[i].left;
  1540. r = l + inst.snapElements[i].width;
  1541. t = inst.snapElements[i].top;
  1542. b = t + inst.snapElements[i].height;
  1543. if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
  1544. if(inst.snapElements[i].snapping) {
  1545. (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
  1546. }
  1547. inst.snapElements[i].snapping = false;
  1548. continue;
  1549. }
  1550. if(o.snapMode !== "inner") {
  1551. ts = Math.abs(t - y2) <= d;
  1552. bs = Math.abs(b - y1) <= d;
  1553. ls = Math.abs(l - x2) <= d;
  1554. rs = Math.abs(r - x1) <= d;
  1555. if(ts) {
  1556. ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
  1557. }
  1558. if(bs) {
  1559. ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
  1560. }
  1561. if(ls) {
  1562. ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
  1563. }
  1564. if(rs) {
  1565. ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
  1566. }
  1567. }
  1568. first = (ts || bs || ls || rs);
  1569. if(o.snapMode !== "outer") {
  1570. ts = Math.abs(t - y1) <= d;
  1571. bs = Math.abs(b - y2) <= d;
  1572. ls = Math.abs(l - x1) <= d;
  1573. rs = Math.abs(r - x2) <= d;
  1574. if(ts) {
  1575. ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
  1576. }
  1577. if(bs) {
  1578. ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
  1579. }
  1580. if(ls) {
  1581. ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
  1582. }
  1583. if(rs) {
  1584. ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
  1585. }
  1586. }
  1587. if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
  1588. (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
  1589. }
  1590. inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
  1591. }
  1592. }
  1593. });
  1594. $.ui.plugin.add("draggable", "stack", {
  1595. start: function() {
  1596. var min,
  1597. o = this.data("ui-draggable").options,
  1598. group = $.makeArray($(o.stack)).sort(function(a,b) {
  1599. return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
  1600. });
  1601. if (!group.length) { return; }
  1602. min = parseInt($(group[0]).css("zIndex"), 10) || 0;
  1603. $(group).each(function(i) {
  1604. $(this).css("zIndex", min + i);
  1605. });
  1606. this.css("zIndex", (min + group.length));
  1607. }
  1608. });
  1609. $.ui.plugin.add("draggable", "zIndex", {
  1610. start: function(event, ui) {
  1611. var t = $(ui.helper), o = $(this).data("ui-draggable").options;
  1612. if(t.css("zIndex")) {
  1613. o._zIndex = t.css("zIndex");
  1614. }
  1615. t.css("zIndex", o.zIndex);
  1616. },
  1617. stop: function(event, ui) {
  1618. var o = $(this).data("ui-draggable").options;
  1619. if(o._zIndex) {
  1620. $(ui.helper).css("zIndex", o._zIndex);
  1621. }
  1622. }
  1623. });
  1624. })(jQuery);
  1625. (function( $, undefined ) {
  1626. function isOverAxis( x, reference, size ) {
  1627. return ( x > reference ) && ( x < ( reference + size ) );
  1628. }
  1629. $.widget("ui.droppable", {
  1630. version: "1.10.4",
  1631. widgetEventPrefix: "drop",
  1632. options: {
  1633. accept: "*",
  1634. activeClass: false,
  1635. addClasses: true,
  1636. greedy: false,
  1637. hoverClass: false,
  1638. scope: "default",
  1639. tolerance: "intersect",
  1640. // callbacks
  1641. activate: null,
  1642. deactivate: null,
  1643. drop: null,
  1644. out: null,
  1645. over: null
  1646. },
  1647. _create: function() {
  1648. var proportions,
  1649. o = this.options,
  1650. accept = o.accept;
  1651. this.isover = false;
  1652. this.isout = true;
  1653. this.accept = $.isFunction(accept) ? accept : function(d) {
  1654. return d.is(accept);
  1655. };
  1656. this.proportions = function( /* valueToWrite */ ) {
  1657. if ( arguments.length ) {
  1658. // Store the droppable's proportions
  1659. proportions = arguments[ 0 ];
  1660. } else {
  1661. // Retrieve or derive the droppable's proportions
  1662. return proportions ?
  1663. proportions :
  1664. proportions = {
  1665. width: this.element[ 0 ].offsetWidth,
  1666. height: this.element[ 0 ].offsetHeight
  1667. };
  1668. }
  1669. };
  1670. // Add the reference and positions to the manager
  1671. $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
  1672. $.ui.ddmanager.droppables[o.scope].push(this);
  1673. (o.addClasses && this.element.addClass("ui-droppable"));
  1674. },
  1675. _destroy: function() {
  1676. var i = 0,
  1677. drop = $.ui.ddmanager.droppables[this.options.scope];
  1678. for ( ; i < drop.length; i++ ) {
  1679. if ( drop[i] === this ) {
  1680. drop.splice(i, 1);
  1681. }
  1682. }
  1683. this.element.removeClass("ui-droppable ui-droppable-disabled");
  1684. },
  1685. _setOption: function(key, value) {
  1686. if(key === "accept") {
  1687. this.accept = $.isFunction(value) ? value : function(d) {
  1688. return d.is(value);
  1689. };
  1690. }
  1691. $.Widget.prototype._setOption.apply(this, arguments);
  1692. },
  1693. _activate: function(event) {
  1694. var draggable = $.ui.ddmanager.current;
  1695. if(this.options.activeClass) {
  1696. this.element.addClass(this.options.activeClass);
  1697. }
  1698. if(draggable){
  1699. this._trigger("activate", event, this.ui(draggable));
  1700. }
  1701. },
  1702. _deactivate: function(event) {
  1703. var draggable = $.ui.ddmanager.current;
  1704. if(this.options.activeClass) {
  1705. this.element.removeClass(this.options.activeClass);
  1706. }
  1707. if(draggable){
  1708. this._trigger("deactivate", event, this.ui(draggable));
  1709. }
  1710. },
  1711. _over: function(event) {
  1712. var draggable = $.ui.ddmanager.current;
  1713. // Bail if draggable and droppable are same element
  1714. if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
  1715. return;
  1716. }
  1717. if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
  1718. if(this.options.hoverClass) {
  1719. this.element.addClass(this.options.hoverClass);
  1720. }
  1721. this._trigger("over", event, this.ui(draggable));
  1722. }
  1723. },
  1724. _out: function(event) {
  1725. var draggable = $.ui.ddmanager.current;
  1726. // Bail if draggable and droppable are same element
  1727. if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
  1728. return;
  1729. }
  1730. if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
  1731. if(this.options.hoverClass) {
  1732. this.element.removeClass(this.options.hoverClass);
  1733. }
  1734. this._trigger("out", event, this.ui(draggable));
  1735. }
  1736. },
  1737. _drop: function(event,custom) {
  1738. var draggable = custom || $.ui.ddmanager.current,
  1739. childrenIntersection = false;
  1740. // Bail if draggable and droppable are same element
  1741. if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
  1742. return false;
  1743. }
  1744. this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() {
  1745. var inst = $.data(this, "ui-droppable");
  1746. if(
  1747. inst.options.greedy &&
  1748. !inst.options.disabled &&
  1749. inst.options.scope === draggable.options.scope &&
  1750. inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) &&
  1751. $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
  1752. ) { childrenIntersection = true; return false; }
  1753. });
  1754. if(childrenIntersection) {
  1755. return false;
  1756. }
  1757. if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
  1758. if(this.options.activeClass) {
  1759. this.element.removeClass(this.options.activeClass);
  1760. }
  1761. if(this.options.hoverClass) {
  1762. this.element.removeClass(this.options.hoverClass);
  1763. }
  1764. this._trigger("drop", event, this.ui(draggable));
  1765. return this.element;
  1766. }
  1767. return false;
  1768. },
  1769. ui: function(c) {
  1770. return {
  1771. draggable: (c.currentItem || c.element),
  1772. helper: c.helper,
  1773. position: c.position,
  1774. offset: c.positionAbs
  1775. };
  1776. }
  1777. });
  1778. $.ui.intersect = function(draggable, droppable, toleranceMode) {
  1779. if (!droppable.offset) {
  1780. return false;
  1781. }
  1782. var draggableLeft, draggableTop,
  1783. x1 = (draggable.positionAbs || draggable.position.absolute).left,
  1784. y1 = (draggable.positionAbs || draggable.position.absolute).top,
  1785. x2 = x1 + draggable.helperProportions.width,
  1786. y2 = y1 + draggable.helperProportions.height,
  1787. l = droppable.offset.left,
  1788. t = droppable.offset.top,
  1789. r = l + droppable.proportions().width,
  1790. b = t + droppable.proportions().height;
  1791. switch (toleranceMode) {
  1792. case "fit":
  1793. return (l <= x1 && x2 <= r && t <= y1 && y2 <= b);
  1794. case "intersect":
  1795. return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half
  1796. x2 - (draggable.helperProportions.width / 2) < r && // Left Half
  1797. t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half
  1798. y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
  1799. case "pointer":
  1800. draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left);
  1801. draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top);
  1802. return isOverAxis( draggableTop, t, droppable.proportions().height ) && isOverAxis( draggableLeft, l, droppable.proportions().width );
  1803. case "touch":
  1804. return (
  1805. (y1 >= t && y1 <= b) || // Top edge touching
  1806. (y2 >= t && y2 <= b) || // Bottom edge touching
  1807. (y1 < t && y2 > b) // Surrounded vertically
  1808. ) && (
  1809. (x1 >= l && x1 <= r) || // Left edge touching
  1810. (x2 >= l && x2 <= r) || // Right edge touching
  1811. (x1 < l && x2 > r) // Surrounded horizontally
  1812. );
  1813. default:
  1814. return false;
  1815. }
  1816. };
  1817. /*
  1818. This manager tracks offsets of draggables and droppables
  1819. */
  1820. $.ui.ddmanager = {
  1821. current: null,
  1822. droppables: { "default": [] },
  1823. prepareOffsets: function(t, event) {
  1824. var i, j,
  1825. m = $.ui.ddmanager.droppables[t.options.scope] || [],
  1826. type = event ? event.type : null, // workaround for #2317
  1827. list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack();
  1828. droppablesLoop: for (i = 0; i < m.length; i++) {
  1829. //No disabled and non-accepted
  1830. if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) {
  1831. continue;
  1832. }
  1833. // Filter out elements in the current dragged item
  1834. for (j=0; j < list.length; j++) {
  1835. if(list[j] === m[i].element[0]) {
  1836. m[i].proportions().height = 0;
  1837. continue droppablesLoop;
  1838. }
  1839. }
  1840. m[i].visible = m[i].element.css("display") !== "none";
  1841. if(!m[i].visible) {
  1842. continue;
  1843. }
  1844. //Activate the droppable if used directly from draggables
  1845. if(type === "mousedown") {
  1846. m[i]._activate.call(m[i], event);
  1847. }
  1848. m[ i ].offset = m[ i ].element.offset();
  1849. m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
  1850. }
  1851. },
  1852. drop: function(draggable, event) {
  1853. var dropped = false;
  1854. // Create a copy of the droppables in case the list changes during the drop (#9116)
  1855. $.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() {
  1856. if(!this.options) {
  1857. return;
  1858. }
  1859. if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) {
  1860. dropped = this._drop.call(this, event) || dropped;
  1861. }
  1862. if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
  1863. this.isout = true;
  1864. this.isover = false;
  1865. this._deactivate.call(this, event);
  1866. }
  1867. });
  1868. return dropped;
  1869. },
  1870. dragStart: function( draggable, event ) {
  1871. //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
  1872. draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
  1873. if( !draggable.options.refreshPositions ) {
  1874. $.ui.ddmanager.prepareOffsets( draggable, event );
  1875. }
  1876. });
  1877. },
  1878. drag: function(draggable, event) {
  1879. //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
  1880. if(draggable.options.refreshPositions) {
  1881. $.ui.ddmanager.prepareOffsets(draggable, event);
  1882. }
  1883. //Run through all droppables and check their positions based on specific tolerance options
  1884. $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
  1885. if(this.options.disabled || this.greedyChild || !this.visible) {
  1886. return;
  1887. }
  1888. var parentInstance, scope, parent,
  1889. intersects = $.ui.intersect(draggable, this, this.options.tolerance),
  1890. c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null);
  1891. if(!c) {
  1892. return;
  1893. }
  1894. if (this.options.greedy) {
  1895. // find droppable parents with same scope
  1896. scope = this.options.scope;
  1897. parent = this.element.parents(":data(ui-droppable)").filter(function () {
  1898. return $.data(this, "ui-droppable").options.scope === scope;
  1899. });
  1900. if (parent.length) {
  1901. parentInstance = $.data(parent[0], "ui-droppable");
  1902. parentInstance.greedyChild = (c === "isover");
  1903. }
  1904. }
  1905. // we just moved into a greedy child
  1906. if (parentInstance && c === "isover") {
  1907. parentInstance.isover = false;
  1908. parentInstance.isout = true;
  1909. parentInstance._out.call(parentInstance, event);
  1910. }
  1911. this[c] = true;
  1912. this[c === "isout" ? "isover" : "isout"] = false;
  1913. this[c === "isover" ? "_over" : "_out"].call(this, event);
  1914. // we just moved out of a greedy child
  1915. if (parentInstance && c === "isout") {
  1916. parentInstance.isout = false;
  1917. parentInstance.isover = true;
  1918. parentInstance._over.call(parentInstance, event);
  1919. }
  1920. });
  1921. },
  1922. dragStop: function( draggable, event ) {
  1923. draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
  1924. //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
  1925. if( !draggable.options.refreshPositions ) {
  1926. $.ui.ddmanager.prepareOffsets( draggable, event );
  1927. }
  1928. }
  1929. };
  1930. })(jQuery);
  1931. (function( $, undefined ) {
  1932. function num(v) {
  1933. return parseInt(v, 10) || 0;
  1934. }
  1935. function isNumber(value) {
  1936. return !isNaN(parseInt(value, 10));
  1937. }
  1938. $.widget("ui.resizable", $.ui.mouse, {
  1939. version: "1.10.4",
  1940. widgetEventPrefix: "resize",
  1941. options: {
  1942. alsoResize: false,
  1943. animate: false,
  1944. animateDuration: "slow",
  1945. animateEasing: "swing",
  1946. aspectRatio: false,
  1947. autoHide: false,
  1948. containment: false,
  1949. ghost: false,
  1950. grid: false,
  1951. handles: "e,s,se",
  1952. helper: false,
  1953. maxHeight: null,
  1954. maxWidth: null,
  1955. minHeight: 10,
  1956. minWidth: 10,
  1957. // See #7960
  1958. zIndex: 90,
  1959. // callbacks
  1960. resize: null,
  1961. start: null,
  1962. stop: null
  1963. },
  1964. _create: function() {
  1965. var n, i, handle, axis, hname,
  1966. that = this,
  1967. o = this.options;
  1968. this.element.addClass("ui-resizable");
  1969. $.extend(this, {
  1970. _aspectRatio: !!(o.aspectRatio),
  1971. aspectRatio: o.aspectRatio,
  1972. originalElement: this.element,
  1973. _proportionallyResizeElements: [],
  1974. _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
  1975. });
  1976. //Wrap the element if it cannot hold child nodes
  1977. if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
  1978. //Create a wrapper element and set the wrapper to the new current internal element
  1979. this.element.wrap(
  1980. $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
  1981. position: this.element.css("position"),
  1982. width: this.element.outerWidth(),
  1983. height: this.element.outerHeight(),
  1984. top: this.element.css("top"),
  1985. left: this.element.css("left")
  1986. })
  1987. );
  1988. //Overwrite the original this.element
  1989. this.element = this.element.parent().data(
  1990. "ui-resizable", this.element.data("ui-resizable")
  1991. );
  1992. this.elementIsWrapper = true;
  1993. //Move margins to the wrapper
  1994. this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
  1995. this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
  1996. //Prevent Safari textarea resize
  1997. this.originalResizeStyle = this.originalElement.css("resize");
  1998. this.originalElement.css("resize", "none");
  1999. //Push the actual element to our proportionallyResize internal array
  2000. this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" }));
  2001. // avoid IE jump (hard set the margin)
  2002. this.originalElement.css({ margin: this.originalElement.css("margin") });
  2003. // fix handlers offset
  2004. this._proportionallyResize();
  2005. }
  2006. 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" });
  2007. if(this.handles.constructor === String) {
  2008. if ( this.handles === "all") {
  2009. this.handles = "n,e,s,w,se,sw,ne,nw";
  2010. }
  2011. n = this.handles.split(",");
  2012. this.handles = {};
  2013. for(i = 0; i < n.length; i++) {
  2014. handle = $.trim(n[i]);
  2015. hname = "ui-resizable-"+handle;
  2016. axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
  2017. // Apply zIndex to all handles - see #7960
  2018. axis.css({ zIndex: o.zIndex });
  2019. //TODO : What's going on here?
  2020. if ("se" === handle) {
  2021. axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
  2022. }
  2023. //Insert into internal handles object and append to element
  2024. this.handles[handle] = ".ui-resizable-"+handle;
  2025. this.element.append(axis);
  2026. }
  2027. }
  2028. this._renderAxis = function(target) {
  2029. var i, axis, padPos, padWrapper;
  2030. target = target || this.element;
  2031. for(i in this.handles) {
  2032. if(this.handles[i].constructor === String) {
  2033. this.handles[i] = $(this.handles[i], this.element).show();
  2034. }
  2035. //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
  2036. if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
  2037. axis = $(this.handles[i], this.element);
  2038. //Checking the correct pad and border
  2039. padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
  2040. //The padding type i have to apply...
  2041. padPos = [ "padding",
  2042. /ne|nw|n/.test(i) ? "Top" :
  2043. /se|sw|s/.test(i) ? "Bottom" :
  2044. /^e$/.test(i) ? "Right" : "Left" ].join("");
  2045. target.css(padPos, padWrapper);
  2046. this._proportionallyResize();
  2047. }
  2048. //TODO: What's that good for? There's not anything to be executed left
  2049. if(!$(this.handles[i]).length) {
  2050. continue;
  2051. }
  2052. }
  2053. };
  2054. //TODO: make renderAxis a prototype function
  2055. this._renderAxis(this.element);
  2056. this._handles = $(".ui-resizable-handle", this.element)
  2057. .disableSelection();
  2058. //Matching axis name
  2059. this._handles.mouseover(function() {
  2060. if (!that.resizing) {
  2061. if (this.className) {
  2062. axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
  2063. }
  2064. //Axis, default = se
  2065. that.axis = axis && axis[1] ? axis[1] : "se";
  2066. }
  2067. });
  2068. //If we want to auto hide the elements
  2069. if (o.autoHide) {
  2070. this._handles.hide();
  2071. $(this.element)
  2072. .addClass("ui-resizable-autohide")
  2073. .mouseenter(function() {
  2074. if (o.disabled) {
  2075. return;
  2076. }
  2077. $(this).removeClass("ui-resizable-autohide");
  2078. that._handles.show();
  2079. })
  2080. .mouseleave(function(){
  2081. if (o.disabled) {
  2082. return;
  2083. }
  2084. if (!that.resizing) {
  2085. $(this).addClass("ui-resizable-autohide");
  2086. that._handles.hide();
  2087. }
  2088. });
  2089. }
  2090. //Initialize the mouse interaction
  2091. this._mouseInit();
  2092. },
  2093. _destroy: function() {
  2094. this._mouseDestroy();
  2095. var wrapper,
  2096. _destroy = function(exp) {
  2097. $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
  2098. .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove();
  2099. };
  2100. //TODO: Unwrap at same DOM position
  2101. if (this.elementIsWrapper) {
  2102. _destroy(this.element);
  2103. wrapper = this.element;
  2104. this.originalElement.css({
  2105. position: wrapper.css("position"),
  2106. width: wrapper.outerWidth(),
  2107. height: wrapper.outerHeight(),
  2108. top: wrapper.css("top"),
  2109. left: wrapper.css("left")
  2110. }).insertAfter( wrapper );
  2111. wrapper.remove();
  2112. }
  2113. this.originalElement.css("resize", this.originalResizeStyle);
  2114. _destroy(this.originalElement);
  2115. return this;
  2116. },
  2117. _mouseCapture: function(event) {
  2118. var i, handle,
  2119. capture = false;
  2120. for (i in this.handles) {
  2121. handle = $(this.handles[i])[0];
  2122. if (handle === event.target || $.contains(handle, event.target)) {
  2123. capture = true;
  2124. }
  2125. }
  2126. return !this.options.disabled && capture;
  2127. },
  2128. _mouseStart: function(event) {
  2129. var curleft, curtop, cursor,
  2130. o = this.options,
  2131. iniPos = this.element.position(),
  2132. el = this.element;
  2133. this.resizing = true;
  2134. // bugfix for http://dev.jquery.com/ticket/1749
  2135. if ( (/absolute/).test( el.css("position") ) ) {
  2136. el.css({ position: "absolute", top: el.css("top"), left: el.css("left") });
  2137. } else if (el.is(".ui-draggable")) {
  2138. el.css({ position: "absolute", top: iniPos.top, left: iniPos.left });
  2139. }
  2140. this._renderProxy();
  2141. curleft = num(this.helper.css("left"));
  2142. curtop = num(this.helper.css("top"));
  2143. if (o.containment) {
  2144. curleft += $(o.containment).scrollLeft() || 0;
  2145. curtop += $(o.containment).scrollTop() || 0;
  2146. }
  2147. //Store needed variables
  2148. this.offset = this.helper.offset();
  2149. this.position = { left: curleft, top: curtop };
  2150. this.size = this._helper ? { width: this.helper.width(), height: this.helper.height() } : { width: el.width(), height: el.height() };
  2151. this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
  2152. this.originalPosition = { left: curleft, top: curtop };
  2153. this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
  2154. this.originalMousePosition = { left: event.pageX, top: event.pageY };
  2155. //Aspect Ratio
  2156. this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
  2157. cursor = $(".ui-resizable-" + this.axis).css("cursor");
  2158. $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
  2159. el.addClass("ui-resizable-resizing");
  2160. this._propagate("start", event);
  2161. return true;
  2162. },
  2163. _mouseDrag: function(event) {
  2164. //Increase performance, avoid regex
  2165. var data,
  2166. el = this.helper, props = {},
  2167. smp = this.originalMousePosition,
  2168. a = this.axis,
  2169. prevTop = this.position.top,
  2170. prevLeft = this.position.left,
  2171. prevWidth = this.size.width,
  2172. prevHeight = this.size.height,
  2173. dx = (event.pageX-smp.left)||0,
  2174. dy = (event.pageY-smp.top)||0,
  2175. trigger = this._change[a];
  2176. if (!trigger) {
  2177. return false;
  2178. }
  2179. // Calculate the attrs that will be change
  2180. data = trigger.apply(this, [event, dx, dy]);
  2181. // Put this in the mouseDrag handler since the user can start pressing shift while resizing
  2182. this._updateVirtualBoundaries(event.shiftKey);
  2183. if (this._aspectRatio || event.shiftKey) {
  2184. data = this._updateRatio(data, event);
  2185. }
  2186. data = this._respectSize(data, event);
  2187. this._updateCache(data);
  2188. // plugins callbacks need to be called first
  2189. this._propagate("resize", event);
  2190. if (this.position.top !== prevTop) {
  2191. props.top = this.position.top + "px";
  2192. }
  2193. if (this.position.left !== prevLeft) {
  2194. props.left = this.position.left + "px";
  2195. }
  2196. if (this.size.width !== prevWidth) {
  2197. props.width = this.size.width + "px";
  2198. }
  2199. if (this.size.height !== prevHeight) {
  2200. props.height = this.size.height + "px";
  2201. }
  2202. el.css(props);
  2203. if (!this._helper && this._proportionallyResizeElements.length) {
  2204. this._proportionallyResize();
  2205. }
  2206. // Call the user callback if the element was resized
  2207. if ( ! $.isEmptyObject(props) ) {
  2208. this._trigger("resize", event, this.ui());
  2209. }
  2210. return false;
  2211. },
  2212. _mouseStop: function(event) {
  2213. this.resizing = false;
  2214. var pr, ista, soffseth, soffsetw, s, left, top,
  2215. o = this.options, that = this;
  2216. if(this._helper) {
  2217. pr = this._proportionallyResizeElements;
  2218. ista = pr.length && (/textarea/i).test(pr[0].nodeName);
  2219. soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height;
  2220. soffsetw = ista ? 0 : that.sizeDiff.width;
  2221. s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) };
  2222. left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null;
  2223. top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
  2224. if (!o.animate) {
  2225. this.element.css($.extend(s, { top: top, left: left }));
  2226. }
  2227. that.helper.height(that.size.height);
  2228. that.helper.width(that.size.width);
  2229. if (this._helper && !o.animate) {
  2230. this._proportionallyResize();
  2231. }
  2232. }
  2233. $("body").css("cursor", "auto");
  2234. this.element.removeClass("ui-resizable-resizing");
  2235. this._propagate("stop", event);
  2236. if (this._helper) {
  2237. this.helper.remove();
  2238. }
  2239. return false;
  2240. },
  2241. _updateVirtualBoundaries: function(forceAspectRatio) {
  2242. var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
  2243. o = this.options;
  2244. b = {
  2245. minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
  2246. maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
  2247. minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
  2248. maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
  2249. };
  2250. if(this._aspectRatio || forceAspectRatio) {
  2251. // We want to create an enclosing box whose aspect ration is the requested one
  2252. // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
  2253. pMinWidth = b.minHeight * this.aspectRatio;
  2254. pMinHeight = b.minWidth / this.aspectRatio;
  2255. pMaxWidth = b.maxHeight * this.aspectRatio;
  2256. pMaxHeight = b.maxWidth / this.aspectRatio;
  2257. if(pMinWidth > b.minWidth) {
  2258. b.minWidth = pMinWidth;
  2259. }
  2260. if(pMinHeight > b.minHeight) {
  2261. b.minHeight = pMinHeight;
  2262. }
  2263. if(pMaxWidth < b.maxWidth) {
  2264. b.maxWidth = pMaxWidth;
  2265. }
  2266. if(pMaxHeight < b.maxHeight) {
  2267. b.maxHeight = pMaxHeight;
  2268. }
  2269. }
  2270. this._vBoundaries = b;
  2271. },
  2272. _updateCache: function(data) {
  2273. this.offset = this.helper.offset();
  2274. if (isNumber(data.left)) {
  2275. this.position.left = data.left;
  2276. }
  2277. if (isNumber(data.top)) {
  2278. this.position.top = data.top;
  2279. }
  2280. if (isNumber(data.height)) {
  2281. this.size.height = data.height;
  2282. }
  2283. if (isNumber(data.width)) {
  2284. this.size.width = data.width;
  2285. }
  2286. },
  2287. _updateRatio: function( data ) {
  2288. var cpos = this.position,
  2289. csize = this.size,
  2290. a = this.axis;
  2291. if (isNumber(data.height)) {
  2292. data.width = (data.height * this.aspectRatio);
  2293. } else if (isNumber(data.width)) {
  2294. data.height = (data.width / this.aspectRatio);
  2295. }
  2296. if (a === "sw") {
  2297. data.left = cpos.left + (csize.width - data.width);
  2298. data.top = null;
  2299. }
  2300. if (a === "nw") {
  2301. data.top = cpos.top + (csize.height - data.height);
  2302. data.left = cpos.left + (csize.width - data.width);
  2303. }
  2304. return data;
  2305. },
  2306. _respectSize: function( data ) {
  2307. var o = this._vBoundaries,
  2308. a = this.axis,
  2309. ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
  2310. isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
  2311. dw = this.originalPosition.left + this.originalSize.width,
  2312. dh = this.position.top + this.size.height,
  2313. cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
  2314. if (isminw) {
  2315. data.width = o.minWidth;
  2316. }
  2317. if (isminh) {
  2318. data.height = o.minHeight;
  2319. }
  2320. if (ismaxw) {
  2321. data.width = o.maxWidth;
  2322. }
  2323. if (ismaxh) {
  2324. data.height = o.maxHeight;
  2325. }
  2326. if (isminw && cw) {
  2327. data.left = dw - o.minWidth;
  2328. }
  2329. if (ismaxw && cw) {
  2330. data.left = dw - o.maxWidth;
  2331. }
  2332. if (isminh && ch) {
  2333. data.top = dh - o.minHeight;
  2334. }
  2335. if (ismaxh && ch) {
  2336. data.top = dh - o.maxHeight;
  2337. }
  2338. // fixing jump error on top/left - bug #2330
  2339. if (!data.width && !data.height && !data.left && data.top) {
  2340. data.top = null;
  2341. } else if (!data.width && !data.height && !data.top && data.left) {
  2342. data.left = null;
  2343. }
  2344. return data;
  2345. },
  2346. _proportionallyResize: function() {
  2347. if (!this._proportionallyResizeElements.length) {
  2348. return;
  2349. }
  2350. var i, j, borders, paddings, prel,
  2351. element = this.helper || this.element;
  2352. for ( i=0; i < this._proportionallyResizeElements.length; i++) {
  2353. prel = this._proportionallyResizeElements[i];
  2354. if (!this.borderDif) {
  2355. this.borderDif = [];
  2356. borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")];
  2357. paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")];
  2358. for ( j = 0; j < borders.length; j++ ) {
  2359. this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 );
  2360. }
  2361. }
  2362. prel.css({
  2363. height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
  2364. width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
  2365. });
  2366. }
  2367. },
  2368. _renderProxy: function() {
  2369. var el = this.element, o = this.options;
  2370. this.elementOffset = el.offset();
  2371. if(this._helper) {
  2372. this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
  2373. this.helper.addClass(this._helper).css({
  2374. width: this.element.outerWidth() - 1,
  2375. height: this.element.outerHeight() - 1,
  2376. position: "absolute",
  2377. left: this.elementOffset.left +"px",
  2378. top: this.elementOffset.top +"px",
  2379. zIndex: ++o.zIndex //TODO: Don't modify option
  2380. });
  2381. this.helper
  2382. .appendTo("body")
  2383. .disableSelection();
  2384. } else {
  2385. this.helper = this.element;
  2386. }
  2387. },
  2388. _change: {
  2389. e: function(event, dx) {
  2390. return { width: this.originalSize.width + dx };
  2391. },
  2392. w: function(event, dx) {
  2393. var cs = this.originalSize, sp = this.originalPosition;
  2394. return { left: sp.left + dx, width: cs.width - dx };
  2395. },
  2396. n: function(event, dx, dy) {
  2397. var cs = this.originalSize, sp = this.originalPosition;
  2398. return { top: sp.top + dy, height: cs.height - dy };
  2399. },
  2400. s: function(event, dx, dy) {
  2401. return { height: this.originalSize.height + dy };
  2402. },
  2403. se: function(event, dx, dy) {
  2404. return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
  2405. },
  2406. sw: function(event, dx, dy) {
  2407. return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
  2408. },
  2409. ne: function(event, dx, dy) {
  2410. return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
  2411. },
  2412. nw: function(event, dx, dy) {
  2413. return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
  2414. }
  2415. },
  2416. _propagate: function(n, event) {
  2417. $.ui.plugin.call(this, n, [event, this.ui()]);
  2418. (n !== "resize" && this._trigger(n, event, this.ui()));
  2419. },
  2420. plugins: {},
  2421. ui: function() {
  2422. return {
  2423. originalElement: this.originalElement,
  2424. element: this.element,
  2425. helper: this.helper,
  2426. position: this.position,
  2427. size: this.size,
  2428. originalSize: this.originalSize,
  2429. originalPosition: this.originalPosition
  2430. };
  2431. }
  2432. });
  2433. /*
  2434. * Resizable Extensions
  2435. */
  2436. $.ui.plugin.add("resizable", "animate", {
  2437. stop: function( event ) {
  2438. var that = $(this).data("ui-resizable"),
  2439. o = that.options,
  2440. pr = that._proportionallyResizeElements,
  2441. ista = pr.length && (/textarea/i).test(pr[0].nodeName),
  2442. soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height,
  2443. soffsetw = ista ? 0 : that.sizeDiff.width,
  2444. style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
  2445. left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null,
  2446. top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
  2447. that.element.animate(
  2448. $.extend(style, top && left ? { top: top, left: left } : {}), {
  2449. duration: o.animateDuration,
  2450. easing: o.animateEasing,
  2451. step: function() {
  2452. var data = {
  2453. width: parseInt(that.element.css("width"), 10),
  2454. height: parseInt(that.element.css("height"), 10),
  2455. top: parseInt(that.element.css("top"), 10),
  2456. left: parseInt(that.element.css("left"), 10)
  2457. };
  2458. if (pr && pr.length) {
  2459. $(pr[0]).css({ width: data.width, height: data.height });
  2460. }
  2461. // propagating resize, and updating values for each animation step
  2462. that._updateCache(data);
  2463. that._propagate("resize", event);
  2464. }
  2465. }
  2466. );
  2467. }
  2468. });
  2469. $.ui.plugin.add("resizable", "containment", {
  2470. start: function() {
  2471. var element, p, co, ch, cw, width, height,
  2472. that = $(this).data("ui-resizable"),
  2473. o = that.options,
  2474. el = that.element,
  2475. oc = o.containment,
  2476. ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
  2477. if (!ce) {
  2478. return;
  2479. }
  2480. that.containerElement = $(ce);
  2481. if (/document/.test(oc) || oc === document) {
  2482. that.containerOffset = { left: 0, top: 0 };
  2483. that.containerPosition = { left: 0, top: 0 };
  2484. that.parentData = {
  2485. element: $(document), left: 0, top: 0,
  2486. width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
  2487. };
  2488. }
  2489. // i'm a node, so compute top, left, right, bottom
  2490. else {
  2491. element = $(ce);
  2492. p = [];
  2493. $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
  2494. that.containerOffset = element.offset();
  2495. that.containerPosition = element.position();
  2496. that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
  2497. co = that.containerOffset;
  2498. ch = that.containerSize.height;
  2499. cw = that.containerSize.width;
  2500. width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw );
  2501. height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
  2502. that.parentData = {
  2503. element: ce, left: co.left, top: co.top, width: width, height: height
  2504. };
  2505. }
  2506. },
  2507. resize: function( event ) {
  2508. var woset, hoset, isParent, isOffsetRelative,
  2509. that = $(this).data("ui-resizable"),
  2510. o = that.options,
  2511. co = that.containerOffset, cp = that.position,
  2512. pRatio = that._aspectRatio || event.shiftKey,
  2513. cop = { top:0, left:0 }, ce = that.containerElement;
  2514. if (ce[0] !== document && (/static/).test(ce.css("position"))) {
  2515. cop = co;
  2516. }
  2517. if (cp.left < (that._helper ? co.left : 0)) {
  2518. that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));
  2519. if (pRatio) {
  2520. that.size.height = that.size.width / that.aspectRatio;
  2521. }
  2522. that.position.left = o.helper ? co.left : 0;
  2523. }
  2524. if (cp.top < (that._helper ? co.top : 0)) {
  2525. that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);
  2526. if (pRatio) {
  2527. that.size.width = that.size.height * that.aspectRatio;
  2528. }
  2529. that.position.top = that._helper ? co.top : 0;
  2530. }
  2531. that.offset.left = that.parentData.left+that.position.left;
  2532. that.offset.top = that.parentData.top+that.position.top;
  2533. woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width );
  2534. hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );
  2535. isParent = that.containerElement.get(0) === that.element.parent().get(0);
  2536. isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position"));
  2537. if ( isParent && isOffsetRelative ) {
  2538. woset -= Math.abs( that.parentData.left );
  2539. }
  2540. if (woset + that.size.width >= that.parentData.width) {
  2541. that.size.width = that.parentData.width - woset;
  2542. if (pRatio) {
  2543. that.size.height = that.size.width / that.aspectRatio;
  2544. }
  2545. }
  2546. if (hoset + that.size.height >= that.parentData.height) {
  2547. that.size.height = that.parentData.height - hoset;
  2548. if (pRatio) {
  2549. that.size.width = that.size.height * that.aspectRatio;
  2550. }
  2551. }
  2552. },
  2553. stop: function(){
  2554. var that = $(this).data("ui-resizable"),
  2555. o = that.options,
  2556. co = that.containerOffset,
  2557. cop = that.containerPosition,
  2558. ce = that.containerElement,
  2559. helper = $(that.helper),
  2560. ho = helper.offset(),
  2561. w = helper.outerWidth() - that.sizeDiff.width,
  2562. h = helper.outerHeight() - that.sizeDiff.height;
  2563. if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) {
  2564. $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
  2565. }
  2566. if (that._helper && !o.animate && (/static/).test(ce.css("position"))) {
  2567. $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
  2568. }
  2569. }
  2570. });
  2571. $.ui.plugin.add("resizable", "alsoResize", {
  2572. start: function () {
  2573. var that = $(this).data("ui-resizable"),
  2574. o = that.options,
  2575. _store = function (exp) {
  2576. $(exp).each(function() {
  2577. var el = $(this);
  2578. el.data("ui-resizable-alsoresize", {
  2579. width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
  2580. left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
  2581. });
  2582. });
  2583. };
  2584. if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) {
  2585. if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
  2586. else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
  2587. }else{
  2588. _store(o.alsoResize);
  2589. }
  2590. },
  2591. resize: function (event, ui) {
  2592. var that = $(this).data("ui-resizable"),
  2593. o = that.options,
  2594. os = that.originalSize,
  2595. op = that.originalPosition,
  2596. delta = {
  2597. height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
  2598. top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0
  2599. },
  2600. _alsoResize = function (exp, c) {
  2601. $(exp).each(function() {
  2602. var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
  2603. css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"];
  2604. $.each(css, function (i, prop) {
  2605. var sum = (start[prop]||0) + (delta[prop]||0);
  2606. if (sum && sum >= 0) {
  2607. style[prop] = sum || null;
  2608. }
  2609. });
  2610. el.css(style);
  2611. });
  2612. };
  2613. if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) {
  2614. $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
  2615. }else{
  2616. _alsoResize(o.alsoResize);
  2617. }
  2618. },
  2619. stop: function () {
  2620. $(this).removeData("resizable-alsoresize");
  2621. }
  2622. });
  2623. $.ui.plugin.add("resizable", "ghost", {
  2624. start: function() {
  2625. var that = $(this).data("ui-resizable"), o = that.options, cs = that.size;
  2626. that.ghost = that.originalElement.clone();
  2627. that.ghost
  2628. .css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
  2629. .addClass("ui-resizable-ghost")
  2630. .addClass(typeof o.ghost === "string" ? o.ghost : "");
  2631. that.ghost.appendTo(that.helper);
  2632. },
  2633. resize: function(){
  2634. var that = $(this).data("ui-resizable");
  2635. if (that.ghost) {
  2636. that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width });
  2637. }
  2638. },
  2639. stop: function() {
  2640. var that = $(this).data("ui-resizable");
  2641. if (that.ghost && that.helper) {
  2642. that.helper.get(0).removeChild(that.ghost.get(0));
  2643. }
  2644. }
  2645. });
  2646. $.ui.plugin.add("resizable", "grid", {
  2647. resize: function() {
  2648. var that = $(this).data("ui-resizable"),
  2649. o = that.options,
  2650. cs = that.size,
  2651. os = that.originalSize,
  2652. op = that.originalPosition,
  2653. a = that.axis,
  2654. grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid,
  2655. gridX = (grid[0]||1),
  2656. gridY = (grid[1]||1),
  2657. ox = Math.round((cs.width - os.width) / gridX) * gridX,
  2658. oy = Math.round((cs.height - os.height) / gridY) * gridY,
  2659. newWidth = os.width + ox,
  2660. newHeight = os.height + oy,
  2661. isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
  2662. isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
  2663. isMinWidth = o.minWidth && (o.minWidth > newWidth),
  2664. isMinHeight = o.minHeight && (o.minHeight > newHeight);
  2665. o.grid = grid;
  2666. if (isMinWidth) {
  2667. newWidth = newWidth + gridX;
  2668. }
  2669. if (isMinHeight) {
  2670. newHeight = newHeight + gridY;
  2671. }
  2672. if (isMaxWidth) {
  2673. newWidth = newWidth - gridX;
  2674. }
  2675. if (isMaxHeight) {
  2676. newHeight = newHeight - gridY;
  2677. }
  2678. if (/^(se|s|e)$/.test(a)) {
  2679. that.size.width = newWidth;
  2680. that.size.height = newHeight;
  2681. } else if (/^(ne)$/.test(a)) {
  2682. that.size.width = newWidth;
  2683. that.size.height = newHeight;
  2684. that.position.top = op.top - oy;
  2685. } else if (/^(sw)$/.test(a)) {
  2686. that.size.width = newWidth;
  2687. that.size.height = newHeight;
  2688. that.position.left = op.left - ox;
  2689. } else {
  2690. if ( newHeight - gridY > 0 ) {
  2691. that.size.height = newHeight;
  2692. that.position.top = op.top - oy;
  2693. } else {
  2694. that.size.height = gridY;
  2695. that.position.top = op.top + os.height - gridY;
  2696. }
  2697. if ( newWidth - gridX > 0 ) {
  2698. that.size.width = newWidth;
  2699. that.position.left = op.left - ox;
  2700. } else {
  2701. that.size.width = gridX;
  2702. that.position.left = op.left + os.width - gridX;
  2703. }
  2704. }
  2705. }
  2706. });
  2707. })(jQuery);
  2708. (function( $, undefined ) {
  2709. var lastActive,
  2710. baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
  2711. typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
  2712. formResetHandler = function() {
  2713. var form = $( this );
  2714. setTimeout(function() {
  2715. form.find( ":ui-button" ).button( "refresh" );
  2716. }, 1 );
  2717. },
  2718. radioGroup = function( radio ) {
  2719. var name = radio.name,
  2720. form = radio.form,
  2721. radios = $( [] );
  2722. if ( name ) {
  2723. name = name.replace( /'/g, "\\'" );
  2724. if ( form ) {
  2725. radios = $( form ).find( "[name='" + name + "']" );
  2726. } else {
  2727. radios = $( "[name='" + name + "']", radio.ownerDocument )
  2728. .filter(function() {
  2729. return !this.form;
  2730. });
  2731. }
  2732. }
  2733. return radios;
  2734. };
  2735. $.widget( "ui.button", {
  2736. version: "1.10.4",
  2737. defaultElement: "<button>",
  2738. options: {
  2739. disabled: null,
  2740. text: true,
  2741. label: null,
  2742. icons: {
  2743. primary: null,
  2744. secondary: null
  2745. }
  2746. },
  2747. _create: function() {
  2748. this.element.closest( "form" )
  2749. .unbind( "reset" + this.eventNamespace )
  2750. .bind( "reset" + this.eventNamespace, formResetHandler );
  2751. if ( typeof this.options.disabled !== "boolean" ) {
  2752. this.options.disabled = !!this.element.prop( "disabled" );
  2753. } else {
  2754. this.element.prop( "disabled", this.options.disabled );
  2755. }
  2756. this._determineButtonType();
  2757. this.hasTitle = !!this.buttonElement.attr( "title" );
  2758. var that = this,
  2759. options = this.options,
  2760. toggleButton = this.type === "checkbox" || this.type === "radio",
  2761. activeClass = !toggleButton ? "ui-state-active" : "";
  2762. if ( options.label === null ) {
  2763. options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
  2764. }
  2765. this._hoverable( this.buttonElement );
  2766. this.buttonElement
  2767. .addClass( baseClasses )
  2768. .attr( "role", "button" )
  2769. .bind( "mouseenter" + this.eventNamespace, function() {
  2770. if ( options.disabled ) {
  2771. return;
  2772. }
  2773. if ( this === lastActive ) {
  2774. $( this ).addClass( "ui-state-active" );
  2775. }
  2776. })
  2777. .bind( "mouseleave" + this.eventNamespace, function() {
  2778. if ( options.disabled ) {
  2779. return;
  2780. }
  2781. $( this ).removeClass( activeClass );
  2782. })
  2783. .bind( "click" + this.eventNamespace, function( event ) {
  2784. if ( options.disabled ) {
  2785. event.preventDefault();
  2786. event.stopImmediatePropagation();
  2787. }
  2788. });
  2789. // Can't use _focusable() because the element that receives focus
  2790. // and the element that gets the ui-state-focus class are different
  2791. this._on({
  2792. focus: function() {
  2793. this.buttonElement.addClass( "ui-state-focus" );
  2794. },
  2795. blur: function() {
  2796. this.buttonElement.removeClass( "ui-state-focus" );
  2797. }
  2798. });
  2799. if ( toggleButton ) {
  2800. this.element.bind( "change" + this.eventNamespace, function() {
  2801. that.refresh();
  2802. });
  2803. }
  2804. if ( this.type === "checkbox" ) {
  2805. this.buttonElement.bind( "click" + this.eventNamespace, function() {
  2806. if ( options.disabled ) {
  2807. return false;
  2808. }
  2809. });
  2810. } else if ( this.type === "radio" ) {
  2811. this.buttonElement.bind( "click" + this.eventNamespace, function() {
  2812. if ( options.disabled ) {
  2813. return false;
  2814. }
  2815. $( this ).addClass( "ui-state-active" );
  2816. that.buttonElement.attr( "aria-pressed", "true" );
  2817. var radio = that.element[ 0 ];
  2818. radioGroup( radio )
  2819. .not( radio )
  2820. .map(function() {
  2821. return $( this ).button( "widget" )[ 0 ];
  2822. })
  2823. .removeClass( "ui-state-active" )
  2824. .attr( "aria-pressed", "false" );
  2825. });
  2826. } else {
  2827. this.buttonElement
  2828. .bind( "mousedown" + this.eventNamespace, function() {
  2829. if ( options.disabled ) {
  2830. return false;
  2831. }
  2832. $( this ).addClass( "ui-state-active" );
  2833. lastActive = this;
  2834. that.document.one( "mouseup", function() {
  2835. lastActive = null;
  2836. });
  2837. })
  2838. .bind( "mouseup" + this.eventNamespace, function() {
  2839. if ( options.disabled ) {
  2840. return false;
  2841. }
  2842. $( this ).removeClass( "ui-state-active" );
  2843. })
  2844. .bind( "keydown" + this.eventNamespace, function(event) {
  2845. if ( options.disabled ) {
  2846. return false;
  2847. }
  2848. if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
  2849. $( this ).addClass( "ui-state-active" );
  2850. }
  2851. })
  2852. // see #8559, we bind to blur here in case the button element loses
  2853. // focus between keydown and keyup, it would be left in an "active" state
  2854. .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
  2855. $( this ).removeClass( "ui-state-active" );
  2856. });
  2857. if ( this.buttonElement.is("a") ) {
  2858. this.buttonElement.keyup(function(event) {
  2859. if ( event.keyCode === $.ui.keyCode.SPACE ) {
  2860. // TODO pass through original event correctly (just as 2nd argument doesn't work)
  2861. $( this ).click();
  2862. }
  2863. });
  2864. }
  2865. }
  2866. // TODO: pull out $.Widget's handling for the disabled option into
  2867. // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
  2868. // be overridden by individual plugins
  2869. this._setOption( "disabled", options.disabled );
  2870. this._resetButton();
  2871. },
  2872. _determineButtonType: function() {
  2873. var ancestor, labelSelector, checked;
  2874. if ( this.element.is("[type=checkbox]") ) {
  2875. this.type = "checkbox";
  2876. } else if ( this.element.is("[type=radio]") ) {
  2877. this.type = "radio";
  2878. } else if ( this.element.is("input") ) {
  2879. this.type = "input";
  2880. } else {
  2881. this.type = "button";
  2882. }
  2883. if ( this.type === "checkbox" || this.type === "radio" ) {
  2884. // we don't search against the document in case the element
  2885. // is disconnected from the DOM
  2886. ancestor = this.element.parents().last();
  2887. labelSelector = "label[for='" + this.element.attr("id") + "']";
  2888. this.buttonElement = ancestor.find( labelSelector );
  2889. if ( !this.buttonElement.length ) {
  2890. ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
  2891. this.buttonElement = ancestor.filter( labelSelector );
  2892. if ( !this.buttonElement.length ) {
  2893. this.buttonElement = ancestor.find( labelSelector );
  2894. }
  2895. }
  2896. this.element.addClass( "ui-helper-hidden-accessible" );
  2897. checked = this.element.is( ":checked" );
  2898. if ( checked ) {
  2899. this.buttonElement.addClass( "ui-state-active" );
  2900. }
  2901. this.buttonElement.prop( "aria-pressed", checked );
  2902. } else {
  2903. this.buttonElement = this.element;
  2904. }
  2905. },
  2906. widget: function() {
  2907. return this.buttonElement;
  2908. },
  2909. _destroy: function() {
  2910. this.element
  2911. .removeClass( "ui-helper-hidden-accessible" );
  2912. this.buttonElement
  2913. .removeClass( baseClasses + " ui-state-active " + typeClasses )
  2914. .removeAttr( "role" )
  2915. .removeAttr( "aria-pressed" )
  2916. .html( this.buttonElement.find(".ui-button-text").html() );
  2917. if ( !this.hasTitle ) {
  2918. this.buttonElement.removeAttr( "title" );
  2919. }
  2920. },
  2921. _setOption: function( key, value ) {
  2922. this._super( key, value );
  2923. if ( key === "disabled" ) {
  2924. this.element.prop( "disabled", !!value );
  2925. if ( value ) {
  2926. this.buttonElement.removeClass( "ui-state-focus" );
  2927. }
  2928. return;
  2929. }
  2930. this._resetButton();
  2931. },
  2932. refresh: function() {
  2933. //See #8237 & #8828
  2934. var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
  2935. if ( isDisabled !== this.options.disabled ) {
  2936. this._setOption( "disabled", isDisabled );
  2937. }
  2938. if ( this.type === "radio" ) {
  2939. radioGroup( this.element[0] ).each(function() {
  2940. if ( $( this ).is( ":checked" ) ) {
  2941. $( this ).button( "widget" )
  2942. .addClass( "ui-state-active" )
  2943. .attr( "aria-pressed", "true" );
  2944. } else {
  2945. $( this ).button( "widget" )
  2946. .removeClass( "ui-state-active" )
  2947. .attr( "aria-pressed", "false" );
  2948. }
  2949. });
  2950. } else if ( this.type === "checkbox" ) {
  2951. if ( this.element.is( ":checked" ) ) {
  2952. this.buttonElement
  2953. .addClass( "ui-state-active" )
  2954. .attr( "aria-pressed", "true" );
  2955. } else {
  2956. this.buttonElement
  2957. .removeClass( "ui-state-active" )
  2958. .attr( "aria-pressed", "false" );
  2959. }
  2960. }
  2961. },
  2962. _resetButton: function() {
  2963. if ( this.type === "input" ) {
  2964. if ( this.options.label ) {
  2965. this.element.val( this.options.label );
  2966. }
  2967. return;
  2968. }
  2969. var buttonElement = this.buttonElement.removeClass( typeClasses ),
  2970. buttonText = $( "<span></span>", this.document[0] )
  2971. .addClass( "ui-button-text" )
  2972. .html( this.options.label )
  2973. .appendTo( buttonElement.empty() )
  2974. .text(),
  2975. icons = this.options.icons,
  2976. multipleIcons = icons.primary && icons.secondary,
  2977. buttonClasses = [];
  2978. if ( icons.primary || icons.secondary ) {
  2979. if ( this.options.text ) {
  2980. buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
  2981. }
  2982. if ( icons.primary ) {
  2983. buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
  2984. }
  2985. if ( icons.secondary ) {
  2986. buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
  2987. }
  2988. if ( !this.options.text ) {
  2989. buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
  2990. if ( !this.hasTitle ) {
  2991. buttonElement.attr( "title", $.trim( buttonText ) );
  2992. }
  2993. }
  2994. } else {
  2995. buttonClasses.push( "ui-button-text-only" );
  2996. }
  2997. buttonElement.addClass( buttonClasses.join( " " ) );
  2998. }
  2999. });
  3000. $.widget( "ui.buttonset", {
  3001. version: "1.10.4",
  3002. options: {
  3003. items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
  3004. },
  3005. _create: function() {
  3006. this.element.addClass( "ui-buttonset" );
  3007. },
  3008. _init: function() {
  3009. this.refresh();
  3010. },
  3011. _setOption: function( key, value ) {
  3012. if ( key === "disabled" ) {
  3013. this.buttons.button( "option", key, value );
  3014. }
  3015. this._super( key, value );
  3016. },
  3017. refresh: function() {
  3018. var rtl = this.element.css( "direction" ) === "rtl";
  3019. this.buttons = this.element.find( this.options.items )
  3020. .filter( ":ui-button" )
  3021. .button( "refresh" )
  3022. .end()
  3023. .not( ":ui-button" )
  3024. .button()
  3025. .end()
  3026. .map(function() {
  3027. return $( this ).button( "widget" )[ 0 ];
  3028. })
  3029. .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
  3030. .filter( ":first" )
  3031. .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
  3032. .end()
  3033. .filter( ":last" )
  3034. .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
  3035. .end()
  3036. .end();
  3037. },
  3038. _destroy: function() {
  3039. this.element.removeClass( "ui-buttonset" );
  3040. this.buttons
  3041. .map(function() {
  3042. return $( this ).button( "widget" )[ 0 ];
  3043. })
  3044. .removeClass( "ui-corner-left ui-corner-right" )
  3045. .end()
  3046. .button( "destroy" );
  3047. }
  3048. });
  3049. }( jQuery ) );
  3050. (function( $, undefined ) {
  3051. // number of pages in a slider
  3052. // (how many times can you page up/down to go through the whole range)
  3053. var numPages = 5;
  3054. $.widget( "ui.slider", $.ui.mouse, {
  3055. version: "1.10.4",
  3056. widgetEventPrefix: "slide",
  3057. options: {
  3058. animate: false,
  3059. distance: 0,
  3060. max: 100,
  3061. min: 0,
  3062. orientation: "horizontal",
  3063. range: false,
  3064. step: 1,
  3065. value: 0,
  3066. values: null,
  3067. // callbacks
  3068. change: null,
  3069. slide: null,
  3070. start: null,
  3071. stop: null
  3072. },
  3073. _create: function() {
  3074. this._keySliding = false;
  3075. this._mouseSliding = false;
  3076. this._animateOff = true;
  3077. this._handleIndex = null;
  3078. this._detectOrientation();
  3079. this._mouseInit();
  3080. this.element
  3081. .addClass( "ui-slider" +
  3082. " ui-slider-" + this.orientation +
  3083. " ui-widget" +
  3084. " ui-widget-content" +
  3085. " ui-corner-all");
  3086. this._refresh();
  3087. this._setOption( "disabled", this.options.disabled );
  3088. this._animateOff = false;
  3089. },
  3090. _refresh: function() {
  3091. this._createRange();
  3092. this._createHandles();
  3093. this._setupEvents();
  3094. this._refreshValue();
  3095. },
  3096. _createHandles: function() {
  3097. var i, handleCount,
  3098. options = this.options,
  3099. existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
  3100. handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
  3101. handles = [];
  3102. handleCount = ( options.values && options.values.length ) || 1;
  3103. if ( existingHandles.length > handleCount ) {
  3104. existingHandles.slice( handleCount ).remove();
  3105. existingHandles = existingHandles.slice( 0, handleCount );
  3106. }
  3107. for ( i = existingHandles.length; i < handleCount; i++ ) {
  3108. handles.push( handle );
  3109. }
  3110. this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
  3111. this.handle = this.handles.eq( 0 );
  3112. this.handles.each(function( i ) {
  3113. $( this ).data( "ui-slider-handle-index", i );
  3114. });
  3115. },
  3116. _createRange: function() {
  3117. var options = this.options,
  3118. classes = "";
  3119. if ( options.range ) {
  3120. if ( options.range === true ) {
  3121. if ( !options.values ) {
  3122. options.values = [ this._valueMin(), this._valueMin() ];
  3123. } else if ( options.values.length && options.values.length !== 2 ) {
  3124. options.values = [ options.values[0], options.values[0] ];
  3125. } else if ( $.isArray( options.values ) ) {
  3126. options.values = options.values.slice(0);
  3127. }
  3128. }
  3129. if ( !this.range || !this.range.length ) {
  3130. this.range = $( "<div></div>" )
  3131. .appendTo( this.element );
  3132. classes = "ui-slider-range" +
  3133. // note: this isn't the most fittingly semantic framework class for this element,
  3134. // but worked best visually with a variety of themes
  3135. " ui-widget-header ui-corner-all";
  3136. } else {
  3137. this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
  3138. // Handle range switching from true to min/max
  3139. .css({
  3140. "left": "",
  3141. "bottom": ""
  3142. });
  3143. }
  3144. this.range.addClass( classes +
  3145. ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
  3146. } else {
  3147. if ( this.range ) {
  3148. this.range.remove();
  3149. }
  3150. this.range = null;
  3151. }
  3152. },
  3153. _setupEvents: function() {
  3154. var elements = this.handles.add( this.range ).filter( "a" );
  3155. this._off( elements );
  3156. this._on( elements, this._handleEvents );
  3157. this._hoverable( elements );
  3158. this._focusable( elements );
  3159. },
  3160. _destroy: function() {
  3161. this.handles.remove();
  3162. if ( this.range ) {
  3163. this.range.remove();
  3164. }
  3165. this.element
  3166. .removeClass( "ui-slider" +
  3167. " ui-slider-horizontal" +
  3168. " ui-slider-vertical" +
  3169. " ui-widget" +
  3170. " ui-widget-content" +
  3171. " ui-corner-all" );
  3172. this._mouseDestroy();
  3173. },
  3174. _mouseCapture: function( event ) {
  3175. var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
  3176. that = this,
  3177. o = this.options;
  3178. if ( o.disabled ) {
  3179. return false;
  3180. }
  3181. this.elementSize = {
  3182. width: this.element.outerWidth(),
  3183. height: this.element.outerHeight()
  3184. };
  3185. this.elementOffset = this.element.offset();
  3186. position = { x: event.pageX, y: event.pageY };
  3187. normValue = this._normValueFromMouse( position );
  3188. distance = this._valueMax() - this._valueMin() + 1;
  3189. this.handles.each(function( i ) {
  3190. var thisDistance = Math.abs( normValue - that.values(i) );
  3191. if (( distance > thisDistance ) ||
  3192. ( distance === thisDistance &&
  3193. (i === that._lastChangedValue || that.values(i) === o.min ))) {
  3194. distance = thisDistance;
  3195. closestHandle = $( this );
  3196. index = i;
  3197. }
  3198. });
  3199. allowed = this._start( event, index );
  3200. if ( allowed === false ) {
  3201. return false;
  3202. }
  3203. this._mouseSliding = true;
  3204. this._handleIndex = index;
  3205. closestHandle
  3206. .addClass( "ui-state-active" )
  3207. .focus();
  3208. offset = closestHandle.offset();
  3209. mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
  3210. this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
  3211. left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
  3212. top: event.pageY - offset.top -
  3213. ( closestHandle.height() / 2 ) -
  3214. ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
  3215. ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
  3216. ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
  3217. };
  3218. if ( !this.handles.hasClass( "ui-state-hover" ) ) {
  3219. this._slide( event, index, normValue );
  3220. }
  3221. this._animateOff = true;
  3222. return true;
  3223. },
  3224. _mouseStart: function() {
  3225. return true;
  3226. },
  3227. _mouseDrag: function( event ) {
  3228. var position = { x: event.pageX, y: event.pageY },
  3229. normValue = this._normValueFromMouse( position );
  3230. this._slide( event, this._handleIndex, normValue );
  3231. return false;
  3232. },
  3233. _mouseStop: function( event ) {
  3234. this.handles.removeClass( "ui-state-active" );
  3235. this._mouseSliding = false;
  3236. this._stop( event, this._handleIndex );
  3237. this._change( event, this._handleIndex );
  3238. this._handleIndex = null;
  3239. this._clickOffset = null;
  3240. this._animateOff = false;
  3241. return false;
  3242. },
  3243. _detectOrientation: function() {
  3244. this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
  3245. },
  3246. _normValueFromMouse: function( position ) {
  3247. var pixelTotal,
  3248. pixelMouse,
  3249. percentMouse,
  3250. valueTotal,
  3251. valueMouse;
  3252. if ( this.orientation === "horizontal" ) {
  3253. pixelTotal = this.elementSize.width;
  3254. pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
  3255. } else {
  3256. pixelTotal = this.elementSize.height;
  3257. pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
  3258. }
  3259. percentMouse = ( pixelMouse / pixelTotal );
  3260. if ( percentMouse > 1 ) {
  3261. percentMouse = 1;
  3262. }
  3263. if ( percentMouse < 0 ) {
  3264. percentMouse = 0;
  3265. }
  3266. if ( this.orientation === "vertical" ) {
  3267. percentMouse = 1 - percentMouse;
  3268. }
  3269. valueTotal = this._valueMax() - this._valueMin();
  3270. valueMouse = this._valueMin() + percentMouse * valueTotal;
  3271. return this._trimAlignValue( valueMouse );
  3272. },
  3273. _start: function( event, index ) {
  3274. var uiHash = {
  3275. handle: this.handles[ index ],
  3276. value: this.value()
  3277. };
  3278. if ( this.options.values && this.options.values.length ) {
  3279. uiHash.value = this.values( index );
  3280. uiHash.values = this.values();
  3281. }
  3282. return this._trigger( "start", event, uiHash );
  3283. },
  3284. _slide: function( event, index, newVal ) {
  3285. var otherVal,
  3286. newValues,
  3287. allowed;
  3288. if ( this.options.values && this.options.values.length ) {
  3289. otherVal = this.values( index ? 0 : 1 );
  3290. if ( ( this.options.values.length === 2 && this.options.range === true ) &&
  3291. ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
  3292. ) {
  3293. newVal = otherVal;
  3294. }
  3295. if ( newVal !== this.values( index ) ) {
  3296. newValues = this.values();
  3297. newValues[ index ] = newVal;
  3298. // A slide can be canceled by returning false from the slide callback
  3299. allowed = this._trigger( "slide", event, {
  3300. handle: this.handles[ index ],
  3301. value: newVal,
  3302. values: newValues
  3303. } );
  3304. otherVal = this.values( index ? 0 : 1 );
  3305. if ( allowed !== false ) {
  3306. this.values( index, newVal );
  3307. }
  3308. }
  3309. } else {
  3310. if ( newVal !== this.value() ) {
  3311. // A slide can be canceled by returning false from the slide callback
  3312. allowed = this._trigger( "slide", event, {
  3313. handle: this.handles[ index ],
  3314. value: newVal
  3315. } );
  3316. if ( allowed !== false ) {
  3317. this.value( newVal );
  3318. }
  3319. }
  3320. }
  3321. },
  3322. _stop: function( event, index ) {
  3323. var uiHash = {
  3324. handle: this.handles[ index ],
  3325. value: this.value()
  3326. };
  3327. if ( this.options.values && this.options.values.length ) {
  3328. uiHash.value = this.values( index );
  3329. uiHash.values = this.values();
  3330. }
  3331. this._trigger( "stop", event, uiHash );
  3332. },
  3333. _change: function( event, index ) {
  3334. if ( !this._keySliding && !this._mouseSliding ) {
  3335. var uiHash = {
  3336. handle: this.handles[ index ],
  3337. value: this.value()
  3338. };
  3339. if ( this.options.values && this.options.values.length ) {
  3340. uiHash.value = this.values( index );
  3341. uiHash.values = this.values();
  3342. }
  3343. //store the last changed value index for reference when handles overlap
  3344. this._lastChangedValue = index;
  3345. this._trigger( "change", event, uiHash );
  3346. }
  3347. },
  3348. value: function( newValue ) {
  3349. if ( arguments.length ) {
  3350. this.options.value = this._trimAlignValue( newValue );
  3351. this._refreshValue();
  3352. this._change( null, 0 );
  3353. return;
  3354. }
  3355. return this._value();
  3356. },
  3357. values: function( index, newValue ) {
  3358. var vals,
  3359. newValues,
  3360. i;
  3361. if ( arguments.length > 1 ) {
  3362. this.options.values[ index ] = this._trimAlignValue( newValue );
  3363. this._refreshValue();
  3364. this._change( null, index );
  3365. return;
  3366. }
  3367. if ( arguments.length ) {
  3368. if ( $.isArray( arguments[ 0 ] ) ) {
  3369. vals = this.options.values;
  3370. newValues = arguments[ 0 ];
  3371. for ( i = 0; i < vals.length; i += 1 ) {
  3372. vals[ i ] = this._trimAlignValue( newValues[ i ] );
  3373. this._change( null, i );
  3374. }
  3375. this._refreshValue();
  3376. } else {
  3377. if ( this.options.values && this.options.values.length ) {
  3378. return this._values( index );
  3379. } else {
  3380. return this.value();
  3381. }
  3382. }
  3383. } else {
  3384. return this._values();
  3385. }
  3386. },
  3387. _setOption: function( key, value ) {
  3388. var i,
  3389. valsLength = 0;
  3390. if ( key === "range" && this.options.range === true ) {
  3391. if ( value === "min" ) {
  3392. this.options.value = this._values( 0 );
  3393. this.options.values = null;
  3394. } else if ( value === "max" ) {
  3395. this.options.value = this._values( this.options.values.length-1 );
  3396. this.options.values = null;
  3397. }
  3398. }
  3399. if ( $.isArray( this.options.values ) ) {
  3400. valsLength = this.options.values.length;
  3401. }
  3402. $.Widget.prototype._setOption.apply( this, arguments );
  3403. switch ( key ) {
  3404. case "orientation":
  3405. this._detectOrientation();
  3406. this.element
  3407. .removeClass( "ui-slider-horizontal ui-slider-vertical" )
  3408. .addClass( "ui-slider-" + this.orientation );
  3409. this._refreshValue();
  3410. break;
  3411. case "value":
  3412. this._animateOff = true;
  3413. this._refreshValue();
  3414. this._change( null, 0 );
  3415. this._animateOff = false;
  3416. break;
  3417. case "values":
  3418. this._animateOff = true;
  3419. this._refreshValue();
  3420. for ( i = 0; i < valsLength; i += 1 ) {
  3421. this._change( null, i );
  3422. }
  3423. this._animateOff = false;
  3424. break;
  3425. case "min":
  3426. case "max":
  3427. this._animateOff = true;
  3428. this._refreshValue();
  3429. this._animateOff = false;
  3430. break;
  3431. case "range":
  3432. this._animateOff = true;
  3433. this._refresh();
  3434. this._animateOff = false;
  3435. break;
  3436. }
  3437. },
  3438. //internal value getter
  3439. // _value() returns value trimmed by min and max, aligned by step
  3440. _value: function() {
  3441. var val = this.options.value;
  3442. val = this._trimAlignValue( val );
  3443. return val;
  3444. },
  3445. //internal values getter
  3446. // _values() returns array of values trimmed by min and max, aligned by step
  3447. // _values( index ) returns single value trimmed by min and max, aligned by step
  3448. _values: function( index ) {
  3449. var val,
  3450. vals,
  3451. i;
  3452. if ( arguments.length ) {
  3453. val = this.options.values[ index ];
  3454. val = this._trimAlignValue( val );
  3455. return val;
  3456. } else if ( this.options.values && this.options.values.length ) {
  3457. // .slice() creates a copy of the array
  3458. // this copy gets trimmed by min and max and then returned
  3459. vals = this.options.values.slice();
  3460. for ( i = 0; i < vals.length; i+= 1) {
  3461. vals[ i ] = this._trimAlignValue( vals[ i ] );
  3462. }
  3463. return vals;
  3464. } else {
  3465. return [];
  3466. }
  3467. },
  3468. // returns the step-aligned value that val is closest to, between (inclusive) min and max
  3469. _trimAlignValue: function( val ) {
  3470. if ( val <= this._valueMin() ) {
  3471. return this._valueMin();
  3472. }
  3473. if ( val >= this._valueMax() ) {
  3474. return this._valueMax();
  3475. }
  3476. var step = ( this.options.step > 0 ) ? this.options.step : 1,
  3477. valModStep = (val - this._valueMin()) % step,
  3478. alignValue = val - valModStep;
  3479. if ( Math.abs(valModStep) * 2 >= step ) {
  3480. alignValue += ( valModStep > 0 ) ? step : ( -step );
  3481. }
  3482. // Since JavaScript has problems with large floats, round
  3483. // the final value to 5 digits after the decimal point (see #4124)
  3484. return parseFloat( alignValue.toFixed(5) );
  3485. },
  3486. _valueMin: function() {
  3487. return this.options.min;
  3488. },
  3489. _valueMax: function() {
  3490. return this.options.max;
  3491. },
  3492. _refreshValue: function() {
  3493. var lastValPercent, valPercent, value, valueMin, valueMax,
  3494. oRange = this.options.range,
  3495. o = this.options,
  3496. that = this,
  3497. animate = ( !this._animateOff ) ? o.animate : false,
  3498. _set = {};
  3499. if ( this.options.values && this.options.values.length ) {
  3500. this.handles.each(function( i ) {
  3501. valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
  3502. _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
  3503. $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
  3504. if ( that.options.range === true ) {
  3505. if ( that.orientation === "horizontal" ) {
  3506. if ( i === 0 ) {
  3507. that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
  3508. }
  3509. if ( i === 1 ) {
  3510. that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
  3511. }
  3512. } else {
  3513. if ( i === 0 ) {
  3514. that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
  3515. }
  3516. if ( i === 1 ) {
  3517. that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
  3518. }
  3519. }
  3520. }
  3521. lastValPercent = valPercent;
  3522. });
  3523. } else {
  3524. value = this.value();
  3525. valueMin = this._valueMin();
  3526. valueMax = this._valueMax();
  3527. valPercent = ( valueMax !== valueMin ) ?
  3528. ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
  3529. 0;
  3530. _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
  3531. this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
  3532. if ( oRange === "min" && this.orientation === "horizontal" ) {
  3533. this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
  3534. }
  3535. if ( oRange === "max" && this.orientation === "horizontal" ) {
  3536. this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
  3537. }
  3538. if ( oRange === "min" && this.orientation === "vertical" ) {
  3539. this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
  3540. }
  3541. if ( oRange === "max" && this.orientation === "vertical" ) {
  3542. this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
  3543. }
  3544. }
  3545. },
  3546. _handleEvents: {
  3547. keydown: function( event ) {
  3548. var allowed, curVal, newVal, step,
  3549. index = $( event.target ).data( "ui-slider-handle-index" );
  3550. switch ( event.keyCode ) {
  3551. case $.ui.keyCode.HOME:
  3552. case $.ui.keyCode.END:
  3553. case $.ui.keyCode.PAGE_UP:
  3554. case $.ui.keyCode.PAGE_DOWN:
  3555. case $.ui.keyCode.UP:
  3556. case $.ui.keyCode.RIGHT:
  3557. case $.ui.keyCode.DOWN:
  3558. case $.ui.keyCode.LEFT:
  3559. event.preventDefault();
  3560. if ( !this._keySliding ) {
  3561. this._keySliding = true;
  3562. $( event.target ).addClass( "ui-state-active" );
  3563. allowed = this._start( event, index );
  3564. if ( allowed === false ) {
  3565. return;
  3566. }
  3567. }
  3568. break;
  3569. }
  3570. step = this.options.step;
  3571. if ( this.options.values && this.options.values.length ) {
  3572. curVal = newVal = this.values( index );
  3573. } else {
  3574. curVal = newVal = this.value();
  3575. }
  3576. switch ( event.keyCode ) {
  3577. case $.ui.keyCode.HOME:
  3578. newVal = this._valueMin();
  3579. break;
  3580. case $.ui.keyCode.END:
  3581. newVal = this._valueMax();
  3582. break;
  3583. case $.ui.keyCode.PAGE_UP:
  3584. newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );
  3585. break;
  3586. case $.ui.keyCode.PAGE_DOWN:
  3587. newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );
  3588. break;
  3589. case $.ui.keyCode.UP:
  3590. case $.ui.keyCode.RIGHT:
  3591. if ( curVal === this._valueMax() ) {
  3592. return;
  3593. }
  3594. newVal = this._trimAlignValue( curVal + step );
  3595. break;
  3596. case $.ui.keyCode.DOWN:
  3597. case $.ui.keyCode.LEFT:
  3598. if ( curVal === this._valueMin() ) {
  3599. return;
  3600. }
  3601. newVal = this._trimAlignValue( curVal - step );
  3602. break;
  3603. }
  3604. this._slide( event, index, newVal );
  3605. },
  3606. click: function( event ) {
  3607. event.preventDefault();
  3608. },
  3609. keyup: function( event ) {
  3610. var index = $( event.target ).data( "ui-slider-handle-index" );
  3611. if ( this._keySliding ) {
  3612. this._keySliding = false;
  3613. this._stop( event, index );
  3614. this._change( event, index );
  3615. $( event.target ).removeClass( "ui-state-active" );
  3616. }
  3617. }
  3618. }
  3619. });
  3620. }(jQuery));
  3621. (function( $ ) {
  3622. function modifier( fn ) {
  3623. return function() {
  3624. var previous = this.element.val();
  3625. fn.apply( this, arguments );
  3626. this._refresh();
  3627. if ( previous !== this.element.val() ) {
  3628. this._trigger( "change" );
  3629. }
  3630. };
  3631. }
  3632. $.widget( "ui.spinner", {
  3633. version: "1.10.4",
  3634. defaultElement: "<input>",
  3635. widgetEventPrefix: "spin",
  3636. options: {
  3637. culture: null,
  3638. icons: {
  3639. down: "ui-icon-triangle-1-s",
  3640. up: "ui-icon-triangle-1-n"
  3641. },
  3642. incremental: true,
  3643. max: null,
  3644. min: null,
  3645. numberFormat: null,
  3646. page: 10,
  3647. step: 1,
  3648. change: null,
  3649. spin: null,
  3650. start: null,
  3651. stop: null
  3652. },
  3653. _create: function() {
  3654. // handle string values that need to be parsed
  3655. this._setOption( "max", this.options.max );
  3656. this._setOption( "min", this.options.min );
  3657. this._setOption( "step", this.options.step );
  3658. // Only format if there is a value, prevents the field from being marked
  3659. // as invalid in Firefox, see #9573.
  3660. if ( this.value() !== "" ) {
  3661. // Format the value, but don't constrain.
  3662. this._value( this.element.val(), true );
  3663. }
  3664. this._draw();
  3665. this._on( this._events );
  3666. this._refresh();
  3667. // turning off autocomplete prevents the browser from remembering the
  3668. // value when navigating through history, so we re-enable autocomplete
  3669. // if the page is unloaded before the widget is destroyed. #7790
  3670. this._on( this.window, {
  3671. beforeunload: function() {
  3672. this.element.removeAttr( "autocomplete" );
  3673. }
  3674. });
  3675. },
  3676. _getCreateOptions: function() {
  3677. var options = {},
  3678. element = this.element;
  3679. $.each( [ "min", "max", "step" ], function( i, option ) {
  3680. var value = element.attr( option );
  3681. if ( value !== undefined && value.length ) {
  3682. options[ option ] = value;
  3683. }
  3684. });
  3685. return options;
  3686. },
  3687. _events: {
  3688. keydown: function( event ) {
  3689. if ( this._start( event ) && this._keydown( event ) ) {
  3690. event.preventDefault();
  3691. }
  3692. },
  3693. keyup: "_stop",
  3694. focus: function() {
  3695. this.previous = this.element.val();
  3696. },
  3697. blur: function( event ) {
  3698. if ( this.cancelBlur ) {
  3699. delete this.cancelBlur;
  3700. return;
  3701. }
  3702. this._stop();
  3703. this._refresh();
  3704. if ( this.previous !== this.element.val() ) {
  3705. this._trigger( "change", event );
  3706. }
  3707. },
  3708. mousewheel: function( event, delta ) {
  3709. if ( !delta ) {
  3710. return;
  3711. }
  3712. if ( !this.spinning && !this._start( event ) ) {
  3713. return false;
  3714. }
  3715. this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
  3716. clearTimeout( this.mousewheelTimer );
  3717. this.mousewheelTimer = this._delay(function() {
  3718. if ( this.spinning ) {
  3719. this._stop( event );
  3720. }
  3721. }, 100 );
  3722. event.preventDefault();
  3723. },
  3724. "mousedown .ui-spinner-button": function( event ) {
  3725. var previous;
  3726. // We never want the buttons to have focus; whenever the user is
  3727. // interacting with the spinner, the focus should be on the input.
  3728. // If the input is focused then this.previous is properly set from
  3729. // when the input first received focus. If the input is not focused
  3730. // then we need to set this.previous based on the value before spinning.
  3731. previous = this.element[0] === this.document[0].activeElement ?
  3732. this.previous : this.element.val();
  3733. function checkFocus() {
  3734. var isActive = this.element[0] === this.document[0].activeElement;
  3735. if ( !isActive ) {
  3736. this.element.focus();
  3737. this.previous = previous;
  3738. // support: IE
  3739. // IE sets focus asynchronously, so we need to check if focus
  3740. // moved off of the input because the user clicked on the button.
  3741. this._delay(function() {
  3742. this.previous = previous;
  3743. });
  3744. }
  3745. }
  3746. // ensure focus is on (or stays on) the text field
  3747. event.preventDefault();
  3748. checkFocus.call( this );
  3749. // support: IE
  3750. // IE doesn't prevent moving focus even with event.preventDefault()
  3751. // so we set a flag to know when we should ignore the blur event
  3752. // and check (again) if focus moved off of the input.
  3753. this.cancelBlur = true;
  3754. this._delay(function() {
  3755. delete this.cancelBlur;
  3756. checkFocus.call( this );
  3757. });
  3758. if ( this._start( event ) === false ) {
  3759. return;
  3760. }
  3761. this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
  3762. },
  3763. "mouseup .ui-spinner-button": "_stop",
  3764. "mouseenter .ui-spinner-button": function( event ) {
  3765. // button will add ui-state-active if mouse was down while mouseleave and kept down
  3766. if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
  3767. return;
  3768. }
  3769. if ( this._start( event ) === false ) {
  3770. return false;
  3771. }
  3772. this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
  3773. },
  3774. // TODO: do we really want to consider this a stop?
  3775. // shouldn't we just stop the repeater and wait until mouseup before
  3776. // we trigger the stop event?
  3777. "mouseleave .ui-spinner-button": "_stop"
  3778. },
  3779. _draw: function() {
  3780. var uiSpinner = this.uiSpinner = this.element
  3781. .addClass( "ui-spinner-input" )
  3782. .attr( "autocomplete", "off" )
  3783. .wrap( this._uiSpinnerHtml() )
  3784. .parent()
  3785. // add buttons
  3786. .append( this._buttonHtml() );
  3787. this.element.attr( "role", "spinbutton" );
  3788. // button bindings
  3789. this.buttons = uiSpinner.find( ".ui-spinner-button" )
  3790. .attr( "tabIndex", -1 )
  3791. .button()
  3792. .removeClass( "ui-corner-all" );
  3793. // IE 6 doesn't understand height: 50% for the buttons
  3794. // unless the wrapper has an explicit height
  3795. if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
  3796. uiSpinner.height() > 0 ) {
  3797. uiSpinner.height( uiSpinner.height() );
  3798. }
  3799. // disable spinner if element was already disabled
  3800. if ( this.options.disabled ) {
  3801. this.disable();
  3802. }
  3803. },
  3804. _keydown: function( event ) {
  3805. var options = this.options,
  3806. keyCode = $.ui.keyCode;
  3807. switch ( event.keyCode ) {
  3808. case keyCode.UP:
  3809. this._repeat( null, 1, event );
  3810. return true;
  3811. case keyCode.DOWN:
  3812. this._repeat( null, -1, event );
  3813. return true;
  3814. case keyCode.PAGE_UP:
  3815. this._repeat( null, options.page, event );
  3816. return true;
  3817. case keyCode.PAGE_DOWN:
  3818. this._repeat( null, -options.page, event );
  3819. return true;
  3820. }
  3821. return false;
  3822. },
  3823. _uiSpinnerHtml: function() {
  3824. return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
  3825. },
  3826. _buttonHtml: function() {
  3827. return "" +
  3828. "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
  3829. "<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
  3830. "</a>" +
  3831. "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
  3832. "<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
  3833. "</a>";
  3834. },
  3835. _start: function( event ) {
  3836. if ( !this.spinning && this._trigger( "start", event ) === false ) {
  3837. return false;
  3838. }
  3839. if ( !this.counter ) {
  3840. this.counter = 1;
  3841. }
  3842. this.spinning = true;
  3843. return true;
  3844. },
  3845. _repeat: function( i, steps, event ) {
  3846. i = i || 500;
  3847. clearTimeout( this.timer );
  3848. this.timer = this._delay(function() {
  3849. this._repeat( 40, steps, event );
  3850. }, i );
  3851. this._spin( steps * this.options.step, event );
  3852. },
  3853. _spin: function( step, event ) {
  3854. var value = this.value() || 0;
  3855. if ( !this.counter ) {
  3856. this.counter = 1;
  3857. }
  3858. value = this._adjustValue( value + step * this._increment( this.counter ) );
  3859. if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
  3860. this._value( value );
  3861. this.counter++;
  3862. }
  3863. },
  3864. _increment: function( i ) {
  3865. var incremental = this.options.incremental;
  3866. if ( incremental ) {
  3867. return $.isFunction( incremental ) ?
  3868. incremental( i ) :
  3869. Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );
  3870. }
  3871. return 1;
  3872. },
  3873. _precision: function() {
  3874. var precision = this._precisionOf( this.options.step );
  3875. if ( this.options.min !== null ) {
  3876. precision = Math.max( precision, this._precisionOf( this.options.min ) );
  3877. }
  3878. return precision;
  3879. },
  3880. _precisionOf: function( num ) {
  3881. var str = num.toString(),
  3882. decimal = str.indexOf( "." );
  3883. return decimal === -1 ? 0 : str.length - decimal - 1;
  3884. },
  3885. _adjustValue: function( value ) {
  3886. var base, aboveMin,
  3887. options = this.options;
  3888. // make sure we're at a valid step
  3889. // - find out where we are relative to the base (min or 0)
  3890. base = options.min !== null ? options.min : 0;
  3891. aboveMin = value - base;
  3892. // - round to the nearest step
  3893. aboveMin = Math.round(aboveMin / options.step) * options.step;
  3894. // - rounding is based on 0, so adjust back to our base
  3895. value = base + aboveMin;
  3896. // fix precision from bad JS floating point math
  3897. value = parseFloat( value.toFixed( this._precision() ) );
  3898. // clamp the value
  3899. if ( options.max !== null && value > options.max) {
  3900. return options.max;
  3901. }
  3902. if ( options.min !== null && value < options.min ) {
  3903. return options.min;
  3904. }
  3905. return value;
  3906. },
  3907. _stop: function( event ) {
  3908. if ( !this.spinning ) {
  3909. return;
  3910. }
  3911. clearTimeout( this.timer );
  3912. clearTimeout( this.mousewheelTimer );
  3913. this.counter = 0;
  3914. this.spinning = false;
  3915. this._trigger( "stop", event );
  3916. },
  3917. _setOption: function( key, value ) {
  3918. if ( key === "culture" || key === "numberFormat" ) {
  3919. var prevValue = this._parse( this.element.val() );
  3920. this.options[ key ] = value;
  3921. this.element.val( this._format( prevValue ) );
  3922. return;
  3923. }
  3924. if ( key === "max" || key === "min" || key === "step" ) {
  3925. if ( typeof value === "string" ) {
  3926. value = this._parse( value );
  3927. }
  3928. }
  3929. if ( key === "icons" ) {
  3930. this.buttons.first().find( ".ui-icon" )
  3931. .removeClass( this.options.icons.up )
  3932. .addClass( value.up );
  3933. this.buttons.last().find( ".ui-icon" )
  3934. .removeClass( this.options.icons.down )
  3935. .addClass( value.down );
  3936. }
  3937. this._super( key, value );
  3938. if ( key === "disabled" ) {
  3939. if ( value ) {
  3940. this.element.prop( "disabled", true );
  3941. this.buttons.button( "disable" );
  3942. } else {
  3943. this.element.prop( "disabled", false );
  3944. this.buttons.button( "enable" );
  3945. }
  3946. }
  3947. },
  3948. _setOptions: modifier(function( options ) {
  3949. this._super( options );
  3950. this._value( this.element.val() );
  3951. }),
  3952. _parse: function( val ) {
  3953. if ( typeof val === "string" && val !== "" ) {
  3954. val = window.Globalize && this.options.numberFormat ?
  3955. Globalize.parseFloat( val, 10, this.options.culture ) : +val;
  3956. }
  3957. return val === "" || isNaN( val ) ? null : val;
  3958. },
  3959. _format: function( value ) {
  3960. if ( value === "" ) {
  3961. return "";
  3962. }
  3963. return window.Globalize && this.options.numberFormat ?
  3964. Globalize.format( value, this.options.numberFormat, this.options.culture ) :
  3965. value;
  3966. },
  3967. _refresh: function() {
  3968. this.element.attr({
  3969. "aria-valuemin": this.options.min,
  3970. "aria-valuemax": this.options.max,
  3971. // TODO: what should we do with values that can't be parsed?
  3972. "aria-valuenow": this._parse( this.element.val() )
  3973. });
  3974. },
  3975. // update the value without triggering change
  3976. _value: function( value, allowAny ) {
  3977. var parsed;
  3978. if ( value !== "" ) {
  3979. parsed = this._parse( value );
  3980. if ( parsed !== null ) {
  3981. if ( !allowAny ) {
  3982. parsed = this._adjustValue( parsed );
  3983. }
  3984. value = this._format( parsed );
  3985. }
  3986. }
  3987. this.element.val( value );
  3988. this._refresh();
  3989. },
  3990. _destroy: function() {
  3991. this.element
  3992. .removeClass( "ui-spinner-input" )
  3993. .prop( "disabled", false )
  3994. .removeAttr( "autocomplete" )
  3995. .removeAttr( "role" )
  3996. .removeAttr( "aria-valuemin" )
  3997. .removeAttr( "aria-valuemax" )
  3998. .removeAttr( "aria-valuenow" );
  3999. this.uiSpinner.replaceWith( this.element );
  4000. },
  4001. stepUp: modifier(function( steps ) {
  4002. this._stepUp( steps );
  4003. }),
  4004. _stepUp: function( steps ) {
  4005. if ( this._start() ) {
  4006. this._spin( (steps || 1) * this.options.step );
  4007. this._stop();
  4008. }
  4009. },
  4010. stepDown: modifier(function( steps ) {
  4011. this._stepDown( steps );
  4012. }),
  4013. _stepDown: function( steps ) {
  4014. if ( this._start() ) {
  4015. this._spin( (steps || 1) * -this.options.step );
  4016. this._stop();
  4017. }
  4018. },
  4019. pageUp: modifier(function( pages ) {
  4020. this._stepUp( (pages || 1) * this.options.page );
  4021. }),
  4022. pageDown: modifier(function( pages ) {
  4023. this._stepDown( (pages || 1) * this.options.page );
  4024. }),
  4025. value: function( newVal ) {
  4026. if ( !arguments.length ) {
  4027. return this._parse( this.element.val() );
  4028. }
  4029. modifier( this._value ).call( this, newVal );
  4030. },
  4031. widget: function() {
  4032. return this.uiSpinner;
  4033. }
  4034. });
  4035. }( jQuery ) );