jquery-ui-1.10.4.custom.js 176 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059
  1. /*! jQuery UI - v1.10.4 - 2014-07-22
  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.sortable.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. function isOverAxis( x, reference, size ) {
  2710. return ( x > reference ) && ( x < ( reference + size ) );
  2711. }
  2712. function isFloating(item) {
  2713. return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
  2714. }
  2715. $.widget("ui.sortable", $.ui.mouse, {
  2716. version: "1.10.4",
  2717. widgetEventPrefix: "sort",
  2718. ready: false,
  2719. options: {
  2720. appendTo: "parent",
  2721. axis: false,
  2722. connectWith: false,
  2723. containment: false,
  2724. cursor: "auto",
  2725. cursorAt: false,
  2726. dropOnEmpty: true,
  2727. forcePlaceholderSize: false,
  2728. forceHelperSize: false,
  2729. grid: false,
  2730. handle: false,
  2731. helper: "original",
  2732. items: "> *",
  2733. opacity: false,
  2734. placeholder: false,
  2735. revert: false,
  2736. scroll: true,
  2737. scrollSensitivity: 20,
  2738. scrollSpeed: 20,
  2739. scope: "default",
  2740. tolerance: "intersect",
  2741. zIndex: 1000,
  2742. // callbacks
  2743. activate: null,
  2744. beforeStop: null,
  2745. change: null,
  2746. deactivate: null,
  2747. out: null,
  2748. over: null,
  2749. receive: null,
  2750. remove: null,
  2751. sort: null,
  2752. start: null,
  2753. stop: null,
  2754. update: null
  2755. },
  2756. _create: function() {
  2757. var o = this.options;
  2758. this.containerCache = {};
  2759. this.element.addClass("ui-sortable");
  2760. //Get the items
  2761. this.refresh();
  2762. //Let's determine if the items are being displayed horizontally
  2763. this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false;
  2764. //Let's determine the parent's offset
  2765. this.offset = this.element.offset();
  2766. //Initialize mouse events for interaction
  2767. this._mouseInit();
  2768. //We're ready to go
  2769. this.ready = true;
  2770. },
  2771. _destroy: function() {
  2772. this.element
  2773. .removeClass("ui-sortable ui-sortable-disabled");
  2774. this._mouseDestroy();
  2775. for ( var i = this.items.length - 1; i >= 0; i-- ) {
  2776. this.items[i].item.removeData(this.widgetName + "-item");
  2777. }
  2778. return this;
  2779. },
  2780. _setOption: function(key, value){
  2781. if ( key === "disabled" ) {
  2782. this.options[ key ] = value;
  2783. this.widget().toggleClass( "ui-sortable-disabled", !!value );
  2784. } else {
  2785. // Don't call widget base _setOption for disable as it adds ui-state-disabled class
  2786. $.Widget.prototype._setOption.apply(this, arguments);
  2787. }
  2788. },
  2789. _mouseCapture: function(event, overrideHandle) {
  2790. var currentItem = null,
  2791. validHandle = false,
  2792. that = this;
  2793. if (this.reverting) {
  2794. return false;
  2795. }
  2796. if(this.options.disabled || this.options.type === "static") {
  2797. return false;
  2798. }
  2799. //We have to refresh the items data once first
  2800. this._refreshItems(event);
  2801. //Find out if the clicked node (or one of its parents) is a actual item in this.items
  2802. $(event.target).parents().each(function() {
  2803. if($.data(this, that.widgetName + "-item") === that) {
  2804. currentItem = $(this);
  2805. return false;
  2806. }
  2807. });
  2808. if($.data(event.target, that.widgetName + "-item") === that) {
  2809. currentItem = $(event.target);
  2810. }
  2811. if(!currentItem) {
  2812. return false;
  2813. }
  2814. if(this.options.handle && !overrideHandle) {
  2815. $(this.options.handle, currentItem).find("*").addBack().each(function() {
  2816. if(this === event.target) {
  2817. validHandle = true;
  2818. }
  2819. });
  2820. if(!validHandle) {
  2821. return false;
  2822. }
  2823. }
  2824. this.currentItem = currentItem;
  2825. this._removeCurrentsFromItems();
  2826. return true;
  2827. },
  2828. _mouseStart: function(event, overrideHandle, noActivation) {
  2829. var i, body,
  2830. o = this.options;
  2831. this.currentContainer = this;
  2832. //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
  2833. this.refreshPositions();
  2834. //Create and append the visible helper
  2835. this.helper = this._createHelper(event);
  2836. //Cache the helper size
  2837. this._cacheHelperProportions();
  2838. /*
  2839. * - Position generation -
  2840. * This block generates everything position related - it's the core of draggables.
  2841. */
  2842. //Cache the margins of the original element
  2843. this._cacheMargins();
  2844. //Get the next scrolling parent
  2845. this.scrollParent = this.helper.scrollParent();
  2846. //The element's absolute position on the page minus margins
  2847. this.offset = this.currentItem.offset();
  2848. this.offset = {
  2849. top: this.offset.top - this.margins.top,
  2850. left: this.offset.left - this.margins.left
  2851. };
  2852. $.extend(this.offset, {
  2853. click: { //Where the click happened, relative to the element
  2854. left: event.pageX - this.offset.left,
  2855. top: event.pageY - this.offset.top
  2856. },
  2857. parent: this._getParentOffset(),
  2858. relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
  2859. });
  2860. // Only after we got the offset, we can change the helper's position to absolute
  2861. // TODO: Still need to figure out a way to make relative sorting possible
  2862. this.helper.css("position", "absolute");
  2863. this.cssPosition = this.helper.css("position");
  2864. //Generate the original position
  2865. this.originalPosition = this._generatePosition(event);
  2866. this.originalPageX = event.pageX;
  2867. this.originalPageY = event.pageY;
  2868. //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
  2869. (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
  2870. //Cache the former DOM position
  2871. this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
  2872. //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
  2873. if(this.helper[0] !== this.currentItem[0]) {
  2874. this.currentItem.hide();
  2875. }
  2876. //Create the placeholder
  2877. this._createPlaceholder();
  2878. //Set a containment if given in the options
  2879. if(o.containment) {
  2880. this._setContainment();
  2881. }
  2882. if( o.cursor && o.cursor !== "auto" ) { // cursor option
  2883. body = this.document.find( "body" );
  2884. // support: IE
  2885. this.storedCursor = body.css( "cursor" );
  2886. body.css( "cursor", o.cursor );
  2887. this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
  2888. }
  2889. if(o.opacity) { // opacity option
  2890. if (this.helper.css("opacity")) {
  2891. this._storedOpacity = this.helper.css("opacity");
  2892. }
  2893. this.helper.css("opacity", o.opacity);
  2894. }
  2895. if(o.zIndex) { // zIndex option
  2896. if (this.helper.css("zIndex")) {
  2897. this._storedZIndex = this.helper.css("zIndex");
  2898. }
  2899. this.helper.css("zIndex", o.zIndex);
  2900. }
  2901. //Prepare scrolling
  2902. if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
  2903. this.overflowOffset = this.scrollParent.offset();
  2904. }
  2905. //Call callbacks
  2906. this._trigger("start", event, this._uiHash());
  2907. //Recache the helper size
  2908. if(!this._preserveHelperProportions) {
  2909. this._cacheHelperProportions();
  2910. }
  2911. //Post "activate" events to possible containers
  2912. if( !noActivation ) {
  2913. for ( i = this.containers.length - 1; i >= 0; i-- ) {
  2914. this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
  2915. }
  2916. }
  2917. //Prepare possible droppables
  2918. if($.ui.ddmanager) {
  2919. $.ui.ddmanager.current = this;
  2920. }
  2921. if ($.ui.ddmanager && !o.dropBehaviour) {
  2922. $.ui.ddmanager.prepareOffsets(this, event);
  2923. }
  2924. this.dragging = true;
  2925. this.helper.addClass("ui-sortable-helper");
  2926. this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
  2927. return true;
  2928. },
  2929. _mouseDrag: function(event) {
  2930. var i, item, itemElement, intersection,
  2931. o = this.options,
  2932. scrolled = false;
  2933. //Compute the helpers position
  2934. this.position = this._generatePosition(event);
  2935. this.positionAbs = this._convertPositionTo("absolute");
  2936. if (!this.lastPositionAbs) {
  2937. this.lastPositionAbs = this.positionAbs;
  2938. }
  2939. //Do scrolling
  2940. if(this.options.scroll) {
  2941. if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
  2942. if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
  2943. this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
  2944. } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
  2945. this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
  2946. }
  2947. if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
  2948. this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
  2949. } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
  2950. this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
  2951. }
  2952. } else {
  2953. if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
  2954. scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
  2955. } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
  2956. scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
  2957. }
  2958. if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
  2959. scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
  2960. } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
  2961. scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
  2962. }
  2963. }
  2964. if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
  2965. $.ui.ddmanager.prepareOffsets(this, event);
  2966. }
  2967. }
  2968. //Regenerate the absolute position used for position checks
  2969. this.positionAbs = this._convertPositionTo("absolute");
  2970. //Set the helper position
  2971. if(!this.options.axis || this.options.axis !== "y") {
  2972. this.helper[0].style.left = this.position.left+"px";
  2973. }
  2974. if(!this.options.axis || this.options.axis !== "x") {
  2975. this.helper[0].style.top = this.position.top+"px";
  2976. }
  2977. //Rearrange
  2978. for (i = this.items.length - 1; i >= 0; i--) {
  2979. //Cache variables and intersection, continue if no intersection
  2980. item = this.items[i];
  2981. itemElement = item.item[0];
  2982. intersection = this._intersectsWithPointer(item);
  2983. if (!intersection) {
  2984. continue;
  2985. }
  2986. // Only put the placeholder inside the current Container, skip all
  2987. // items from other containers. This works because when moving
  2988. // an item from one container to another the
  2989. // currentContainer is switched before the placeholder is moved.
  2990. //
  2991. // Without this, moving items in "sub-sortables" can cause
  2992. // the placeholder to jitter beetween the outer and inner container.
  2993. if (item.instance !== this.currentContainer) {
  2994. continue;
  2995. }
  2996. // cannot intersect with itself
  2997. // no useless actions that have been done before
  2998. // no action if the item moved is the parent of the item checked
  2999. if (itemElement !== this.currentItem[0] &&
  3000. this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
  3001. !$.contains(this.placeholder[0], itemElement) &&
  3002. (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
  3003. ) {
  3004. this.direction = intersection === 1 ? "down" : "up";
  3005. if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
  3006. this._rearrange(event, item);
  3007. } else {
  3008. break;
  3009. }
  3010. this._trigger("change", event, this._uiHash());
  3011. break;
  3012. }
  3013. }
  3014. //Post events to containers
  3015. this._contactContainers(event);
  3016. //Interconnect with droppables
  3017. if($.ui.ddmanager) {
  3018. $.ui.ddmanager.drag(this, event);
  3019. }
  3020. //Call callbacks
  3021. this._trigger("sort", event, this._uiHash());
  3022. this.lastPositionAbs = this.positionAbs;
  3023. return false;
  3024. },
  3025. _mouseStop: function(event, noPropagation) {
  3026. if(!event) {
  3027. return;
  3028. }
  3029. //If we are using droppables, inform the manager about the drop
  3030. if ($.ui.ddmanager && !this.options.dropBehaviour) {
  3031. $.ui.ddmanager.drop(this, event);
  3032. }
  3033. if(this.options.revert) {
  3034. var that = this,
  3035. cur = this.placeholder.offset(),
  3036. axis = this.options.axis,
  3037. animation = {};
  3038. if ( !axis || axis === "x" ) {
  3039. animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft);
  3040. }
  3041. if ( !axis || axis === "y" ) {
  3042. animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop);
  3043. }
  3044. this.reverting = true;
  3045. $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
  3046. that._clear(event);
  3047. });
  3048. } else {
  3049. this._clear(event, noPropagation);
  3050. }
  3051. return false;
  3052. },
  3053. cancel: function() {
  3054. if(this.dragging) {
  3055. this._mouseUp({ target: null });
  3056. if(this.options.helper === "original") {
  3057. this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
  3058. } else {
  3059. this.currentItem.show();
  3060. }
  3061. //Post deactivating events to containers
  3062. for (var i = this.containers.length - 1; i >= 0; i--){
  3063. this.containers[i]._trigger("deactivate", null, this._uiHash(this));
  3064. if(this.containers[i].containerCache.over) {
  3065. this.containers[i]._trigger("out", null, this._uiHash(this));
  3066. this.containers[i].containerCache.over = 0;
  3067. }
  3068. }
  3069. }
  3070. if (this.placeholder) {
  3071. //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
  3072. if(this.placeholder[0].parentNode) {
  3073. this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
  3074. }
  3075. if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
  3076. this.helper.remove();
  3077. }
  3078. $.extend(this, {
  3079. helper: null,
  3080. dragging: false,
  3081. reverting: false,
  3082. _noFinalSort: null
  3083. });
  3084. if(this.domPosition.prev) {
  3085. $(this.domPosition.prev).after(this.currentItem);
  3086. } else {
  3087. $(this.domPosition.parent).prepend(this.currentItem);
  3088. }
  3089. }
  3090. return this;
  3091. },
  3092. serialize: function(o) {
  3093. var items = this._getItemsAsjQuery(o && o.connected),
  3094. str = [];
  3095. o = o || {};
  3096. $(items).each(function() {
  3097. var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
  3098. if (res) {
  3099. str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
  3100. }
  3101. });
  3102. if(!str.length && o.key) {
  3103. str.push(o.key + "=");
  3104. }
  3105. return str.join("&");
  3106. },
  3107. toArray: function(o) {
  3108. var items = this._getItemsAsjQuery(o && o.connected),
  3109. ret = [];
  3110. o = o || {};
  3111. items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
  3112. return ret;
  3113. },
  3114. /* Be careful with the following core functions */
  3115. _intersectsWith: function(item) {
  3116. var x1 = this.positionAbs.left,
  3117. x2 = x1 + this.helperProportions.width,
  3118. y1 = this.positionAbs.top,
  3119. y2 = y1 + this.helperProportions.height,
  3120. l = item.left,
  3121. r = l + item.width,
  3122. t = item.top,
  3123. b = t + item.height,
  3124. dyClick = this.offset.click.top,
  3125. dxClick = this.offset.click.left,
  3126. isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
  3127. isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
  3128. isOverElement = isOverElementHeight && isOverElementWidth;
  3129. if ( this.options.tolerance === "pointer" ||
  3130. this.options.forcePointerForContainers ||
  3131. (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
  3132. ) {
  3133. return isOverElement;
  3134. } else {
  3135. return (l < x1 + (this.helperProportions.width / 2) && // Right Half
  3136. x2 - (this.helperProportions.width / 2) < r && // Left Half
  3137. t < y1 + (this.helperProportions.height / 2) && // Bottom Half
  3138. y2 - (this.helperProportions.height / 2) < b ); // Top Half
  3139. }
  3140. },
  3141. _intersectsWithPointer: function(item) {
  3142. var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
  3143. isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
  3144. isOverElement = isOverElementHeight && isOverElementWidth,
  3145. verticalDirection = this._getDragVerticalDirection(),
  3146. horizontalDirection = this._getDragHorizontalDirection();
  3147. if (!isOverElement) {
  3148. return false;
  3149. }
  3150. return this.floating ?
  3151. ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
  3152. : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
  3153. },
  3154. _intersectsWithSides: function(item) {
  3155. var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
  3156. isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
  3157. verticalDirection = this._getDragVerticalDirection(),
  3158. horizontalDirection = this._getDragHorizontalDirection();
  3159. if (this.floating && horizontalDirection) {
  3160. return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
  3161. } else {
  3162. return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
  3163. }
  3164. },
  3165. _getDragVerticalDirection: function() {
  3166. var delta = this.positionAbs.top - this.lastPositionAbs.top;
  3167. return delta !== 0 && (delta > 0 ? "down" : "up");
  3168. },
  3169. _getDragHorizontalDirection: function() {
  3170. var delta = this.positionAbs.left - this.lastPositionAbs.left;
  3171. return delta !== 0 && (delta > 0 ? "right" : "left");
  3172. },
  3173. refresh: function(event) {
  3174. this._refreshItems(event);
  3175. this.refreshPositions();
  3176. return this;
  3177. },
  3178. _connectWith: function() {
  3179. var options = this.options;
  3180. return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
  3181. },
  3182. _getItemsAsjQuery: function(connected) {
  3183. var i, j, cur, inst,
  3184. items = [],
  3185. queries = [],
  3186. connectWith = this._connectWith();
  3187. if(connectWith && connected) {
  3188. for (i = connectWith.length - 1; i >= 0; i--){
  3189. cur = $(connectWith[i]);
  3190. for ( j = cur.length - 1; j >= 0; j--){
  3191. inst = $.data(cur[j], this.widgetFullName);
  3192. if(inst && inst !== this && !inst.options.disabled) {
  3193. queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]);
  3194. }
  3195. }
  3196. }
  3197. }
  3198. queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), this]);
  3199. function addItems() {
  3200. items.push( this );
  3201. }
  3202. for (i = queries.length - 1; i >= 0; i--){
  3203. queries[i][0].each( addItems );
  3204. }
  3205. return $(items);
  3206. },
  3207. _removeCurrentsFromItems: function() {
  3208. var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
  3209. this.items = $.grep(this.items, function (item) {
  3210. for (var j=0; j < list.length; j++) {
  3211. if(list[j] === item.item[0]) {
  3212. return false;
  3213. }
  3214. }
  3215. return true;
  3216. });
  3217. },
  3218. _refreshItems: function(event) {
  3219. this.items = [];
  3220. this.containers = [this];
  3221. var i, j, cur, inst, targetData, _queries, item, queriesLength,
  3222. items = this.items,
  3223. queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
  3224. connectWith = this._connectWith();
  3225. if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
  3226. for (i = connectWith.length - 1; i >= 0; i--){
  3227. cur = $(connectWith[i]);
  3228. for (j = cur.length - 1; j >= 0; j--){
  3229. inst = $.data(cur[j], this.widgetFullName);
  3230. if(inst && inst !== this && !inst.options.disabled) {
  3231. queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
  3232. this.containers.push(inst);
  3233. }
  3234. }
  3235. }
  3236. }
  3237. for (i = queries.length - 1; i >= 0; i--) {
  3238. targetData = queries[i][1];
  3239. _queries = queries[i][0];
  3240. for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
  3241. item = $(_queries[j]);
  3242. item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
  3243. items.push({
  3244. item: item,
  3245. instance: targetData,
  3246. width: 0, height: 0,
  3247. left: 0, top: 0
  3248. });
  3249. }
  3250. }
  3251. },
  3252. refreshPositions: function(fast) {
  3253. //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
  3254. if(this.offsetParent && this.helper) {
  3255. this.offset.parent = this._getParentOffset();
  3256. }
  3257. var i, item, t, p;
  3258. for (i = this.items.length - 1; i >= 0; i--){
  3259. item = this.items[i];
  3260. //We ignore calculating positions of all connected containers when we're not over them
  3261. if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
  3262. continue;
  3263. }
  3264. t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
  3265. if (!fast) {
  3266. item.width = t.outerWidth();
  3267. item.height = t.outerHeight();
  3268. }
  3269. p = t.offset();
  3270. item.left = p.left;
  3271. item.top = p.top;
  3272. }
  3273. if(this.options.custom && this.options.custom.refreshContainers) {
  3274. this.options.custom.refreshContainers.call(this);
  3275. } else {
  3276. for (i = this.containers.length - 1; i >= 0; i--){
  3277. p = this.containers[i].element.offset();
  3278. this.containers[i].containerCache.left = p.left;
  3279. this.containers[i].containerCache.top = p.top;
  3280. this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
  3281. this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
  3282. }
  3283. }
  3284. return this;
  3285. },
  3286. _createPlaceholder: function(that) {
  3287. that = that || this;
  3288. var className,
  3289. o = that.options;
  3290. if(!o.placeholder || o.placeholder.constructor === String) {
  3291. className = o.placeholder;
  3292. o.placeholder = {
  3293. element: function() {
  3294. var nodeName = that.currentItem[0].nodeName.toLowerCase(),
  3295. element = $( "<" + nodeName + ">", that.document[0] )
  3296. .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
  3297. .removeClass("ui-sortable-helper");
  3298. if ( nodeName === "tr" ) {
  3299. that.currentItem.children().each(function() {
  3300. $( "<td>&#160;</td>", that.document[0] )
  3301. .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
  3302. .appendTo( element );
  3303. });
  3304. } else if ( nodeName === "img" ) {
  3305. element.attr( "src", that.currentItem.attr( "src" ) );
  3306. }
  3307. if ( !className ) {
  3308. element.css( "visibility", "hidden" );
  3309. }
  3310. return element;
  3311. },
  3312. update: function(container, p) {
  3313. // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
  3314. // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
  3315. if(className && !o.forcePlaceholderSize) {
  3316. return;
  3317. }
  3318. //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
  3319. if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
  3320. if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
  3321. }
  3322. };
  3323. }
  3324. //Create the placeholder
  3325. that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
  3326. //Append it after the actual current item
  3327. that.currentItem.after(that.placeholder);
  3328. //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
  3329. o.placeholder.update(that, that.placeholder);
  3330. },
  3331. _contactContainers: function(event) {
  3332. var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating,
  3333. innermostContainer = null,
  3334. innermostIndex = null;
  3335. // get innermost container that intersects with item
  3336. for (i = this.containers.length - 1; i >= 0; i--) {
  3337. // never consider a container that's located within the item itself
  3338. if($.contains(this.currentItem[0], this.containers[i].element[0])) {
  3339. continue;
  3340. }
  3341. if(this._intersectsWith(this.containers[i].containerCache)) {
  3342. // if we've already found a container and it's more "inner" than this, then continue
  3343. if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
  3344. continue;
  3345. }
  3346. innermostContainer = this.containers[i];
  3347. innermostIndex = i;
  3348. } else {
  3349. // container doesn't intersect. trigger "out" event if necessary
  3350. if(this.containers[i].containerCache.over) {
  3351. this.containers[i]._trigger("out", event, this._uiHash(this));
  3352. this.containers[i].containerCache.over = 0;
  3353. }
  3354. }
  3355. }
  3356. // if no intersecting containers found, return
  3357. if(!innermostContainer) {
  3358. return;
  3359. }
  3360. // move the item into the container if it's not there already
  3361. if(this.containers.length === 1) {
  3362. if (!this.containers[innermostIndex].containerCache.over) {
  3363. this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
  3364. this.containers[innermostIndex].containerCache.over = 1;
  3365. }
  3366. } else {
  3367. //When entering a new container, we will find the item with the least distance and append our item near it
  3368. dist = 10000;
  3369. itemWithLeastDistance = null;
  3370. floating = innermostContainer.floating || isFloating(this.currentItem);
  3371. posProperty = floating ? "left" : "top";
  3372. sizeProperty = floating ? "width" : "height";
  3373. base = this.positionAbs[posProperty] + this.offset.click[posProperty];
  3374. for (j = this.items.length - 1; j >= 0; j--) {
  3375. if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
  3376. continue;
  3377. }
  3378. if(this.items[j].item[0] === this.currentItem[0]) {
  3379. continue;
  3380. }
  3381. if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) {
  3382. continue;
  3383. }
  3384. cur = this.items[j].item.offset()[posProperty];
  3385. nearBottom = false;
  3386. if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
  3387. nearBottom = true;
  3388. cur += this.items[j][sizeProperty];
  3389. }
  3390. if(Math.abs(cur - base) < dist) {
  3391. dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
  3392. this.direction = nearBottom ? "up": "down";
  3393. }
  3394. }
  3395. //Check if dropOnEmpty is enabled
  3396. if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
  3397. return;
  3398. }
  3399. if(this.currentContainer === this.containers[innermostIndex]) {
  3400. return;
  3401. }
  3402. itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
  3403. this._trigger("change", event, this._uiHash());
  3404. this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
  3405. this.currentContainer = this.containers[innermostIndex];
  3406. //Update the placeholder
  3407. this.options.placeholder.update(this.currentContainer, this.placeholder);
  3408. this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
  3409. this.containers[innermostIndex].containerCache.over = 1;
  3410. }
  3411. },
  3412. _createHelper: function(event) {
  3413. var o = this.options,
  3414. helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
  3415. //Add the helper to the DOM if that didn't happen already
  3416. if(!helper.parents("body").length) {
  3417. $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
  3418. }
  3419. if(helper[0] === this.currentItem[0]) {
  3420. this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
  3421. }
  3422. if(!helper[0].style.width || o.forceHelperSize) {
  3423. helper.width(this.currentItem.width());
  3424. }
  3425. if(!helper[0].style.height || o.forceHelperSize) {
  3426. helper.height(this.currentItem.height());
  3427. }
  3428. return helper;
  3429. },
  3430. _adjustOffsetFromHelper: function(obj) {
  3431. if (typeof obj === "string") {
  3432. obj = obj.split(" ");
  3433. }
  3434. if ($.isArray(obj)) {
  3435. obj = {left: +obj[0], top: +obj[1] || 0};
  3436. }
  3437. if ("left" in obj) {
  3438. this.offset.click.left = obj.left + this.margins.left;
  3439. }
  3440. if ("right" in obj) {
  3441. this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
  3442. }
  3443. if ("top" in obj) {
  3444. this.offset.click.top = obj.top + this.margins.top;
  3445. }
  3446. if ("bottom" in obj) {
  3447. this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
  3448. }
  3449. },
  3450. _getParentOffset: function() {
  3451. //Get the offsetParent and cache its position
  3452. this.offsetParent = this.helper.offsetParent();
  3453. var po = this.offsetParent.offset();
  3454. // This is a special case where we need to modify a offset calculated on start, since the following happened:
  3455. // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
  3456. // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
  3457. // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
  3458. if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
  3459. po.left += this.scrollParent.scrollLeft();
  3460. po.top += this.scrollParent.scrollTop();
  3461. }
  3462. // This needs to be actually done for all browsers, since pageX/pageY includes this information
  3463. // with an ugly IE fix
  3464. if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
  3465. po = { top: 0, left: 0 };
  3466. }
  3467. return {
  3468. top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
  3469. left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
  3470. };
  3471. },
  3472. _getRelativeOffset: function() {
  3473. if(this.cssPosition === "relative") {
  3474. var p = this.currentItem.position();
  3475. return {
  3476. top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
  3477. left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
  3478. };
  3479. } else {
  3480. return { top: 0, left: 0 };
  3481. }
  3482. },
  3483. _cacheMargins: function() {
  3484. this.margins = {
  3485. left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
  3486. top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
  3487. };
  3488. },
  3489. _cacheHelperProportions: function() {
  3490. this.helperProportions = {
  3491. width: this.helper.outerWidth(),
  3492. height: this.helper.outerHeight()
  3493. };
  3494. },
  3495. _setContainment: function() {
  3496. var ce, co, over,
  3497. o = this.options;
  3498. if(o.containment === "parent") {
  3499. o.containment = this.helper[0].parentNode;
  3500. }
  3501. if(o.containment === "document" || o.containment === "window") {
  3502. this.containment = [
  3503. 0 - this.offset.relative.left - this.offset.parent.left,
  3504. 0 - this.offset.relative.top - this.offset.parent.top,
  3505. $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
  3506. ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
  3507. ];
  3508. }
  3509. if(!(/^(document|window|parent)$/).test(o.containment)) {
  3510. ce = $(o.containment)[0];
  3511. co = $(o.containment).offset();
  3512. over = ($(ce).css("overflow") !== "hidden");
  3513. this.containment = [
  3514. co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
  3515. co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
  3516. co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
  3517. co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
  3518. ];
  3519. }
  3520. },
  3521. _convertPositionTo: function(d, pos) {
  3522. if(!pos) {
  3523. pos = this.position;
  3524. }
  3525. var mod = d === "absolute" ? 1 : -1,
  3526. scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
  3527. scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
  3528. return {
  3529. top: (
  3530. pos.top + // The absolute mouse position
  3531. this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
  3532. this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border)
  3533. ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
  3534. ),
  3535. left: (
  3536. pos.left + // The absolute mouse position
  3537. this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
  3538. this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border)
  3539. ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
  3540. )
  3541. };
  3542. },
  3543. _generatePosition: function(event) {
  3544. var top, left,
  3545. o = this.options,
  3546. pageX = event.pageX,
  3547. pageY = event.pageY,
  3548. scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
  3549. // This is another very weird special case that only happens for relative elements:
  3550. // 1. If the css position is relative
  3551. // 2. and the scroll parent is the document or similar to the offset parent
  3552. // we have to refresh the relative offset during the scroll so there are no jumps
  3553. if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) {
  3554. this.offset.relative = this._getRelativeOffset();
  3555. }
  3556. /*
  3557. * - Position constraining -
  3558. * Constrain the position to a mix of grid, containment.
  3559. */
  3560. if(this.originalPosition) { //If we are not dragging yet, we won't check for options
  3561. if(this.containment) {
  3562. if(event.pageX - this.offset.click.left < this.containment[0]) {
  3563. pageX = this.containment[0] + this.offset.click.left;
  3564. }
  3565. if(event.pageY - this.offset.click.top < this.containment[1]) {
  3566. pageY = this.containment[1] + this.offset.click.top;
  3567. }
  3568. if(event.pageX - this.offset.click.left > this.containment[2]) {
  3569. pageX = this.containment[2] + this.offset.click.left;
  3570. }
  3571. if(event.pageY - this.offset.click.top > this.containment[3]) {
  3572. pageY = this.containment[3] + this.offset.click.top;
  3573. }
  3574. }
  3575. if(o.grid) {
  3576. top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
  3577. pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
  3578. left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
  3579. pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
  3580. }
  3581. }
  3582. return {
  3583. top: (
  3584. pageY - // The absolute mouse position
  3585. this.offset.click.top - // Click offset (relative to the element)
  3586. this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent
  3587. this.offset.parent.top + // The offsetParent's offset without borders (offset + border)
  3588. ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
  3589. ),
  3590. left: (
  3591. pageX - // The absolute mouse position
  3592. this.offset.click.left - // Click offset (relative to the element)
  3593. this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent
  3594. this.offset.parent.left + // The offsetParent's offset without borders (offset + border)
  3595. ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
  3596. )
  3597. };
  3598. },
  3599. _rearrange: function(event, i, a, hardRefresh) {
  3600. a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === "down" ? i.item[0] : i.item[0].nextSibling));
  3601. //Various things done here to improve the performance:
  3602. // 1. we create a setTimeout, that calls refreshPositions
  3603. // 2. on the instance, we have a counter variable, that get's higher after every append
  3604. // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
  3605. // 4. this lets only the last addition to the timeout stack through
  3606. this.counter = this.counter ? ++this.counter : 1;
  3607. var counter = this.counter;
  3608. this._delay(function() {
  3609. if(counter === this.counter) {
  3610. this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
  3611. }
  3612. });
  3613. },
  3614. _clear: function(event, noPropagation) {
  3615. this.reverting = false;
  3616. // We delay all events that have to be triggered to after the point where the placeholder has been removed and
  3617. // everything else normalized again
  3618. var i,
  3619. delayedTriggers = [];
  3620. // We first have to update the dom position of the actual currentItem
  3621. // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
  3622. if(!this._noFinalSort && this.currentItem.parent().length) {
  3623. this.placeholder.before(this.currentItem);
  3624. }
  3625. this._noFinalSort = null;
  3626. if(this.helper[0] === this.currentItem[0]) {
  3627. for(i in this._storedCSS) {
  3628. if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
  3629. this._storedCSS[i] = "";
  3630. }
  3631. }
  3632. this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
  3633. } else {
  3634. this.currentItem.show();
  3635. }
  3636. if(this.fromOutside && !noPropagation) {
  3637. delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
  3638. }
  3639. if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
  3640. delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
  3641. }
  3642. // Check if the items Container has Changed and trigger appropriate
  3643. // events.
  3644. if (this !== this.currentContainer) {
  3645. if(!noPropagation) {
  3646. delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
  3647. delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
  3648. delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
  3649. }
  3650. }
  3651. //Post events to containers
  3652. function delayEvent( type, instance, container ) {
  3653. return function( event ) {
  3654. container._trigger( type, event, instance._uiHash( instance ) );
  3655. };
  3656. }
  3657. for (i = this.containers.length - 1; i >= 0; i--){
  3658. if (!noPropagation) {
  3659. delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
  3660. }
  3661. if(this.containers[i].containerCache.over) {
  3662. delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
  3663. this.containers[i].containerCache.over = 0;
  3664. }
  3665. }
  3666. //Do what was originally in plugins
  3667. if ( this.storedCursor ) {
  3668. this.document.find( "body" ).css( "cursor", this.storedCursor );
  3669. this.storedStylesheet.remove();
  3670. }
  3671. if(this._storedOpacity) {
  3672. this.helper.css("opacity", this._storedOpacity);
  3673. }
  3674. if(this._storedZIndex) {
  3675. this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
  3676. }
  3677. this.dragging = false;
  3678. if(this.cancelHelperRemoval) {
  3679. if(!noPropagation) {
  3680. this._trigger("beforeStop", event, this._uiHash());
  3681. for (i=0; i < delayedTriggers.length; i++) {
  3682. delayedTriggers[i].call(this, event);
  3683. } //Trigger all delayed events
  3684. this._trigger("stop", event, this._uiHash());
  3685. }
  3686. this.fromOutside = false;
  3687. return false;
  3688. }
  3689. if(!noPropagation) {
  3690. this._trigger("beforeStop", event, this._uiHash());
  3691. }
  3692. //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
  3693. this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
  3694. if(this.helper[0] !== this.currentItem[0]) {
  3695. this.helper.remove();
  3696. }
  3697. this.helper = null;
  3698. if(!noPropagation) {
  3699. for (i=0; i < delayedTriggers.length; i++) {
  3700. delayedTriggers[i].call(this, event);
  3701. } //Trigger all delayed events
  3702. this._trigger("stop", event, this._uiHash());
  3703. }
  3704. this.fromOutside = false;
  3705. return true;
  3706. },
  3707. _trigger: function() {
  3708. if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
  3709. this.cancel();
  3710. }
  3711. },
  3712. _uiHash: function(_inst) {
  3713. var inst = _inst || this;
  3714. return {
  3715. helper: inst.helper,
  3716. placeholder: inst.placeholder || $([]),
  3717. position: inst.position,
  3718. originalPosition: inst.originalPosition,
  3719. offset: inst.positionAbs,
  3720. item: inst.currentItem,
  3721. sender: _inst ? _inst.element : null
  3722. };
  3723. }
  3724. });
  3725. })(jQuery);
  3726. (function( $, undefined ) {
  3727. var lastActive,
  3728. baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
  3729. 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",
  3730. formResetHandler = function() {
  3731. var form = $( this );
  3732. setTimeout(function() {
  3733. form.find( ":ui-button" ).button( "refresh" );
  3734. }, 1 );
  3735. },
  3736. radioGroup = function( radio ) {
  3737. var name = radio.name,
  3738. form = radio.form,
  3739. radios = $( [] );
  3740. if ( name ) {
  3741. name = name.replace( /'/g, "\\'" );
  3742. if ( form ) {
  3743. radios = $( form ).find( "[name='" + name + "']" );
  3744. } else {
  3745. radios = $( "[name='" + name + "']", radio.ownerDocument )
  3746. .filter(function() {
  3747. return !this.form;
  3748. });
  3749. }
  3750. }
  3751. return radios;
  3752. };
  3753. $.widget( "ui.button", {
  3754. version: "1.10.4",
  3755. defaultElement: "<button>",
  3756. options: {
  3757. disabled: null,
  3758. text: true,
  3759. label: null,
  3760. icons: {
  3761. primary: null,
  3762. secondary: null
  3763. }
  3764. },
  3765. _create: function() {
  3766. this.element.closest( "form" )
  3767. .unbind( "reset" + this.eventNamespace )
  3768. .bind( "reset" + this.eventNamespace, formResetHandler );
  3769. if ( typeof this.options.disabled !== "boolean" ) {
  3770. this.options.disabled = !!this.element.prop( "disabled" );
  3771. } else {
  3772. this.element.prop( "disabled", this.options.disabled );
  3773. }
  3774. this._determineButtonType();
  3775. this.hasTitle = !!this.buttonElement.attr( "title" );
  3776. var that = this,
  3777. options = this.options,
  3778. toggleButton = this.type === "checkbox" || this.type === "radio",
  3779. activeClass = !toggleButton ? "ui-state-active" : "";
  3780. if ( options.label === null ) {
  3781. options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
  3782. }
  3783. this._hoverable( this.buttonElement );
  3784. this.buttonElement
  3785. .addClass( baseClasses )
  3786. .attr( "role", "button" )
  3787. .bind( "mouseenter" + this.eventNamespace, function() {
  3788. if ( options.disabled ) {
  3789. return;
  3790. }
  3791. if ( this === lastActive ) {
  3792. $( this ).addClass( "ui-state-active" );
  3793. }
  3794. })
  3795. .bind( "mouseleave" + this.eventNamespace, function() {
  3796. if ( options.disabled ) {
  3797. return;
  3798. }
  3799. $( this ).removeClass( activeClass );
  3800. })
  3801. .bind( "click" + this.eventNamespace, function( event ) {
  3802. if ( options.disabled ) {
  3803. event.preventDefault();
  3804. event.stopImmediatePropagation();
  3805. }
  3806. });
  3807. // Can't use _focusable() because the element that receives focus
  3808. // and the element that gets the ui-state-focus class are different
  3809. this._on({
  3810. focus: function() {
  3811. this.buttonElement.addClass( "ui-state-focus" );
  3812. },
  3813. blur: function() {
  3814. this.buttonElement.removeClass( "ui-state-focus" );
  3815. }
  3816. });
  3817. if ( toggleButton ) {
  3818. this.element.bind( "change" + this.eventNamespace, function() {
  3819. that.refresh();
  3820. });
  3821. }
  3822. if ( this.type === "checkbox" ) {
  3823. this.buttonElement.bind( "click" + this.eventNamespace, function() {
  3824. if ( options.disabled ) {
  3825. return false;
  3826. }
  3827. });
  3828. } else if ( this.type === "radio" ) {
  3829. this.buttonElement.bind( "click" + this.eventNamespace, function() {
  3830. if ( options.disabled ) {
  3831. return false;
  3832. }
  3833. $( this ).addClass( "ui-state-active" );
  3834. that.buttonElement.attr( "aria-pressed", "true" );
  3835. var radio = that.element[ 0 ];
  3836. radioGroup( radio )
  3837. .not( radio )
  3838. .map(function() {
  3839. return $( this ).button( "widget" )[ 0 ];
  3840. })
  3841. .removeClass( "ui-state-active" )
  3842. .attr( "aria-pressed", "false" );
  3843. });
  3844. } else {
  3845. this.buttonElement
  3846. .bind( "mousedown" + this.eventNamespace, function() {
  3847. if ( options.disabled ) {
  3848. return false;
  3849. }
  3850. $( this ).addClass( "ui-state-active" );
  3851. lastActive = this;
  3852. that.document.one( "mouseup", function() {
  3853. lastActive = null;
  3854. });
  3855. })
  3856. .bind( "mouseup" + this.eventNamespace, function() {
  3857. if ( options.disabled ) {
  3858. return false;
  3859. }
  3860. $( this ).removeClass( "ui-state-active" );
  3861. })
  3862. .bind( "keydown" + this.eventNamespace, function(event) {
  3863. if ( options.disabled ) {
  3864. return false;
  3865. }
  3866. if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
  3867. $( this ).addClass( "ui-state-active" );
  3868. }
  3869. })
  3870. // see #8559, we bind to blur here in case the button element loses
  3871. // focus between keydown and keyup, it would be left in an "active" state
  3872. .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
  3873. $( this ).removeClass( "ui-state-active" );
  3874. });
  3875. if ( this.buttonElement.is("a") ) {
  3876. this.buttonElement.keyup(function(event) {
  3877. if ( event.keyCode === $.ui.keyCode.SPACE ) {
  3878. // TODO pass through original event correctly (just as 2nd argument doesn't work)
  3879. $( this ).click();
  3880. }
  3881. });
  3882. }
  3883. }
  3884. // TODO: pull out $.Widget's handling for the disabled option into
  3885. // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
  3886. // be overridden by individual plugins
  3887. this._setOption( "disabled", options.disabled );
  3888. this._resetButton();
  3889. },
  3890. _determineButtonType: function() {
  3891. var ancestor, labelSelector, checked;
  3892. if ( this.element.is("[type=checkbox]") ) {
  3893. this.type = "checkbox";
  3894. } else if ( this.element.is("[type=radio]") ) {
  3895. this.type = "radio";
  3896. } else if ( this.element.is("input") ) {
  3897. this.type = "input";
  3898. } else {
  3899. this.type = "button";
  3900. }
  3901. if ( this.type === "checkbox" || this.type === "radio" ) {
  3902. // we don't search against the document in case the element
  3903. // is disconnected from the DOM
  3904. ancestor = this.element.parents().last();
  3905. labelSelector = "label[for='" + this.element.attr("id") + "']";
  3906. this.buttonElement = ancestor.find( labelSelector );
  3907. if ( !this.buttonElement.length ) {
  3908. ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
  3909. this.buttonElement = ancestor.filter( labelSelector );
  3910. if ( !this.buttonElement.length ) {
  3911. this.buttonElement = ancestor.find( labelSelector );
  3912. }
  3913. }
  3914. this.element.addClass( "ui-helper-hidden-accessible" );
  3915. checked = this.element.is( ":checked" );
  3916. if ( checked ) {
  3917. this.buttonElement.addClass( "ui-state-active" );
  3918. }
  3919. this.buttonElement.prop( "aria-pressed", checked );
  3920. } else {
  3921. this.buttonElement = this.element;
  3922. }
  3923. },
  3924. widget: function() {
  3925. return this.buttonElement;
  3926. },
  3927. _destroy: function() {
  3928. this.element
  3929. .removeClass( "ui-helper-hidden-accessible" );
  3930. this.buttonElement
  3931. .removeClass( baseClasses + " ui-state-active " + typeClasses )
  3932. .removeAttr( "role" )
  3933. .removeAttr( "aria-pressed" )
  3934. .html( this.buttonElement.find(".ui-button-text").html() );
  3935. if ( !this.hasTitle ) {
  3936. this.buttonElement.removeAttr( "title" );
  3937. }
  3938. },
  3939. _setOption: function( key, value ) {
  3940. this._super( key, value );
  3941. if ( key === "disabled" ) {
  3942. this.element.prop( "disabled", !!value );
  3943. if ( value ) {
  3944. this.buttonElement.removeClass( "ui-state-focus" );
  3945. }
  3946. return;
  3947. }
  3948. this._resetButton();
  3949. },
  3950. refresh: function() {
  3951. //See #8237 & #8828
  3952. var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
  3953. if ( isDisabled !== this.options.disabled ) {
  3954. this._setOption( "disabled", isDisabled );
  3955. }
  3956. if ( this.type === "radio" ) {
  3957. radioGroup( this.element[0] ).each(function() {
  3958. if ( $( this ).is( ":checked" ) ) {
  3959. $( this ).button( "widget" )
  3960. .addClass( "ui-state-active" )
  3961. .attr( "aria-pressed", "true" );
  3962. } else {
  3963. $( this ).button( "widget" )
  3964. .removeClass( "ui-state-active" )
  3965. .attr( "aria-pressed", "false" );
  3966. }
  3967. });
  3968. } else if ( this.type === "checkbox" ) {
  3969. if ( this.element.is( ":checked" ) ) {
  3970. this.buttonElement
  3971. .addClass( "ui-state-active" )
  3972. .attr( "aria-pressed", "true" );
  3973. } else {
  3974. this.buttonElement
  3975. .removeClass( "ui-state-active" )
  3976. .attr( "aria-pressed", "false" );
  3977. }
  3978. }
  3979. },
  3980. _resetButton: function() {
  3981. if ( this.type === "input" ) {
  3982. if ( this.options.label ) {
  3983. this.element.val( this.options.label );
  3984. }
  3985. return;
  3986. }
  3987. var buttonElement = this.buttonElement.removeClass( typeClasses ),
  3988. buttonText = $( "<span></span>", this.document[0] )
  3989. .addClass( "ui-button-text" )
  3990. .html( this.options.label )
  3991. .appendTo( buttonElement.empty() )
  3992. .text(),
  3993. icons = this.options.icons,
  3994. multipleIcons = icons.primary && icons.secondary,
  3995. buttonClasses = [];
  3996. if ( icons.primary || icons.secondary ) {
  3997. if ( this.options.text ) {
  3998. buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
  3999. }
  4000. if ( icons.primary ) {
  4001. buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
  4002. }
  4003. if ( icons.secondary ) {
  4004. buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
  4005. }
  4006. if ( !this.options.text ) {
  4007. buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
  4008. if ( !this.hasTitle ) {
  4009. buttonElement.attr( "title", $.trim( buttonText ) );
  4010. }
  4011. }
  4012. } else {
  4013. buttonClasses.push( "ui-button-text-only" );
  4014. }
  4015. buttonElement.addClass( buttonClasses.join( " " ) );
  4016. }
  4017. });
  4018. $.widget( "ui.buttonset", {
  4019. version: "1.10.4",
  4020. options: {
  4021. items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
  4022. },
  4023. _create: function() {
  4024. this.element.addClass( "ui-buttonset" );
  4025. },
  4026. _init: function() {
  4027. this.refresh();
  4028. },
  4029. _setOption: function( key, value ) {
  4030. if ( key === "disabled" ) {
  4031. this.buttons.button( "option", key, value );
  4032. }
  4033. this._super( key, value );
  4034. },
  4035. refresh: function() {
  4036. var rtl = this.element.css( "direction" ) === "rtl";
  4037. this.buttons = this.element.find( this.options.items )
  4038. .filter( ":ui-button" )
  4039. .button( "refresh" )
  4040. .end()
  4041. .not( ":ui-button" )
  4042. .button()
  4043. .end()
  4044. .map(function() {
  4045. return $( this ).button( "widget" )[ 0 ];
  4046. })
  4047. .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
  4048. .filter( ":first" )
  4049. .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
  4050. .end()
  4051. .filter( ":last" )
  4052. .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
  4053. .end()
  4054. .end();
  4055. },
  4056. _destroy: function() {
  4057. this.element.removeClass( "ui-buttonset" );
  4058. this.buttons
  4059. .map(function() {
  4060. return $( this ).button( "widget" )[ 0 ];
  4061. })
  4062. .removeClass( "ui-corner-left ui-corner-right" )
  4063. .end()
  4064. .button( "destroy" );
  4065. }
  4066. });
  4067. }( jQuery ) );
  4068. (function( $, undefined ) {
  4069. // number of pages in a slider
  4070. // (how many times can you page up/down to go through the whole range)
  4071. var numPages = 5;
  4072. $.widget( "ui.slider", $.ui.mouse, {
  4073. version: "1.10.4",
  4074. widgetEventPrefix: "slide",
  4075. options: {
  4076. animate: false,
  4077. distance: 0,
  4078. max: 100,
  4079. min: 0,
  4080. orientation: "horizontal",
  4081. range: false,
  4082. step: 1,
  4083. value: 0,
  4084. values: null,
  4085. // callbacks
  4086. change: null,
  4087. slide: null,
  4088. start: null,
  4089. stop: null
  4090. },
  4091. _create: function() {
  4092. this._keySliding = false;
  4093. this._mouseSliding = false;
  4094. this._animateOff = true;
  4095. this._handleIndex = null;
  4096. this._detectOrientation();
  4097. this._mouseInit();
  4098. this.element
  4099. .addClass( "ui-slider" +
  4100. " ui-slider-" + this.orientation +
  4101. " ui-widget" +
  4102. " ui-widget-content" +
  4103. " ui-corner-all");
  4104. this._refresh();
  4105. this._setOption( "disabled", this.options.disabled );
  4106. this._animateOff = false;
  4107. },
  4108. _refresh: function() {
  4109. this._createRange();
  4110. this._createHandles();
  4111. this._setupEvents();
  4112. this._refreshValue();
  4113. },
  4114. _createHandles: function() {
  4115. var i, handleCount,
  4116. options = this.options,
  4117. existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
  4118. handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
  4119. handles = [];
  4120. handleCount = ( options.values && options.values.length ) || 1;
  4121. if ( existingHandles.length > handleCount ) {
  4122. existingHandles.slice( handleCount ).remove();
  4123. existingHandles = existingHandles.slice( 0, handleCount );
  4124. }
  4125. for ( i = existingHandles.length; i < handleCount; i++ ) {
  4126. handles.push( handle );
  4127. }
  4128. this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
  4129. this.handle = this.handles.eq( 0 );
  4130. this.handles.each(function( i ) {
  4131. $( this ).data( "ui-slider-handle-index", i );
  4132. });
  4133. },
  4134. _createRange: function() {
  4135. var options = this.options,
  4136. classes = "";
  4137. if ( options.range ) {
  4138. if ( options.range === true ) {
  4139. if ( !options.values ) {
  4140. options.values = [ this._valueMin(), this._valueMin() ];
  4141. } else if ( options.values.length && options.values.length !== 2 ) {
  4142. options.values = [ options.values[0], options.values[0] ];
  4143. } else if ( $.isArray( options.values ) ) {
  4144. options.values = options.values.slice(0);
  4145. }
  4146. }
  4147. if ( !this.range || !this.range.length ) {
  4148. this.range = $( "<div></div>" )
  4149. .appendTo( this.element );
  4150. classes = "ui-slider-range" +
  4151. // note: this isn't the most fittingly semantic framework class for this element,
  4152. // but worked best visually with a variety of themes
  4153. " ui-widget-header ui-corner-all";
  4154. } else {
  4155. this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
  4156. // Handle range switching from true to min/max
  4157. .css({
  4158. "left": "",
  4159. "bottom": ""
  4160. });
  4161. }
  4162. this.range.addClass( classes +
  4163. ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
  4164. } else {
  4165. if ( this.range ) {
  4166. this.range.remove();
  4167. }
  4168. this.range = null;
  4169. }
  4170. },
  4171. _setupEvents: function() {
  4172. var elements = this.handles.add( this.range ).filter( "a" );
  4173. this._off( elements );
  4174. this._on( elements, this._handleEvents );
  4175. this._hoverable( elements );
  4176. this._focusable( elements );
  4177. },
  4178. _destroy: function() {
  4179. this.handles.remove();
  4180. if ( this.range ) {
  4181. this.range.remove();
  4182. }
  4183. this.element
  4184. .removeClass( "ui-slider" +
  4185. " ui-slider-horizontal" +
  4186. " ui-slider-vertical" +
  4187. " ui-widget" +
  4188. " ui-widget-content" +
  4189. " ui-corner-all" );
  4190. this._mouseDestroy();
  4191. },
  4192. _mouseCapture: function( event ) {
  4193. var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
  4194. that = this,
  4195. o = this.options;
  4196. if ( o.disabled ) {
  4197. return false;
  4198. }
  4199. this.elementSize = {
  4200. width: this.element.outerWidth(),
  4201. height: this.element.outerHeight()
  4202. };
  4203. this.elementOffset = this.element.offset();
  4204. position = { x: event.pageX, y: event.pageY };
  4205. normValue = this._normValueFromMouse( position );
  4206. distance = this._valueMax() - this._valueMin() + 1;
  4207. this.handles.each(function( i ) {
  4208. var thisDistance = Math.abs( normValue - that.values(i) );
  4209. if (( distance > thisDistance ) ||
  4210. ( distance === thisDistance &&
  4211. (i === that._lastChangedValue || that.values(i) === o.min ))) {
  4212. distance = thisDistance;
  4213. closestHandle = $( this );
  4214. index = i;
  4215. }
  4216. });
  4217. allowed = this._start( event, index );
  4218. if ( allowed === false ) {
  4219. return false;
  4220. }
  4221. this._mouseSliding = true;
  4222. this._handleIndex = index;
  4223. closestHandle
  4224. .addClass( "ui-state-active" )
  4225. .focus();
  4226. offset = closestHandle.offset();
  4227. mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
  4228. this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
  4229. left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
  4230. top: event.pageY - offset.top -
  4231. ( closestHandle.height() / 2 ) -
  4232. ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
  4233. ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
  4234. ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
  4235. };
  4236. if ( !this.handles.hasClass( "ui-state-hover" ) ) {
  4237. this._slide( event, index, normValue );
  4238. }
  4239. this._animateOff = true;
  4240. return true;
  4241. },
  4242. _mouseStart: function() {
  4243. return true;
  4244. },
  4245. _mouseDrag: function( event ) {
  4246. var position = { x: event.pageX, y: event.pageY },
  4247. normValue = this._normValueFromMouse( position );
  4248. this._slide( event, this._handleIndex, normValue );
  4249. return false;
  4250. },
  4251. _mouseStop: function( event ) {
  4252. this.handles.removeClass( "ui-state-active" );
  4253. this._mouseSliding = false;
  4254. this._stop( event, this._handleIndex );
  4255. this._change( event, this._handleIndex );
  4256. this._handleIndex = null;
  4257. this._clickOffset = null;
  4258. this._animateOff = false;
  4259. return false;
  4260. },
  4261. _detectOrientation: function() {
  4262. this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
  4263. },
  4264. _normValueFromMouse: function( position ) {
  4265. var pixelTotal,
  4266. pixelMouse,
  4267. percentMouse,
  4268. valueTotal,
  4269. valueMouse;
  4270. if ( this.orientation === "horizontal" ) {
  4271. pixelTotal = this.elementSize.width;
  4272. pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
  4273. } else {
  4274. pixelTotal = this.elementSize.height;
  4275. pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
  4276. }
  4277. percentMouse = ( pixelMouse / pixelTotal );
  4278. if ( percentMouse > 1 ) {
  4279. percentMouse = 1;
  4280. }
  4281. if ( percentMouse < 0 ) {
  4282. percentMouse = 0;
  4283. }
  4284. if ( this.orientation === "vertical" ) {
  4285. percentMouse = 1 - percentMouse;
  4286. }
  4287. valueTotal = this._valueMax() - this._valueMin();
  4288. valueMouse = this._valueMin() + percentMouse * valueTotal;
  4289. return this._trimAlignValue( valueMouse );
  4290. },
  4291. _start: function( event, index ) {
  4292. var uiHash = {
  4293. handle: this.handles[ index ],
  4294. value: this.value()
  4295. };
  4296. if ( this.options.values && this.options.values.length ) {
  4297. uiHash.value = this.values( index );
  4298. uiHash.values = this.values();
  4299. }
  4300. return this._trigger( "start", event, uiHash );
  4301. },
  4302. _slide: function( event, index, newVal ) {
  4303. var otherVal,
  4304. newValues,
  4305. allowed;
  4306. if ( this.options.values && this.options.values.length ) {
  4307. otherVal = this.values( index ? 0 : 1 );
  4308. if ( ( this.options.values.length === 2 && this.options.range === true ) &&
  4309. ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
  4310. ) {
  4311. newVal = otherVal;
  4312. }
  4313. if ( newVal !== this.values( index ) ) {
  4314. newValues = this.values();
  4315. newValues[ index ] = newVal;
  4316. // A slide can be canceled by returning false from the slide callback
  4317. allowed = this._trigger( "slide", event, {
  4318. handle: this.handles[ index ],
  4319. value: newVal,
  4320. values: newValues
  4321. } );
  4322. otherVal = this.values( index ? 0 : 1 );
  4323. if ( allowed !== false ) {
  4324. this.values( index, newVal );
  4325. }
  4326. }
  4327. } else {
  4328. if ( newVal !== this.value() ) {
  4329. // A slide can be canceled by returning false from the slide callback
  4330. allowed = this._trigger( "slide", event, {
  4331. handle: this.handles[ index ],
  4332. value: newVal
  4333. } );
  4334. if ( allowed !== false ) {
  4335. this.value( newVal );
  4336. }
  4337. }
  4338. }
  4339. },
  4340. _stop: function( event, index ) {
  4341. var uiHash = {
  4342. handle: this.handles[ index ],
  4343. value: this.value()
  4344. };
  4345. if ( this.options.values && this.options.values.length ) {
  4346. uiHash.value = this.values( index );
  4347. uiHash.values = this.values();
  4348. }
  4349. this._trigger( "stop", event, uiHash );
  4350. },
  4351. _change: function( event, index ) {
  4352. if ( !this._keySliding && !this._mouseSliding ) {
  4353. var uiHash = {
  4354. handle: this.handles[ index ],
  4355. value: this.value()
  4356. };
  4357. if ( this.options.values && this.options.values.length ) {
  4358. uiHash.value = this.values( index );
  4359. uiHash.values = this.values();
  4360. }
  4361. //store the last changed value index for reference when handles overlap
  4362. this._lastChangedValue = index;
  4363. this._trigger( "change", event, uiHash );
  4364. }
  4365. },
  4366. value: function( newValue ) {
  4367. if ( arguments.length ) {
  4368. this.options.value = this._trimAlignValue( newValue );
  4369. this._refreshValue();
  4370. this._change( null, 0 );
  4371. return;
  4372. }
  4373. return this._value();
  4374. },
  4375. values: function( index, newValue ) {
  4376. var vals,
  4377. newValues,
  4378. i;
  4379. if ( arguments.length > 1 ) {
  4380. this.options.values[ index ] = this._trimAlignValue( newValue );
  4381. this._refreshValue();
  4382. this._change( null, index );
  4383. return;
  4384. }
  4385. if ( arguments.length ) {
  4386. if ( $.isArray( arguments[ 0 ] ) ) {
  4387. vals = this.options.values;
  4388. newValues = arguments[ 0 ];
  4389. for ( i = 0; i < vals.length; i += 1 ) {
  4390. vals[ i ] = this._trimAlignValue( newValues[ i ] );
  4391. this._change( null, i );
  4392. }
  4393. this._refreshValue();
  4394. } else {
  4395. if ( this.options.values && this.options.values.length ) {
  4396. return this._values( index );
  4397. } else {
  4398. return this.value();
  4399. }
  4400. }
  4401. } else {
  4402. return this._values();
  4403. }
  4404. },
  4405. _setOption: function( key, value ) {
  4406. var i,
  4407. valsLength = 0;
  4408. if ( key === "range" && this.options.range === true ) {
  4409. if ( value === "min" ) {
  4410. this.options.value = this._values( 0 );
  4411. this.options.values = null;
  4412. } else if ( value === "max" ) {
  4413. this.options.value = this._values( this.options.values.length-1 );
  4414. this.options.values = null;
  4415. }
  4416. }
  4417. if ( $.isArray( this.options.values ) ) {
  4418. valsLength = this.options.values.length;
  4419. }
  4420. $.Widget.prototype._setOption.apply( this, arguments );
  4421. switch ( key ) {
  4422. case "orientation":
  4423. this._detectOrientation();
  4424. this.element
  4425. .removeClass( "ui-slider-horizontal ui-slider-vertical" )
  4426. .addClass( "ui-slider-" + this.orientation );
  4427. this._refreshValue();
  4428. break;
  4429. case "value":
  4430. this._animateOff = true;
  4431. this._refreshValue();
  4432. this._change( null, 0 );
  4433. this._animateOff = false;
  4434. break;
  4435. case "values":
  4436. this._animateOff = true;
  4437. this._refreshValue();
  4438. for ( i = 0; i < valsLength; i += 1 ) {
  4439. this._change( null, i );
  4440. }
  4441. this._animateOff = false;
  4442. break;
  4443. case "min":
  4444. case "max":
  4445. this._animateOff = true;
  4446. this._refreshValue();
  4447. this._animateOff = false;
  4448. break;
  4449. case "range":
  4450. this._animateOff = true;
  4451. this._refresh();
  4452. this._animateOff = false;
  4453. break;
  4454. }
  4455. },
  4456. //internal value getter
  4457. // _value() returns value trimmed by min and max, aligned by step
  4458. _value: function() {
  4459. var val = this.options.value;
  4460. val = this._trimAlignValue( val );
  4461. return val;
  4462. },
  4463. //internal values getter
  4464. // _values() returns array of values trimmed by min and max, aligned by step
  4465. // _values( index ) returns single value trimmed by min and max, aligned by step
  4466. _values: function( index ) {
  4467. var val,
  4468. vals,
  4469. i;
  4470. if ( arguments.length ) {
  4471. val = this.options.values[ index ];
  4472. val = this._trimAlignValue( val );
  4473. return val;
  4474. } else if ( this.options.values && this.options.values.length ) {
  4475. // .slice() creates a copy of the array
  4476. // this copy gets trimmed by min and max and then returned
  4477. vals = this.options.values.slice();
  4478. for ( i = 0; i < vals.length; i+= 1) {
  4479. vals[ i ] = this._trimAlignValue( vals[ i ] );
  4480. }
  4481. return vals;
  4482. } else {
  4483. return [];
  4484. }
  4485. },
  4486. // returns the step-aligned value that val is closest to, between (inclusive) min and max
  4487. _trimAlignValue: function( val ) {
  4488. if ( val <= this._valueMin() ) {
  4489. return this._valueMin();
  4490. }
  4491. if ( val >= this._valueMax() ) {
  4492. return this._valueMax();
  4493. }
  4494. var step = ( this.options.step > 0 ) ? this.options.step : 1,
  4495. valModStep = (val - this._valueMin()) % step,
  4496. alignValue = val - valModStep;
  4497. if ( Math.abs(valModStep) * 2 >= step ) {
  4498. alignValue += ( valModStep > 0 ) ? step : ( -step );
  4499. }
  4500. // Since JavaScript has problems with large floats, round
  4501. // the final value to 5 digits after the decimal point (see #4124)
  4502. return parseFloat( alignValue.toFixed(5) );
  4503. },
  4504. _valueMin: function() {
  4505. return this.options.min;
  4506. },
  4507. _valueMax: function() {
  4508. return this.options.max;
  4509. },
  4510. _refreshValue: function() {
  4511. var lastValPercent, valPercent, value, valueMin, valueMax,
  4512. oRange = this.options.range,
  4513. o = this.options,
  4514. that = this,
  4515. animate = ( !this._animateOff ) ? o.animate : false,
  4516. _set = {};
  4517. if ( this.options.values && this.options.values.length ) {
  4518. this.handles.each(function( i ) {
  4519. valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
  4520. _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
  4521. $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
  4522. if ( that.options.range === true ) {
  4523. if ( that.orientation === "horizontal" ) {
  4524. if ( i === 0 ) {
  4525. that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
  4526. }
  4527. if ( i === 1 ) {
  4528. that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
  4529. }
  4530. } else {
  4531. if ( i === 0 ) {
  4532. that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
  4533. }
  4534. if ( i === 1 ) {
  4535. that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
  4536. }
  4537. }
  4538. }
  4539. lastValPercent = valPercent;
  4540. });
  4541. } else {
  4542. value = this.value();
  4543. valueMin = this._valueMin();
  4544. valueMax = this._valueMax();
  4545. valPercent = ( valueMax !== valueMin ) ?
  4546. ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
  4547. 0;
  4548. _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
  4549. this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
  4550. if ( oRange === "min" && this.orientation === "horizontal" ) {
  4551. this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
  4552. }
  4553. if ( oRange === "max" && this.orientation === "horizontal" ) {
  4554. this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
  4555. }
  4556. if ( oRange === "min" && this.orientation === "vertical" ) {
  4557. this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
  4558. }
  4559. if ( oRange === "max" && this.orientation === "vertical" ) {
  4560. this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
  4561. }
  4562. }
  4563. },
  4564. _handleEvents: {
  4565. keydown: function( event ) {
  4566. var allowed, curVal, newVal, step,
  4567. index = $( event.target ).data( "ui-slider-handle-index" );
  4568. switch ( event.keyCode ) {
  4569. case $.ui.keyCode.HOME:
  4570. case $.ui.keyCode.END:
  4571. case $.ui.keyCode.PAGE_UP:
  4572. case $.ui.keyCode.PAGE_DOWN:
  4573. case $.ui.keyCode.UP:
  4574. case $.ui.keyCode.RIGHT:
  4575. case $.ui.keyCode.DOWN:
  4576. case $.ui.keyCode.LEFT:
  4577. event.preventDefault();
  4578. if ( !this._keySliding ) {
  4579. this._keySliding = true;
  4580. $( event.target ).addClass( "ui-state-active" );
  4581. allowed = this._start( event, index );
  4582. if ( allowed === false ) {
  4583. return;
  4584. }
  4585. }
  4586. break;
  4587. }
  4588. step = this.options.step;
  4589. if ( this.options.values && this.options.values.length ) {
  4590. curVal = newVal = this.values( index );
  4591. } else {
  4592. curVal = newVal = this.value();
  4593. }
  4594. switch ( event.keyCode ) {
  4595. case $.ui.keyCode.HOME:
  4596. newVal = this._valueMin();
  4597. break;
  4598. case $.ui.keyCode.END:
  4599. newVal = this._valueMax();
  4600. break;
  4601. case $.ui.keyCode.PAGE_UP:
  4602. newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );
  4603. break;
  4604. case $.ui.keyCode.PAGE_DOWN:
  4605. newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );
  4606. break;
  4607. case $.ui.keyCode.UP:
  4608. case $.ui.keyCode.RIGHT:
  4609. if ( curVal === this._valueMax() ) {
  4610. return;
  4611. }
  4612. newVal = this._trimAlignValue( curVal + step );
  4613. break;
  4614. case $.ui.keyCode.DOWN:
  4615. case $.ui.keyCode.LEFT:
  4616. if ( curVal === this._valueMin() ) {
  4617. return;
  4618. }
  4619. newVal = this._trimAlignValue( curVal - step );
  4620. break;
  4621. }
  4622. this._slide( event, index, newVal );
  4623. },
  4624. click: function( event ) {
  4625. event.preventDefault();
  4626. },
  4627. keyup: function( event ) {
  4628. var index = $( event.target ).data( "ui-slider-handle-index" );
  4629. if ( this._keySliding ) {
  4630. this._keySliding = false;
  4631. this._stop( event, index );
  4632. this._change( event, index );
  4633. $( event.target ).removeClass( "ui-state-active" );
  4634. }
  4635. }
  4636. }
  4637. });
  4638. }(jQuery));
  4639. (function( $ ) {
  4640. function modifier( fn ) {
  4641. return function() {
  4642. var previous = this.element.val();
  4643. fn.apply( this, arguments );
  4644. this._refresh();
  4645. if ( previous !== this.element.val() ) {
  4646. this._trigger( "change" );
  4647. }
  4648. };
  4649. }
  4650. $.widget( "ui.spinner", {
  4651. version: "1.10.4",
  4652. defaultElement: "<input>",
  4653. widgetEventPrefix: "spin",
  4654. options: {
  4655. culture: null,
  4656. icons: {
  4657. down: "ui-icon-triangle-1-s",
  4658. up: "ui-icon-triangle-1-n"
  4659. },
  4660. incremental: true,
  4661. max: null,
  4662. min: null,
  4663. numberFormat: null,
  4664. page: 10,
  4665. step: 1,
  4666. change: null,
  4667. spin: null,
  4668. start: null,
  4669. stop: null
  4670. },
  4671. _create: function() {
  4672. // handle string values that need to be parsed
  4673. this._setOption( "max", this.options.max );
  4674. this._setOption( "min", this.options.min );
  4675. this._setOption( "step", this.options.step );
  4676. // Only format if there is a value, prevents the field from being marked
  4677. // as invalid in Firefox, see #9573.
  4678. if ( this.value() !== "" ) {
  4679. // Format the value, but don't constrain.
  4680. this._value( this.element.val(), true );
  4681. }
  4682. this._draw();
  4683. this._on( this._events );
  4684. this._refresh();
  4685. // turning off autocomplete prevents the browser from remembering the
  4686. // value when navigating through history, so we re-enable autocomplete
  4687. // if the page is unloaded before the widget is destroyed. #7790
  4688. this._on( this.window, {
  4689. beforeunload: function() {
  4690. this.element.removeAttr( "autocomplete" );
  4691. }
  4692. });
  4693. },
  4694. _getCreateOptions: function() {
  4695. var options = {},
  4696. element = this.element;
  4697. $.each( [ "min", "max", "step" ], function( i, option ) {
  4698. var value = element.attr( option );
  4699. if ( value !== undefined && value.length ) {
  4700. options[ option ] = value;
  4701. }
  4702. });
  4703. return options;
  4704. },
  4705. _events: {
  4706. keydown: function( event ) {
  4707. if ( this._start( event ) && this._keydown( event ) ) {
  4708. event.preventDefault();
  4709. }
  4710. },
  4711. keyup: "_stop",
  4712. focus: function() {
  4713. this.previous = this.element.val();
  4714. },
  4715. blur: function( event ) {
  4716. if ( this.cancelBlur ) {
  4717. delete this.cancelBlur;
  4718. return;
  4719. }
  4720. this._stop();
  4721. this._refresh();
  4722. if ( this.previous !== this.element.val() ) {
  4723. this._trigger( "change", event );
  4724. }
  4725. },
  4726. mousewheel: function( event, delta ) {
  4727. if ( !delta ) {
  4728. return;
  4729. }
  4730. if ( !this.spinning && !this._start( event ) ) {
  4731. return false;
  4732. }
  4733. this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
  4734. clearTimeout( this.mousewheelTimer );
  4735. this.mousewheelTimer = this._delay(function() {
  4736. if ( this.spinning ) {
  4737. this._stop( event );
  4738. }
  4739. }, 100 );
  4740. event.preventDefault();
  4741. },
  4742. "mousedown .ui-spinner-button": function( event ) {
  4743. var previous;
  4744. // We never want the buttons to have focus; whenever the user is
  4745. // interacting with the spinner, the focus should be on the input.
  4746. // If the input is focused then this.previous is properly set from
  4747. // when the input first received focus. If the input is not focused
  4748. // then we need to set this.previous based on the value before spinning.
  4749. previous = this.element[0] === this.document[0].activeElement ?
  4750. this.previous : this.element.val();
  4751. function checkFocus() {
  4752. var isActive = this.element[0] === this.document[0].activeElement;
  4753. if ( !isActive ) {
  4754. this.element.focus();
  4755. this.previous = previous;
  4756. // support: IE
  4757. // IE sets focus asynchronously, so we need to check if focus
  4758. // moved off of the input because the user clicked on the button.
  4759. this._delay(function() {
  4760. this.previous = previous;
  4761. });
  4762. }
  4763. }
  4764. // ensure focus is on (or stays on) the text field
  4765. event.preventDefault();
  4766. checkFocus.call( this );
  4767. // support: IE
  4768. // IE doesn't prevent moving focus even with event.preventDefault()
  4769. // so we set a flag to know when we should ignore the blur event
  4770. // and check (again) if focus moved off of the input.
  4771. this.cancelBlur = true;
  4772. this._delay(function() {
  4773. delete this.cancelBlur;
  4774. checkFocus.call( this );
  4775. });
  4776. if ( this._start( event ) === false ) {
  4777. return;
  4778. }
  4779. this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
  4780. },
  4781. "mouseup .ui-spinner-button": "_stop",
  4782. "mouseenter .ui-spinner-button": function( event ) {
  4783. // button will add ui-state-active if mouse was down while mouseleave and kept down
  4784. if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
  4785. return;
  4786. }
  4787. if ( this._start( event ) === false ) {
  4788. return false;
  4789. }
  4790. this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
  4791. },
  4792. // TODO: do we really want to consider this a stop?
  4793. // shouldn't we just stop the repeater and wait until mouseup before
  4794. // we trigger the stop event?
  4795. "mouseleave .ui-spinner-button": "_stop"
  4796. },
  4797. _draw: function() {
  4798. var uiSpinner = this.uiSpinner = this.element
  4799. .addClass( "ui-spinner-input" )
  4800. .attr( "autocomplete", "off" )
  4801. .wrap( this._uiSpinnerHtml() )
  4802. .parent()
  4803. // add buttons
  4804. .append( this._buttonHtml() );
  4805. this.element.attr( "role", "spinbutton" );
  4806. // button bindings
  4807. this.buttons = uiSpinner.find( ".ui-spinner-button" )
  4808. .attr( "tabIndex", -1 )
  4809. .button()
  4810. .removeClass( "ui-corner-all" );
  4811. // IE 6 doesn't understand height: 50% for the buttons
  4812. // unless the wrapper has an explicit height
  4813. if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
  4814. uiSpinner.height() > 0 ) {
  4815. uiSpinner.height( uiSpinner.height() );
  4816. }
  4817. // disable spinner if element was already disabled
  4818. if ( this.options.disabled ) {
  4819. this.disable();
  4820. }
  4821. },
  4822. _keydown: function( event ) {
  4823. var options = this.options,
  4824. keyCode = $.ui.keyCode;
  4825. switch ( event.keyCode ) {
  4826. case keyCode.UP:
  4827. this._repeat( null, 1, event );
  4828. return true;
  4829. case keyCode.DOWN:
  4830. this._repeat( null, -1, event );
  4831. return true;
  4832. case keyCode.PAGE_UP:
  4833. this._repeat( null, options.page, event );
  4834. return true;
  4835. case keyCode.PAGE_DOWN:
  4836. this._repeat( null, -options.page, event );
  4837. return true;
  4838. }
  4839. return false;
  4840. },
  4841. _uiSpinnerHtml: function() {
  4842. return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
  4843. },
  4844. _buttonHtml: function() {
  4845. return "" +
  4846. "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
  4847. "<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
  4848. "</a>" +
  4849. "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
  4850. "<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
  4851. "</a>";
  4852. },
  4853. _start: function( event ) {
  4854. if ( !this.spinning && this._trigger( "start", event ) === false ) {
  4855. return false;
  4856. }
  4857. if ( !this.counter ) {
  4858. this.counter = 1;
  4859. }
  4860. this.spinning = true;
  4861. return true;
  4862. },
  4863. _repeat: function( i, steps, event ) {
  4864. i = i || 500;
  4865. clearTimeout( this.timer );
  4866. this.timer = this._delay(function() {
  4867. this._repeat( 40, steps, event );
  4868. }, i );
  4869. this._spin( steps * this.options.step, event );
  4870. },
  4871. _spin: function( step, event ) {
  4872. var value = this.value() || 0;
  4873. if ( !this.counter ) {
  4874. this.counter = 1;
  4875. }
  4876. value = this._adjustValue( value + step * this._increment( this.counter ) );
  4877. if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
  4878. this._value( value );
  4879. this.counter++;
  4880. }
  4881. },
  4882. _increment: function( i ) {
  4883. var incremental = this.options.incremental;
  4884. if ( incremental ) {
  4885. return $.isFunction( incremental ) ?
  4886. incremental( i ) :
  4887. Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );
  4888. }
  4889. return 1;
  4890. },
  4891. _precision: function() {
  4892. var precision = this._precisionOf( this.options.step );
  4893. if ( this.options.min !== null ) {
  4894. precision = Math.max( precision, this._precisionOf( this.options.min ) );
  4895. }
  4896. return precision;
  4897. },
  4898. _precisionOf: function( num ) {
  4899. var str = num.toString(),
  4900. decimal = str.indexOf( "." );
  4901. return decimal === -1 ? 0 : str.length - decimal - 1;
  4902. },
  4903. _adjustValue: function( value ) {
  4904. var base, aboveMin,
  4905. options = this.options;
  4906. // make sure we're at a valid step
  4907. // - find out where we are relative to the base (min or 0)
  4908. base = options.min !== null ? options.min : 0;
  4909. aboveMin = value - base;
  4910. // - round to the nearest step
  4911. aboveMin = Math.round(aboveMin / options.step) * options.step;
  4912. // - rounding is based on 0, so adjust back to our base
  4913. value = base + aboveMin;
  4914. // fix precision from bad JS floating point math
  4915. value = parseFloat( value.toFixed( this._precision() ) );
  4916. // clamp the value
  4917. if ( options.max !== null && value > options.max) {
  4918. return options.max;
  4919. }
  4920. if ( options.min !== null && value < options.min ) {
  4921. return options.min;
  4922. }
  4923. return value;
  4924. },
  4925. _stop: function( event ) {
  4926. if ( !this.spinning ) {
  4927. return;
  4928. }
  4929. clearTimeout( this.timer );
  4930. clearTimeout( this.mousewheelTimer );
  4931. this.counter = 0;
  4932. this.spinning = false;
  4933. this._trigger( "stop", event );
  4934. },
  4935. _setOption: function( key, value ) {
  4936. if ( key === "culture" || key === "numberFormat" ) {
  4937. var prevValue = this._parse( this.element.val() );
  4938. this.options[ key ] = value;
  4939. this.element.val( this._format( prevValue ) );
  4940. return;
  4941. }
  4942. if ( key === "max" || key === "min" || key === "step" ) {
  4943. if ( typeof value === "string" ) {
  4944. value = this._parse( value );
  4945. }
  4946. }
  4947. if ( key === "icons" ) {
  4948. this.buttons.first().find( ".ui-icon" )
  4949. .removeClass( this.options.icons.up )
  4950. .addClass( value.up );
  4951. this.buttons.last().find( ".ui-icon" )
  4952. .removeClass( this.options.icons.down )
  4953. .addClass( value.down );
  4954. }
  4955. this._super( key, value );
  4956. if ( key === "disabled" ) {
  4957. if ( value ) {
  4958. this.element.prop( "disabled", true );
  4959. this.buttons.button( "disable" );
  4960. } else {
  4961. this.element.prop( "disabled", false );
  4962. this.buttons.button( "enable" );
  4963. }
  4964. }
  4965. },
  4966. _setOptions: modifier(function( options ) {
  4967. this._super( options );
  4968. this._value( this.element.val() );
  4969. }),
  4970. _parse: function( val ) {
  4971. if ( typeof val === "string" && val !== "" ) {
  4972. val = window.Globalize && this.options.numberFormat ?
  4973. Globalize.parseFloat( val, 10, this.options.culture ) : +val;
  4974. }
  4975. return val === "" || isNaN( val ) ? null : val;
  4976. },
  4977. _format: function( value ) {
  4978. if ( value === "" ) {
  4979. return "";
  4980. }
  4981. return window.Globalize && this.options.numberFormat ?
  4982. Globalize.format( value, this.options.numberFormat, this.options.culture ) :
  4983. value;
  4984. },
  4985. _refresh: function() {
  4986. this.element.attr({
  4987. "aria-valuemin": this.options.min,
  4988. "aria-valuemax": this.options.max,
  4989. // TODO: what should we do with values that can't be parsed?
  4990. "aria-valuenow": this._parse( this.element.val() )
  4991. });
  4992. },
  4993. // update the value without triggering change
  4994. _value: function( value, allowAny ) {
  4995. var parsed;
  4996. if ( value !== "" ) {
  4997. parsed = this._parse( value );
  4998. if ( parsed !== null ) {
  4999. if ( !allowAny ) {
  5000. parsed = this._adjustValue( parsed );
  5001. }
  5002. value = this._format( parsed );
  5003. }
  5004. }
  5005. this.element.val( value );
  5006. this._refresh();
  5007. },
  5008. _destroy: function() {
  5009. this.element
  5010. .removeClass( "ui-spinner-input" )
  5011. .prop( "disabled", false )
  5012. .removeAttr( "autocomplete" )
  5013. .removeAttr( "role" )
  5014. .removeAttr( "aria-valuemin" )
  5015. .removeAttr( "aria-valuemax" )
  5016. .removeAttr( "aria-valuenow" );
  5017. this.uiSpinner.replaceWith( this.element );
  5018. },
  5019. stepUp: modifier(function( steps ) {
  5020. this._stepUp( steps );
  5021. }),
  5022. _stepUp: function( steps ) {
  5023. if ( this._start() ) {
  5024. this._spin( (steps || 1) * this.options.step );
  5025. this._stop();
  5026. }
  5027. },
  5028. stepDown: modifier(function( steps ) {
  5029. this._stepDown( steps );
  5030. }),
  5031. _stepDown: function( steps ) {
  5032. if ( this._start() ) {
  5033. this._spin( (steps || 1) * -this.options.step );
  5034. this._stop();
  5035. }
  5036. },
  5037. pageUp: modifier(function( pages ) {
  5038. this._stepUp( (pages || 1) * this.options.page );
  5039. }),
  5040. pageDown: modifier(function( pages ) {
  5041. this._stepDown( (pages || 1) * this.options.page );
  5042. }),
  5043. value: function( newVal ) {
  5044. if ( !arguments.length ) {
  5045. return this._parse( this.element.val() );
  5046. }
  5047. modifier( this._value ).call( this, newVal );
  5048. },
  5049. widget: function() {
  5050. return this.uiSpinner;
  5051. }
  5052. });
  5053. }( jQuery ) );