jquery-ui-1.9.1.custom.js 438 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823
  1. /*! jQuery UI - v1.9.1 - 2012-11-14
  2. * http://jqueryui.com
  3. * Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.menu.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js, jquery.ui.effect.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js
  4. * Copyright (c) 2012 jQuery Foundation and other contributors Licensed MIT */
  5. (function( $, undefined ) {
  6. var uuid = 0,
  7. runiqueId = /^ui-id-\d+$/;
  8. // prevent duplicate loading
  9. // this is only a problem because we proxy existing functions
  10. // and we don't want to double proxy them
  11. $.ui = $.ui || {};
  12. if ( $.ui.version ) {
  13. return;
  14. }
  15. $.extend( $.ui, {
  16. version: "1.9.1",
  17. keyCode: {
  18. BACKSPACE: 8,
  19. COMMA: 188,
  20. DELETE: 46,
  21. DOWN: 40,
  22. END: 35,
  23. ENTER: 13,
  24. ESCAPE: 27,
  25. HOME: 36,
  26. LEFT: 37,
  27. NUMPAD_ADD: 107,
  28. NUMPAD_DECIMAL: 110,
  29. NUMPAD_DIVIDE: 111,
  30. NUMPAD_ENTER: 108,
  31. NUMPAD_MULTIPLY: 106,
  32. NUMPAD_SUBTRACT: 109,
  33. PAGE_DOWN: 34,
  34. PAGE_UP: 33,
  35. PERIOD: 190,
  36. RIGHT: 39,
  37. SPACE: 32,
  38. TAB: 9,
  39. UP: 38
  40. }
  41. });
  42. // plugins
  43. $.fn.extend({
  44. _focus: $.fn.focus,
  45. focus: function( delay, fn ) {
  46. return typeof delay === "number" ?
  47. this.each(function() {
  48. var elem = this;
  49. setTimeout(function() {
  50. $( elem ).focus();
  51. if ( fn ) {
  52. fn.call( elem );
  53. }
  54. }, delay );
  55. }) :
  56. this._focus.apply( this, arguments );
  57. },
  58. scrollParent: function() {
  59. var scrollParent;
  60. if (($.ui.ie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
  61. scrollParent = this.parents().filter(function() {
  62. return (/(relative|absolute|fixed)/).test($.css(this,'position')) && (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x'));
  63. }).eq(0);
  64. } else {
  65. scrollParent = this.parents().filter(function() {
  66. return (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x'));
  67. }).eq(0);
  68. }
  69. return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
  70. },
  71. zIndex: function( zIndex ) {
  72. if ( zIndex !== undefined ) {
  73. return this.css( "zIndex", zIndex );
  74. }
  75. if ( this.length ) {
  76. var elem = $( this[ 0 ] ), position, value;
  77. while ( elem.length && elem[ 0 ] !== document ) {
  78. // Ignore z-index if position is set to a value where z-index is ignored by the browser
  79. // This makes behavior of this function consistent across browsers
  80. // WebKit always returns auto if the element is positioned
  81. position = elem.css( "position" );
  82. if ( position === "absolute" || position === "relative" || position === "fixed" ) {
  83. // IE returns 0 when zIndex is not specified
  84. // other browsers return a string
  85. // we ignore the case of nested elements with an explicit value of 0
  86. // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
  87. value = parseInt( elem.css( "zIndex" ), 10 );
  88. if ( !isNaN( value ) && value !== 0 ) {
  89. return value;
  90. }
  91. }
  92. elem = elem.parent();
  93. }
  94. }
  95. return 0;
  96. },
  97. uniqueId: function() {
  98. return this.each(function() {
  99. if ( !this.id ) {
  100. this.id = "ui-id-" + (++uuid);
  101. }
  102. });
  103. },
  104. removeUniqueId: function() {
  105. return this.each(function() {
  106. if ( runiqueId.test( this.id ) ) {
  107. $( this ).removeAttr( "id" );
  108. }
  109. });
  110. }
  111. });
  112. // support: jQuery <1.8
  113. if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
  114. $.each( [ "Width", "Height" ], function( i, name ) {
  115. var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
  116. type = name.toLowerCase(),
  117. orig = {
  118. innerWidth: $.fn.innerWidth,
  119. innerHeight: $.fn.innerHeight,
  120. outerWidth: $.fn.outerWidth,
  121. outerHeight: $.fn.outerHeight
  122. };
  123. function reduce( elem, size, border, margin ) {
  124. $.each( side, function() {
  125. size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
  126. if ( border ) {
  127. size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
  128. }
  129. if ( margin ) {
  130. size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
  131. }
  132. });
  133. return size;
  134. }
  135. $.fn[ "inner" + name ] = function( size ) {
  136. if ( size === undefined ) {
  137. return orig[ "inner" + name ].call( this );
  138. }
  139. return this.each(function() {
  140. $( this ).css( type, reduce( this, size ) + "px" );
  141. });
  142. };
  143. $.fn[ "outer" + name] = function( size, margin ) {
  144. if ( typeof size !== "number" ) {
  145. return orig[ "outer" + name ].call( this, size );
  146. }
  147. return this.each(function() {
  148. $( this).css( type, reduce( this, size, true, margin ) + "px" );
  149. });
  150. };
  151. });
  152. }
  153. // selectors
  154. function focusable( element, isTabIndexNotNaN ) {
  155. var map, mapName, img,
  156. nodeName = element.nodeName.toLowerCase();
  157. if ( "area" === nodeName ) {
  158. map = element.parentNode;
  159. mapName = map.name;
  160. if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
  161. return false;
  162. }
  163. img = $( "img[usemap=#" + mapName + "]" )[0];
  164. return !!img && visible( img );
  165. }
  166. return ( /input|select|textarea|button|object/.test( nodeName ) ?
  167. !element.disabled :
  168. "a" === nodeName ?
  169. element.href || isTabIndexNotNaN :
  170. isTabIndexNotNaN) &&
  171. // the element and all of its ancestors must be visible
  172. visible( element );
  173. }
  174. function visible( element ) {
  175. return $.expr.filters.visible( element ) &&
  176. !$( element ).parents().andSelf().filter(function() {
  177. return $.css( this, "visibility" ) === "hidden";
  178. }).length;
  179. }
  180. $.extend( $.expr[ ":" ], {
  181. data: $.expr.createPseudo ?
  182. $.expr.createPseudo(function( dataName ) {
  183. return function( elem ) {
  184. return !!$.data( elem, dataName );
  185. };
  186. }) :
  187. // support: jQuery <1.8
  188. function( elem, i, match ) {
  189. return !!$.data( elem, match[ 3 ] );
  190. },
  191. focusable: function( element ) {
  192. return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
  193. },
  194. tabbable: function( element ) {
  195. var tabIndex = $.attr( element, "tabindex" ),
  196. isTabIndexNaN = isNaN( tabIndex );
  197. return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
  198. }
  199. });
  200. // support
  201. $(function() {
  202. var body = document.body,
  203. div = body.appendChild( div = document.createElement( "div" ) );
  204. // access offsetHeight before setting the style to prevent a layout bug
  205. // in IE 9 which causes the element to continue to take up space even
  206. // after it is removed from the DOM (#8026)
  207. div.offsetHeight;
  208. $.extend( div.style, {
  209. minHeight: "100px",
  210. height: "auto",
  211. padding: 0,
  212. borderWidth: 0
  213. });
  214. $.support.minHeight = div.offsetHeight === 100;
  215. $.support.selectstart = "onselectstart" in div;
  216. // set display to none to avoid a layout bug in IE
  217. // http://dev.jquery.com/ticket/4014
  218. body.removeChild( div ).style.display = "none";
  219. });
  220. // deprecated
  221. (function() {
  222. var uaMatch = /msie ([\w.]+)/.exec( navigator.userAgent.toLowerCase() ) || [];
  223. $.ui.ie = uaMatch.length ? true : false;
  224. $.ui.ie6 = parseFloat( uaMatch[ 1 ], 10 ) === 6;
  225. })();
  226. $.fn.extend({
  227. disableSelection: function() {
  228. return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
  229. ".ui-disableSelection", function( event ) {
  230. event.preventDefault();
  231. });
  232. },
  233. enableSelection: function() {
  234. return this.unbind( ".ui-disableSelection" );
  235. }
  236. });
  237. $.extend( $.ui, {
  238. // $.ui.plugin is deprecated. Use the proxy pattern instead.
  239. plugin: {
  240. add: function( module, option, set ) {
  241. var i,
  242. proto = $.ui[ module ].prototype;
  243. for ( i in set ) {
  244. proto.plugins[ i ] = proto.plugins[ i ] || [];
  245. proto.plugins[ i ].push( [ option, set[ i ] ] );
  246. }
  247. },
  248. call: function( instance, name, args ) {
  249. var i,
  250. set = instance.plugins[ name ];
  251. if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
  252. return;
  253. }
  254. for ( i = 0; i < set.length; i++ ) {
  255. if ( instance.options[ set[ i ][ 0 ] ] ) {
  256. set[ i ][ 1 ].apply( instance.element, args );
  257. }
  258. }
  259. }
  260. },
  261. contains: $.contains,
  262. // only used by resizable
  263. hasScroll: function( el, a ) {
  264. //If overflow is hidden, the element might have extra content, but the user wants to hide it
  265. if ( $( el ).css( "overflow" ) === "hidden") {
  266. return false;
  267. }
  268. var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
  269. has = false;
  270. if ( el[ scroll ] > 0 ) {
  271. return true;
  272. }
  273. // TODO: determine which cases actually cause this to happen
  274. // if the element doesn't have the scroll set, see if it's possible to
  275. // set the scroll
  276. el[ scroll ] = 1;
  277. has = ( el[ scroll ] > 0 );
  278. el[ scroll ] = 0;
  279. return has;
  280. },
  281. // these are odd functions, fix the API or move into individual plugins
  282. isOverAxis: function( x, reference, size ) {
  283. //Determines when x coordinate is over "b" element axis
  284. return ( x > reference ) && ( x < ( reference + size ) );
  285. },
  286. isOver: function( y, x, top, left, height, width ) {
  287. //Determines when x, y coordinates is over "b" element
  288. return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
  289. }
  290. });
  291. })( jQuery );
  292. (function( $, undefined ) {
  293. var uuid = 0,
  294. slice = Array.prototype.slice,
  295. _cleanData = $.cleanData;
  296. $.cleanData = function( elems ) {
  297. for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
  298. try {
  299. $( elem ).triggerHandler( "remove" );
  300. // http://bugs.jquery.com/ticket/8235
  301. } catch( e ) {}
  302. }
  303. _cleanData( elems );
  304. };
  305. $.widget = function( name, base, prototype ) {
  306. var fullName, existingConstructor, constructor, basePrototype,
  307. namespace = name.split( "." )[ 0 ];
  308. name = name.split( "." )[ 1 ];
  309. fullName = namespace + "-" + name;
  310. if ( !prototype ) {
  311. prototype = base;
  312. base = $.Widget;
  313. }
  314. // create selector for plugin
  315. $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
  316. return !!$.data( elem, fullName );
  317. };
  318. $[ namespace ] = $[ namespace ] || {};
  319. existingConstructor = $[ namespace ][ name ];
  320. constructor = $[ namespace ][ name ] = function( options, element ) {
  321. // allow instantiation without "new" keyword
  322. if ( !this._createWidget ) {
  323. return new constructor( options, element );
  324. }
  325. // allow instantiation without initializing for simple inheritance
  326. // must use "new" keyword (the code above always passes args)
  327. if ( arguments.length ) {
  328. this._createWidget( options, element );
  329. }
  330. };
  331. // extend with the existing constructor to carry over any static properties
  332. $.extend( constructor, existingConstructor, {
  333. version: prototype.version,
  334. // copy the object used to create the prototype in case we need to
  335. // redefine the widget later
  336. _proto: $.extend( {}, prototype ),
  337. // track widgets that inherit from this widget in case this widget is
  338. // redefined after a widget inherits from it
  339. _childConstructors: []
  340. });
  341. basePrototype = new base();
  342. // we need to make the options hash a property directly on the new instance
  343. // otherwise we'll modify the options hash on the prototype that we're
  344. // inheriting from
  345. basePrototype.options = $.widget.extend( {}, basePrototype.options );
  346. $.each( prototype, function( prop, value ) {
  347. if ( $.isFunction( value ) ) {
  348. prototype[ prop ] = (function() {
  349. var _super = function() {
  350. return base.prototype[ prop ].apply( this, arguments );
  351. },
  352. _superApply = function( args ) {
  353. return base.prototype[ prop ].apply( this, args );
  354. };
  355. return function() {
  356. var __super = this._super,
  357. __superApply = this._superApply,
  358. returnValue;
  359. this._super = _super;
  360. this._superApply = _superApply;
  361. returnValue = value.apply( this, arguments );
  362. this._super = __super;
  363. this._superApply = __superApply;
  364. return returnValue;
  365. };
  366. })();
  367. }
  368. });
  369. constructor.prototype = $.widget.extend( basePrototype, {
  370. // TODO: remove support for widgetEventPrefix
  371. // always use the name + a colon as the prefix, e.g., draggable:start
  372. // don't prefix for widgets that aren't DOM-based
  373. widgetEventPrefix: basePrototype.widgetEventPrefix || name
  374. }, prototype, {
  375. constructor: constructor,
  376. namespace: namespace,
  377. widgetName: name,
  378. // TODO remove widgetBaseClass, see #8155
  379. widgetBaseClass: fullName,
  380. widgetFullName: fullName
  381. });
  382. // If this widget is being redefined then we need to find all widgets that
  383. // are inheriting from it and redefine all of them so that they inherit from
  384. // the new version of this widget. We're essentially trying to replace one
  385. // level in the prototype chain.
  386. if ( existingConstructor ) {
  387. $.each( existingConstructor._childConstructors, function( i, child ) {
  388. var childPrototype = child.prototype;
  389. // redefine the child widget using the same prototype that was
  390. // originally used, but inherit from the new version of the base
  391. $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
  392. });
  393. // remove the list of existing child constructors from the old constructor
  394. // so the old child constructors can be garbage collected
  395. delete existingConstructor._childConstructors;
  396. } else {
  397. base._childConstructors.push( constructor );
  398. }
  399. $.widget.bridge( name, constructor );
  400. };
  401. $.widget.extend = function( target ) {
  402. var input = slice.call( arguments, 1 ),
  403. inputIndex = 0,
  404. inputLength = input.length,
  405. key,
  406. value;
  407. for ( ; inputIndex < inputLength; inputIndex++ ) {
  408. for ( key in input[ inputIndex ] ) {
  409. value = input[ inputIndex ][ key ];
  410. if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
  411. // Clone objects
  412. if ( $.isPlainObject( value ) ) {
  413. target[ key ] = $.isPlainObject( target[ key ] ) ?
  414. $.widget.extend( {}, target[ key ], value ) :
  415. // Don't extend strings, arrays, etc. with objects
  416. $.widget.extend( {}, value );
  417. // Copy everything else by reference
  418. } else {
  419. target[ key ] = value;
  420. }
  421. }
  422. }
  423. }
  424. return target;
  425. };
  426. $.widget.bridge = function( name, object ) {
  427. var fullName = object.prototype.widgetFullName;
  428. $.fn[ name ] = function( options ) {
  429. var isMethodCall = typeof options === "string",
  430. args = slice.call( arguments, 1 ),
  431. returnValue = this;
  432. // allow multiple hashes to be passed on init
  433. options = !isMethodCall && args.length ?
  434. $.widget.extend.apply( null, [ options ].concat(args) ) :
  435. options;
  436. if ( isMethodCall ) {
  437. this.each(function() {
  438. var methodValue,
  439. instance = $.data( this, fullName );
  440. if ( !instance ) {
  441. return $.error( "cannot call methods on " + name + " prior to initialization; " +
  442. "attempted to call method '" + options + "'" );
  443. }
  444. if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
  445. return $.error( "no such method '" + options + "' for " + name + " widget instance" );
  446. }
  447. methodValue = instance[ options ].apply( instance, args );
  448. if ( methodValue !== instance && methodValue !== undefined ) {
  449. returnValue = methodValue && methodValue.jquery ?
  450. returnValue.pushStack( methodValue.get() ) :
  451. methodValue;
  452. return false;
  453. }
  454. });
  455. } else {
  456. this.each(function() {
  457. var instance = $.data( this, fullName );
  458. if ( instance ) {
  459. instance.option( options || {} )._init();
  460. } else {
  461. new object( options, this );
  462. }
  463. });
  464. }
  465. return returnValue;
  466. };
  467. };
  468. $.Widget = function( /* options, element */ ) {};
  469. $.Widget._childConstructors = [];
  470. $.Widget.prototype = {
  471. widgetName: "widget",
  472. widgetEventPrefix: "",
  473. defaultElement: "<div>",
  474. options: {
  475. disabled: false,
  476. // callbacks
  477. create: null
  478. },
  479. _createWidget: function( options, element ) {
  480. element = $( element || this.defaultElement || this )[ 0 ];
  481. this.element = $( element );
  482. this.uuid = uuid++;
  483. this.eventNamespace = "." + this.widgetName + this.uuid;
  484. this.options = $.widget.extend( {},
  485. this.options,
  486. this._getCreateOptions(),
  487. options );
  488. this.bindings = $();
  489. this.hoverable = $();
  490. this.focusable = $();
  491. if ( element !== this ) {
  492. // 1.9 BC for #7810
  493. // TODO remove dual storage
  494. $.data( element, this.widgetName, this );
  495. $.data( element, this.widgetFullName, this );
  496. this._on( this.element, {
  497. remove: function( event ) {
  498. if ( event.target === element ) {
  499. this.destroy();
  500. }
  501. }
  502. });
  503. this.document = $( element.style ?
  504. // element within the document
  505. element.ownerDocument :
  506. // element is window or document
  507. element.document || element );
  508. this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
  509. }
  510. this._create();
  511. this._trigger( "create", null, this._getCreateEventData() );
  512. this._init();
  513. },
  514. _getCreateOptions: $.noop,
  515. _getCreateEventData: $.noop,
  516. _create: $.noop,
  517. _init: $.noop,
  518. destroy: function() {
  519. this._destroy();
  520. // we can probably remove the unbind calls in 2.0
  521. // all event bindings should go through this._on()
  522. this.element
  523. .unbind( this.eventNamespace )
  524. // 1.9 BC for #7810
  525. // TODO remove dual storage
  526. .removeData( this.widgetName )
  527. .removeData( this.widgetFullName )
  528. // support: jquery <1.6.3
  529. // http://bugs.jquery.com/ticket/9413
  530. .removeData( $.camelCase( this.widgetFullName ) );
  531. this.widget()
  532. .unbind( this.eventNamespace )
  533. .removeAttr( "aria-disabled" )
  534. .removeClass(
  535. this.widgetFullName + "-disabled " +
  536. "ui-state-disabled" );
  537. // clean up events and states
  538. this.bindings.unbind( this.eventNamespace );
  539. this.hoverable.removeClass( "ui-state-hover" );
  540. this.focusable.removeClass( "ui-state-focus" );
  541. },
  542. _destroy: $.noop,
  543. widget: function() {
  544. return this.element;
  545. },
  546. option: function( key, value ) {
  547. var options = key,
  548. parts,
  549. curOption,
  550. i;
  551. if ( arguments.length === 0 ) {
  552. // don't return a reference to the internal hash
  553. return $.widget.extend( {}, this.options );
  554. }
  555. if ( typeof key === "string" ) {
  556. // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
  557. options = {};
  558. parts = key.split( "." );
  559. key = parts.shift();
  560. if ( parts.length ) {
  561. curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
  562. for ( i = 0; i < parts.length - 1; i++ ) {
  563. curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
  564. curOption = curOption[ parts[ i ] ];
  565. }
  566. key = parts.pop();
  567. if ( value === undefined ) {
  568. return curOption[ key ] === undefined ? null : curOption[ key ];
  569. }
  570. curOption[ key ] = value;
  571. } else {
  572. if ( value === undefined ) {
  573. return this.options[ key ] === undefined ? null : this.options[ key ];
  574. }
  575. options[ key ] = value;
  576. }
  577. }
  578. this._setOptions( options );
  579. return this;
  580. },
  581. _setOptions: function( options ) {
  582. var key;
  583. for ( key in options ) {
  584. this._setOption( key, options[ key ] );
  585. }
  586. return this;
  587. },
  588. _setOption: function( key, value ) {
  589. this.options[ key ] = value;
  590. if ( key === "disabled" ) {
  591. this.widget()
  592. .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
  593. .attr( "aria-disabled", value );
  594. this.hoverable.removeClass( "ui-state-hover" );
  595. this.focusable.removeClass( "ui-state-focus" );
  596. }
  597. return this;
  598. },
  599. enable: function() {
  600. return this._setOption( "disabled", false );
  601. },
  602. disable: function() {
  603. return this._setOption( "disabled", true );
  604. },
  605. _on: function( element, handlers ) {
  606. var delegateElement,
  607. instance = this;
  608. // no element argument, shuffle and use this.element
  609. if ( !handlers ) {
  610. handlers = element;
  611. element = this.element;
  612. delegateElement = this.widget();
  613. } else {
  614. // accept selectors, DOM elements
  615. element = delegateElement = $( element );
  616. this.bindings = this.bindings.add( element );
  617. }
  618. $.each( handlers, function( event, handler ) {
  619. function handlerProxy() {
  620. // allow widgets to customize the disabled handling
  621. // - disabled as an array instead of boolean
  622. // - disabled class as method for disabling individual parts
  623. if ( instance.options.disabled === true ||
  624. $( this ).hasClass( "ui-state-disabled" ) ) {
  625. return;
  626. }
  627. return ( typeof handler === "string" ? instance[ handler ] : handler )
  628. .apply( instance, arguments );
  629. }
  630. // copy the guid so direct unbinding works
  631. if ( typeof handler !== "string" ) {
  632. handlerProxy.guid = handler.guid =
  633. handler.guid || handlerProxy.guid || $.guid++;
  634. }
  635. var match = event.match( /^(\w+)\s*(.*)$/ ),
  636. eventName = match[1] + instance.eventNamespace,
  637. selector = match[2];
  638. if ( selector ) {
  639. delegateElement.delegate( selector, eventName, handlerProxy );
  640. } else {
  641. element.bind( eventName, handlerProxy );
  642. }
  643. });
  644. },
  645. _off: function( element, eventName ) {
  646. eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
  647. element.unbind( eventName ).undelegate( eventName );
  648. },
  649. _delay: function( handler, delay ) {
  650. function handlerProxy() {
  651. return ( typeof handler === "string" ? instance[ handler ] : handler )
  652. .apply( instance, arguments );
  653. }
  654. var instance = this;
  655. return setTimeout( handlerProxy, delay || 0 );
  656. },
  657. _hoverable: function( element ) {
  658. this.hoverable = this.hoverable.add( element );
  659. this._on( element, {
  660. mouseenter: function( event ) {
  661. $( event.currentTarget ).addClass( "ui-state-hover" );
  662. },
  663. mouseleave: function( event ) {
  664. $( event.currentTarget ).removeClass( "ui-state-hover" );
  665. }
  666. });
  667. },
  668. _focusable: function( element ) {
  669. this.focusable = this.focusable.add( element );
  670. this._on( element, {
  671. focusin: function( event ) {
  672. $( event.currentTarget ).addClass( "ui-state-focus" );
  673. },
  674. focusout: function( event ) {
  675. $( event.currentTarget ).removeClass( "ui-state-focus" );
  676. }
  677. });
  678. },
  679. _trigger: function( type, event, data ) {
  680. var prop, orig,
  681. callback = this.options[ type ];
  682. data = data || {};
  683. event = $.Event( event );
  684. event.type = ( type === this.widgetEventPrefix ?
  685. type :
  686. this.widgetEventPrefix + type ).toLowerCase();
  687. // the original event may come from any element
  688. // so we need to reset the target on the new event
  689. event.target = this.element[ 0 ];
  690. // copy original event properties over to the new event
  691. orig = event.originalEvent;
  692. if ( orig ) {
  693. for ( prop in orig ) {
  694. if ( !( prop in event ) ) {
  695. event[ prop ] = orig[ prop ];
  696. }
  697. }
  698. }
  699. this.element.trigger( event, data );
  700. return !( $.isFunction( callback ) &&
  701. callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
  702. event.isDefaultPrevented() );
  703. }
  704. };
  705. $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
  706. $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
  707. if ( typeof options === "string" ) {
  708. options = { effect: options };
  709. }
  710. var hasOptions,
  711. effectName = !options ?
  712. method :
  713. options === true || typeof options === "number" ?
  714. defaultEffect :
  715. options.effect || defaultEffect;
  716. options = options || {};
  717. if ( typeof options === "number" ) {
  718. options = { duration: options };
  719. }
  720. hasOptions = !$.isEmptyObject( options );
  721. options.complete = callback;
  722. if ( options.delay ) {
  723. element.delay( options.delay );
  724. }
  725. if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) {
  726. element[ method ]( options );
  727. } else if ( effectName !== method && element[ effectName ] ) {
  728. element[ effectName ]( options.duration, options.easing, callback );
  729. } else {
  730. element.queue(function( next ) {
  731. $( this )[ method ]();
  732. if ( callback ) {
  733. callback.call( element[ 0 ] );
  734. }
  735. next();
  736. });
  737. }
  738. };
  739. });
  740. // DEPRECATED
  741. if ( $.uiBackCompat !== false ) {
  742. $.Widget.prototype._getCreateOptions = function() {
  743. return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
  744. };
  745. }
  746. })( jQuery );
  747. (function( $, undefined ) {
  748. var mouseHandled = false;
  749. $( document ).mouseup( function( e ) {
  750. mouseHandled = false;
  751. });
  752. $.widget("ui.mouse", {
  753. version: "1.9.1",
  754. options: {
  755. cancel: 'input,textarea,button,select,option',
  756. distance: 1,
  757. delay: 0
  758. },
  759. _mouseInit: function() {
  760. var that = this;
  761. this.element
  762. .bind('mousedown.'+this.widgetName, function(event) {
  763. return that._mouseDown(event);
  764. })
  765. .bind('click.'+this.widgetName, function(event) {
  766. if (true === $.data(event.target, that.widgetName + '.preventClickEvent')) {
  767. $.removeData(event.target, that.widgetName + '.preventClickEvent');
  768. event.stopImmediatePropagation();
  769. return false;
  770. }
  771. });
  772. this.started = false;
  773. },
  774. // TODO: make sure destroying one instance of mouse doesn't mess with
  775. // other instances of mouse
  776. _mouseDestroy: function() {
  777. this.element.unbind('.'+this.widgetName);
  778. if ( this._mouseMoveDelegate ) {
  779. $(document)
  780. .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
  781. .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
  782. }
  783. },
  784. _mouseDown: function(event) {
  785. // don't let more than one widget handle mouseStart
  786. if( mouseHandled ) { return; }
  787. // we may have missed mouseup (out of window)
  788. (this._mouseStarted && this._mouseUp(event));
  789. this._mouseDownEvent = event;
  790. var that = this,
  791. btnIsLeft = (event.which === 1),
  792. // event.target.nodeName works around a bug in IE 8 with
  793. // disabled inputs (#7620)
  794. elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
  795. if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
  796. return true;
  797. }
  798. this.mouseDelayMet = !this.options.delay;
  799. if (!this.mouseDelayMet) {
  800. this._mouseDelayTimer = setTimeout(function() {
  801. that.mouseDelayMet = true;
  802. }, this.options.delay);
  803. }
  804. if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
  805. this._mouseStarted = (this._mouseStart(event) !== false);
  806. if (!this._mouseStarted) {
  807. event.preventDefault();
  808. return true;
  809. }
  810. }
  811. // Click event may never have fired (Gecko & Opera)
  812. if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) {
  813. $.removeData(event.target, this.widgetName + '.preventClickEvent');
  814. }
  815. // these delegates are required to keep context
  816. this._mouseMoveDelegate = function(event) {
  817. return that._mouseMove(event);
  818. };
  819. this._mouseUpDelegate = function(event) {
  820. return that._mouseUp(event);
  821. };
  822. $(document)
  823. .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
  824. .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
  825. event.preventDefault();
  826. mouseHandled = true;
  827. return true;
  828. },
  829. _mouseMove: function(event) {
  830. // IE mouseup check - mouseup happened when mouse was out of window
  831. if ($.ui.ie && !(document.documentMode >= 9) && !event.button) {
  832. return this._mouseUp(event);
  833. }
  834. if (this._mouseStarted) {
  835. this._mouseDrag(event);
  836. return event.preventDefault();
  837. }
  838. if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
  839. this._mouseStarted =
  840. (this._mouseStart(this._mouseDownEvent, event) !== false);
  841. (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
  842. }
  843. return !this._mouseStarted;
  844. },
  845. _mouseUp: function(event) {
  846. $(document)
  847. .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
  848. .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
  849. if (this._mouseStarted) {
  850. this._mouseStarted = false;
  851. if (event.target === this._mouseDownEvent.target) {
  852. $.data(event.target, this.widgetName + '.preventClickEvent', true);
  853. }
  854. this._mouseStop(event);
  855. }
  856. return false;
  857. },
  858. _mouseDistanceMet: function(event) {
  859. return (Math.max(
  860. Math.abs(this._mouseDownEvent.pageX - event.pageX),
  861. Math.abs(this._mouseDownEvent.pageY - event.pageY)
  862. ) >= this.options.distance
  863. );
  864. },
  865. _mouseDelayMet: function(event) {
  866. return this.mouseDelayMet;
  867. },
  868. // These are placeholder methods, to be overriden by extending plugin
  869. _mouseStart: function(event) {},
  870. _mouseDrag: function(event) {},
  871. _mouseStop: function(event) {},
  872. _mouseCapture: function(event) { return true; }
  873. });
  874. })(jQuery);
  875. (function( $, undefined ) {
  876. $.ui = $.ui || {};
  877. var cachedScrollbarWidth,
  878. max = Math.max,
  879. abs = Math.abs,
  880. round = Math.round,
  881. rhorizontal = /left|center|right/,
  882. rvertical = /top|center|bottom/,
  883. roffset = /[\+\-]\d+%?/,
  884. rposition = /^\w+/,
  885. rpercent = /%$/,
  886. _position = $.fn.position;
  887. function getOffsets( offsets, width, height ) {
  888. return [
  889. parseInt( offsets[ 0 ], 10 ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
  890. parseInt( offsets[ 1 ], 10 ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
  891. ];
  892. }
  893. function parseCss( element, property ) {
  894. return parseInt( $.css( element, property ), 10 ) || 0;
  895. }
  896. $.position = {
  897. scrollbarWidth: function() {
  898. if ( cachedScrollbarWidth !== undefined ) {
  899. return cachedScrollbarWidth;
  900. }
  901. var w1, w2,
  902. div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
  903. innerDiv = div.children()[0];
  904. $( "body" ).append( div );
  905. w1 = innerDiv.offsetWidth;
  906. div.css( "overflow", "scroll" );
  907. w2 = innerDiv.offsetWidth;
  908. if ( w1 === w2 ) {
  909. w2 = div[0].clientWidth;
  910. }
  911. div.remove();
  912. return (cachedScrollbarWidth = w1 - w2);
  913. },
  914. getScrollInfo: function( within ) {
  915. var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ),
  916. overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ),
  917. hasOverflowX = overflowX === "scroll" ||
  918. ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
  919. hasOverflowY = overflowY === "scroll" ||
  920. ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
  921. return {
  922. width: hasOverflowX ? $.position.scrollbarWidth() : 0,
  923. height: hasOverflowY ? $.position.scrollbarWidth() : 0
  924. };
  925. },
  926. getWithinInfo: function( element ) {
  927. var withinElement = $( element || window ),
  928. isWindow = $.isWindow( withinElement[0] );
  929. return {
  930. element: withinElement,
  931. isWindow: isWindow,
  932. offset: withinElement.offset() || { left: 0, top: 0 },
  933. scrollLeft: withinElement.scrollLeft(),
  934. scrollTop: withinElement.scrollTop(),
  935. width: isWindow ? withinElement.width() : withinElement.outerWidth(),
  936. height: isWindow ? withinElement.height() : withinElement.outerHeight()
  937. };
  938. }
  939. };
  940. $.fn.position = function( options ) {
  941. if ( !options || !options.of ) {
  942. return _position.apply( this, arguments );
  943. }
  944. // make a copy, we don't want to modify arguments
  945. options = $.extend( {}, options );
  946. var atOffset, targetWidth, targetHeight, targetOffset, basePosition,
  947. target = $( options.of ),
  948. within = $.position.getWithinInfo( options.within ),
  949. scrollInfo = $.position.getScrollInfo( within ),
  950. targetElem = target[0],
  951. collision = ( options.collision || "flip" ).split( " " ),
  952. offsets = {};
  953. if ( targetElem.nodeType === 9 ) {
  954. targetWidth = target.width();
  955. targetHeight = target.height();
  956. targetOffset = { top: 0, left: 0 };
  957. } else if ( $.isWindow( targetElem ) ) {
  958. targetWidth = target.width();
  959. targetHeight = target.height();
  960. targetOffset = { top: target.scrollTop(), left: target.scrollLeft() };
  961. } else if ( targetElem.preventDefault ) {
  962. // force left top to allow flipping
  963. options.at = "left top";
  964. targetWidth = targetHeight = 0;
  965. targetOffset = { top: targetElem.pageY, left: targetElem.pageX };
  966. } else {
  967. targetWidth = target.outerWidth();
  968. targetHeight = target.outerHeight();
  969. targetOffset = target.offset();
  970. }
  971. // clone to reuse original targetOffset later
  972. basePosition = $.extend( {}, targetOffset );
  973. // force my and at to have valid horizontal and vertical positions
  974. // if a value is missing or invalid, it will be converted to center
  975. $.each( [ "my", "at" ], function() {
  976. var pos = ( options[ this ] || "" ).split( " " ),
  977. horizontalOffset,
  978. verticalOffset;
  979. if ( pos.length === 1) {
  980. pos = rhorizontal.test( pos[ 0 ] ) ?
  981. pos.concat( [ "center" ] ) :
  982. rvertical.test( pos[ 0 ] ) ?
  983. [ "center" ].concat( pos ) :
  984. [ "center", "center" ];
  985. }
  986. pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
  987. pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
  988. // calculate offsets
  989. horizontalOffset = roffset.exec( pos[ 0 ] );
  990. verticalOffset = roffset.exec( pos[ 1 ] );
  991. offsets[ this ] = [
  992. horizontalOffset ? horizontalOffset[ 0 ] : 0,
  993. verticalOffset ? verticalOffset[ 0 ] : 0
  994. ];
  995. // reduce to just the positions without the offsets
  996. options[ this ] = [
  997. rposition.exec( pos[ 0 ] )[ 0 ],
  998. rposition.exec( pos[ 1 ] )[ 0 ]
  999. ];
  1000. });
  1001. // normalize collision option
  1002. if ( collision.length === 1 ) {
  1003. collision[ 1 ] = collision[ 0 ];
  1004. }
  1005. if ( options.at[ 0 ] === "right" ) {
  1006. basePosition.left += targetWidth;
  1007. } else if ( options.at[ 0 ] === "center" ) {
  1008. basePosition.left += targetWidth / 2;
  1009. }
  1010. if ( options.at[ 1 ] === "bottom" ) {
  1011. basePosition.top += targetHeight;
  1012. } else if ( options.at[ 1 ] === "center" ) {
  1013. basePosition.top += targetHeight / 2;
  1014. }
  1015. atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
  1016. basePosition.left += atOffset[ 0 ];
  1017. basePosition.top += atOffset[ 1 ];
  1018. return this.each(function() {
  1019. var collisionPosition, using,
  1020. elem = $( this ),
  1021. elemWidth = elem.outerWidth(),
  1022. elemHeight = elem.outerHeight(),
  1023. marginLeft = parseCss( this, "marginLeft" ),
  1024. marginTop = parseCss( this, "marginTop" ),
  1025. collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
  1026. collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
  1027. position = $.extend( {}, basePosition ),
  1028. myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
  1029. if ( options.my[ 0 ] === "right" ) {
  1030. position.left -= elemWidth;
  1031. } else if ( options.my[ 0 ] === "center" ) {
  1032. position.left -= elemWidth / 2;
  1033. }
  1034. if ( options.my[ 1 ] === "bottom" ) {
  1035. position.top -= elemHeight;
  1036. } else if ( options.my[ 1 ] === "center" ) {
  1037. position.top -= elemHeight / 2;
  1038. }
  1039. position.left += myOffset[ 0 ];
  1040. position.top += myOffset[ 1 ];
  1041. // if the browser doesn't support fractions, then round for consistent results
  1042. if ( !$.support.offsetFractions ) {
  1043. position.left = round( position.left );
  1044. position.top = round( position.top );
  1045. }
  1046. collisionPosition = {
  1047. marginLeft: marginLeft,
  1048. marginTop: marginTop
  1049. };
  1050. $.each( [ "left", "top" ], function( i, dir ) {
  1051. if ( $.ui.position[ collision[ i ] ] ) {
  1052. $.ui.position[ collision[ i ] ][ dir ]( position, {
  1053. targetWidth: targetWidth,
  1054. targetHeight: targetHeight,
  1055. elemWidth: elemWidth,
  1056. elemHeight: elemHeight,
  1057. collisionPosition: collisionPosition,
  1058. collisionWidth: collisionWidth,
  1059. collisionHeight: collisionHeight,
  1060. offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
  1061. my: options.my,
  1062. at: options.at,
  1063. within: within,
  1064. elem : elem
  1065. });
  1066. }
  1067. });
  1068. if ( $.fn.bgiframe ) {
  1069. elem.bgiframe();
  1070. }
  1071. if ( options.using ) {
  1072. // adds feedback as second argument to using callback, if present
  1073. using = function( props ) {
  1074. var left = targetOffset.left - position.left,
  1075. right = left + targetWidth - elemWidth,
  1076. top = targetOffset.top - position.top,
  1077. bottom = top + targetHeight - elemHeight,
  1078. feedback = {
  1079. target: {
  1080. element: target,
  1081. left: targetOffset.left,
  1082. top: targetOffset.top,
  1083. width: targetWidth,
  1084. height: targetHeight
  1085. },
  1086. element: {
  1087. element: elem,
  1088. left: position.left,
  1089. top: position.top,
  1090. width: elemWidth,
  1091. height: elemHeight
  1092. },
  1093. horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
  1094. vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
  1095. };
  1096. if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
  1097. feedback.horizontal = "center";
  1098. }
  1099. if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
  1100. feedback.vertical = "middle";
  1101. }
  1102. if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
  1103. feedback.important = "horizontal";
  1104. } else {
  1105. feedback.important = "vertical";
  1106. }
  1107. options.using.call( this, props, feedback );
  1108. };
  1109. }
  1110. elem.offset( $.extend( position, { using: using } ) );
  1111. });
  1112. };
  1113. $.ui.position = {
  1114. fit: {
  1115. left: function( position, data ) {
  1116. var within = data.within,
  1117. withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
  1118. outerWidth = within.width,
  1119. collisionPosLeft = position.left - data.collisionPosition.marginLeft,
  1120. overLeft = withinOffset - collisionPosLeft,
  1121. overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
  1122. newOverRight;
  1123. // element is wider than within
  1124. if ( data.collisionWidth > outerWidth ) {
  1125. // element is initially over the left side of within
  1126. if ( overLeft > 0 && overRight <= 0 ) {
  1127. newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
  1128. position.left += overLeft - newOverRight;
  1129. // element is initially over right side of within
  1130. } else if ( overRight > 0 && overLeft <= 0 ) {
  1131. position.left = withinOffset;
  1132. // element is initially over both left and right sides of within
  1133. } else {
  1134. if ( overLeft > overRight ) {
  1135. position.left = withinOffset + outerWidth - data.collisionWidth;
  1136. } else {
  1137. position.left = withinOffset;
  1138. }
  1139. }
  1140. // too far left -> align with left edge
  1141. } else if ( overLeft > 0 ) {
  1142. position.left += overLeft;
  1143. // too far right -> align with right edge
  1144. } else if ( overRight > 0 ) {
  1145. position.left -= overRight;
  1146. // adjust based on position and margin
  1147. } else {
  1148. position.left = max( position.left - collisionPosLeft, position.left );
  1149. }
  1150. },
  1151. top: function( position, data ) {
  1152. var within = data.within,
  1153. withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
  1154. outerHeight = data.within.height,
  1155. collisionPosTop = position.top - data.collisionPosition.marginTop,
  1156. overTop = withinOffset - collisionPosTop,
  1157. overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
  1158. newOverBottom;
  1159. // element is taller than within
  1160. if ( data.collisionHeight > outerHeight ) {
  1161. // element is initially over the top of within
  1162. if ( overTop > 0 && overBottom <= 0 ) {
  1163. newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
  1164. position.top += overTop - newOverBottom;
  1165. // element is initially over bottom of within
  1166. } else if ( overBottom > 0 && overTop <= 0 ) {
  1167. position.top = withinOffset;
  1168. // element is initially over both top and bottom of within
  1169. } else {
  1170. if ( overTop > overBottom ) {
  1171. position.top = withinOffset + outerHeight - data.collisionHeight;
  1172. } else {
  1173. position.top = withinOffset;
  1174. }
  1175. }
  1176. // too far up -> align with top
  1177. } else if ( overTop > 0 ) {
  1178. position.top += overTop;
  1179. // too far down -> align with bottom edge
  1180. } else if ( overBottom > 0 ) {
  1181. position.top -= overBottom;
  1182. // adjust based on position and margin
  1183. } else {
  1184. position.top = max( position.top - collisionPosTop, position.top );
  1185. }
  1186. }
  1187. },
  1188. flip: {
  1189. left: function( position, data ) {
  1190. var within = data.within,
  1191. withinOffset = within.offset.left + within.scrollLeft,
  1192. outerWidth = within.width,
  1193. offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
  1194. collisionPosLeft = position.left - data.collisionPosition.marginLeft,
  1195. overLeft = collisionPosLeft - offsetLeft,
  1196. overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
  1197. myOffset = data.my[ 0 ] === "left" ?
  1198. -data.elemWidth :
  1199. data.my[ 0 ] === "right" ?
  1200. data.elemWidth :
  1201. 0,
  1202. atOffset = data.at[ 0 ] === "left" ?
  1203. data.targetWidth :
  1204. data.at[ 0 ] === "right" ?
  1205. -data.targetWidth :
  1206. 0,
  1207. offset = -2 * data.offset[ 0 ],
  1208. newOverRight,
  1209. newOverLeft;
  1210. if ( overLeft < 0 ) {
  1211. newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
  1212. if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
  1213. position.left += myOffset + atOffset + offset;
  1214. }
  1215. }
  1216. else if ( overRight > 0 ) {
  1217. newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
  1218. if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
  1219. position.left += myOffset + atOffset + offset;
  1220. }
  1221. }
  1222. },
  1223. top: function( position, data ) {
  1224. var within = data.within,
  1225. withinOffset = within.offset.top + within.scrollTop,
  1226. outerHeight = within.height,
  1227. offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
  1228. collisionPosTop = position.top - data.collisionPosition.marginTop,
  1229. overTop = collisionPosTop - offsetTop,
  1230. overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
  1231. top = data.my[ 1 ] === "top",
  1232. myOffset = top ?
  1233. -data.elemHeight :
  1234. data.my[ 1 ] === "bottom" ?
  1235. data.elemHeight :
  1236. 0,
  1237. atOffset = data.at[ 1 ] === "top" ?
  1238. data.targetHeight :
  1239. data.at[ 1 ] === "bottom" ?
  1240. -data.targetHeight :
  1241. 0,
  1242. offset = -2 * data.offset[ 1 ],
  1243. newOverTop,
  1244. newOverBottom;
  1245. if ( overTop < 0 ) {
  1246. newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
  1247. if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
  1248. position.top += myOffset + atOffset + offset;
  1249. }
  1250. }
  1251. else if ( overBottom > 0 ) {
  1252. newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
  1253. if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
  1254. position.top += myOffset + atOffset + offset;
  1255. }
  1256. }
  1257. }
  1258. },
  1259. flipfit: {
  1260. left: function() {
  1261. $.ui.position.flip.left.apply( this, arguments );
  1262. $.ui.position.fit.left.apply( this, arguments );
  1263. },
  1264. top: function() {
  1265. $.ui.position.flip.top.apply( this, arguments );
  1266. $.ui.position.fit.top.apply( this, arguments );
  1267. }
  1268. }
  1269. };
  1270. // fraction support test
  1271. (function () {
  1272. var testElement, testElementParent, testElementStyle, offsetLeft, i,
  1273. body = document.getElementsByTagName( "body" )[ 0 ],
  1274. div = document.createElement( "div" );
  1275. //Create a "fake body" for testing based on method used in jQuery.support
  1276. testElement = document.createElement( body ? "div" : "body" );
  1277. testElementStyle = {
  1278. visibility: "hidden",
  1279. width: 0,
  1280. height: 0,
  1281. border: 0,
  1282. margin: 0,
  1283. background: "none"
  1284. };
  1285. if ( body ) {
  1286. $.extend( testElementStyle, {
  1287. position: "absolute",
  1288. left: "-1000px",
  1289. top: "-1000px"
  1290. });
  1291. }
  1292. for ( i in testElementStyle ) {
  1293. testElement.style[ i ] = testElementStyle[ i ];
  1294. }
  1295. testElement.appendChild( div );
  1296. testElementParent = body || document.documentElement;
  1297. testElementParent.insertBefore( testElement, testElementParent.firstChild );
  1298. div.style.cssText = "position: absolute; left: 10.7432222px;";
  1299. offsetLeft = $( div ).offset().left;
  1300. $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
  1301. testElement.innerHTML = "";
  1302. testElementParent.removeChild( testElement );
  1303. })();
  1304. // DEPRECATED
  1305. if ( $.uiBackCompat !== false ) {
  1306. // offset option
  1307. (function( $ ) {
  1308. var _position = $.fn.position;
  1309. $.fn.position = function( options ) {
  1310. if ( !options || !options.offset ) {
  1311. return _position.call( this, options );
  1312. }
  1313. var offset = options.offset.split( " " ),
  1314. at = options.at.split( " " );
  1315. if ( offset.length === 1 ) {
  1316. offset[ 1 ] = offset[ 0 ];
  1317. }
  1318. if ( /^\d/.test( offset[ 0 ] ) ) {
  1319. offset[ 0 ] = "+" + offset[ 0 ];
  1320. }
  1321. if ( /^\d/.test( offset[ 1 ] ) ) {
  1322. offset[ 1 ] = "+" + offset[ 1 ];
  1323. }
  1324. if ( at.length === 1 ) {
  1325. if ( /left|center|right/.test( at[ 0 ] ) ) {
  1326. at[ 1 ] = "center";
  1327. } else {
  1328. at[ 1 ] = at[ 0 ];
  1329. at[ 0 ] = "center";
  1330. }
  1331. }
  1332. return _position.call( this, $.extend( options, {
  1333. at: at[ 0 ] + offset[ 0 ] + " " + at[ 1 ] + offset[ 1 ],
  1334. offset: undefined
  1335. } ) );
  1336. };
  1337. }( jQuery ) );
  1338. }
  1339. }( jQuery ) );
  1340. (function( $, undefined ) {
  1341. $.widget("ui.draggable", $.ui.mouse, {
  1342. version: "1.9.1",
  1343. widgetEventPrefix: "drag",
  1344. options: {
  1345. addClasses: true,
  1346. appendTo: "parent",
  1347. axis: false,
  1348. connectToSortable: false,
  1349. containment: false,
  1350. cursor: "auto",
  1351. cursorAt: false,
  1352. grid: false,
  1353. handle: false,
  1354. helper: "original",
  1355. iframeFix: false,
  1356. opacity: false,
  1357. refreshPositions: false,
  1358. revert: false,
  1359. revertDuration: 500,
  1360. scope: "default",
  1361. scroll: true,
  1362. scrollSensitivity: 20,
  1363. scrollSpeed: 20,
  1364. snap: false,
  1365. snapMode: "both",
  1366. snapTolerance: 20,
  1367. stack: false,
  1368. zIndex: false
  1369. },
  1370. _create: function() {
  1371. if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
  1372. this.element[0].style.position = 'relative';
  1373. (this.options.addClasses && this.element.addClass("ui-draggable"));
  1374. (this.options.disabled && this.element.addClass("ui-draggable-disabled"));
  1375. this._mouseInit();
  1376. },
  1377. _destroy: function() {
  1378. this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
  1379. this._mouseDestroy();
  1380. },
  1381. _mouseCapture: function(event) {
  1382. var o = this.options;
  1383. // among others, prevent a drag on a resizable-handle
  1384. if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
  1385. return false;
  1386. //Quit if we're not on a valid handle
  1387. this.handle = this._getHandle(event);
  1388. if (!this.handle)
  1389. return false;
  1390. $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
  1391. $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
  1392. .css({
  1393. width: this.offsetWidth+"px", height: this.offsetHeight+"px",
  1394. position: "absolute", opacity: "0.001", zIndex: 1000
  1395. })
  1396. .css($(this).offset())
  1397. .appendTo("body");
  1398. });
  1399. return true;
  1400. },
  1401. _mouseStart: function(event) {
  1402. var o = this.options;
  1403. //Create and append the visible helper
  1404. this.helper = this._createHelper(event);
  1405. this.helper.addClass("ui-draggable-dragging");
  1406. //Cache the helper size
  1407. this._cacheHelperProportions();
  1408. //If ddmanager is used for droppables, set the global draggable
  1409. if($.ui.ddmanager)
  1410. $.ui.ddmanager.current = this;
  1411. /*
  1412. * - Position generation -
  1413. * This block generates everything position related - it's the core of draggables.
  1414. */
  1415. //Cache the margins of the original element
  1416. this._cacheMargins();
  1417. //Store the helper's css position
  1418. this.cssPosition = this.helper.css("position");
  1419. this.scrollParent = this.helper.scrollParent();
  1420. //The element's absolute position on the page minus margins
  1421. this.offset = this.positionAbs = this.element.offset();
  1422. this.offset = {
  1423. top: this.offset.top - this.margins.top,
  1424. left: this.offset.left - this.margins.left
  1425. };
  1426. $.extend(this.offset, {
  1427. click: { //Where the click happened, relative to the element
  1428. left: event.pageX - this.offset.left,
  1429. top: event.pageY - this.offset.top
  1430. },
  1431. parent: this._getParentOffset(),
  1432. relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
  1433. });
  1434. //Generate the original position
  1435. this.originalPosition = this.position = this._generatePosition(event);
  1436. this.originalPageX = event.pageX;
  1437. this.originalPageY = event.pageY;
  1438. //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
  1439. (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
  1440. //Set a containment if given in the options
  1441. if(o.containment)
  1442. this._setContainment();
  1443. //Trigger event + callbacks
  1444. if(this._trigger("start", event) === false) {
  1445. this._clear();
  1446. return false;
  1447. }
  1448. //Recache the helper size
  1449. this._cacheHelperProportions();
  1450. //Prepare the droppable offsets
  1451. if ($.ui.ddmanager && !o.dropBehaviour)
  1452. $.ui.ddmanager.prepareOffsets(this, event);
  1453. this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
  1454. //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
  1455. if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event);
  1456. return true;
  1457. },
  1458. _mouseDrag: function(event, noPropagation) {
  1459. //Compute the helpers position
  1460. this.position = this._generatePosition(event);
  1461. this.positionAbs = this._convertPositionTo("absolute");
  1462. //Call plugins and callbacks and use the resulting position if something is returned
  1463. if (!noPropagation) {
  1464. var ui = this._uiHash();
  1465. if(this._trigger('drag', event, ui) === false) {
  1466. this._mouseUp({});
  1467. return false;
  1468. }
  1469. this.position = ui.position;
  1470. }
  1471. if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
  1472. if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
  1473. if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
  1474. return false;
  1475. },
  1476. _mouseStop: function(event) {
  1477. //If we are using droppables, inform the manager about the drop
  1478. var dropped = false;
  1479. if ($.ui.ddmanager && !this.options.dropBehaviour)
  1480. dropped = $.ui.ddmanager.drop(this, event);
  1481. //if a drop comes from outside (a sortable)
  1482. if(this.dropped) {
  1483. dropped = this.dropped;
  1484. this.dropped = false;
  1485. }
  1486. //if the original element is no longer in the DOM don't bother to continue (see #8269)
  1487. var element = this.element[0], elementInDom = false;
  1488. while ( element && (element = element.parentNode) ) {
  1489. if (element == document ) {
  1490. elementInDom = true;
  1491. }
  1492. }
  1493. if ( !elementInDom && this.options.helper === "original" )
  1494. return false;
  1495. 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))) {
  1496. var that = this;
  1497. $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
  1498. if(that._trigger("stop", event) !== false) {
  1499. that._clear();
  1500. }
  1501. });
  1502. } else {
  1503. if(this._trigger("stop", event) !== false) {
  1504. this._clear();
  1505. }
  1506. }
  1507. return false;
  1508. },
  1509. _mouseUp: function(event) {
  1510. //Remove frame helpers
  1511. $("div.ui-draggable-iframeFix").each(function() {
  1512. this.parentNode.removeChild(this);
  1513. });
  1514. //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
  1515. if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event);
  1516. return $.ui.mouse.prototype._mouseUp.call(this, event);
  1517. },
  1518. cancel: function() {
  1519. if(this.helper.is(".ui-draggable-dragging")) {
  1520. this._mouseUp({});
  1521. } else {
  1522. this._clear();
  1523. }
  1524. return this;
  1525. },
  1526. _getHandle: function(event) {
  1527. var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
  1528. $(this.options.handle, this.element)
  1529. .find("*")
  1530. .andSelf()
  1531. .each(function() {
  1532. if(this == event.target) handle = true;
  1533. });
  1534. return handle;
  1535. },
  1536. _createHelper: function(event) {
  1537. var o = this.options;
  1538. var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element);
  1539. if(!helper.parents('body').length)
  1540. helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
  1541. if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
  1542. helper.css("position", "absolute");
  1543. return helper;
  1544. },
  1545. _adjustOffsetFromHelper: function(obj) {
  1546. if (typeof obj == 'string') {
  1547. obj = obj.split(' ');
  1548. }
  1549. if ($.isArray(obj)) {
  1550. obj = {left: +obj[0], top: +obj[1] || 0};
  1551. }
  1552. if ('left' in obj) {
  1553. this.offset.click.left = obj.left + this.margins.left;
  1554. }
  1555. if ('right' in obj) {
  1556. this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
  1557. }
  1558. if ('top' in obj) {
  1559. this.offset.click.top = obj.top + this.margins.top;
  1560. }
  1561. if ('bottom' in obj) {
  1562. this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
  1563. }
  1564. },
  1565. _getParentOffset: function() {
  1566. //Get the offsetParent and cache its position
  1567. this.offsetParent = this.helper.offsetParent();
  1568. var po = this.offsetParent.offset();
  1569. // This is a special case where we need to modify a offset calculated on start, since the following happened:
  1570. // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
  1571. // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
  1572. // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
  1573. if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
  1574. po.left += this.scrollParent.scrollLeft();
  1575. po.top += this.scrollParent.scrollTop();
  1576. }
  1577. if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
  1578. || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix
  1579. po = { top: 0, left: 0 };
  1580. return {
  1581. top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
  1582. left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
  1583. };
  1584. },
  1585. _getRelativeOffset: function() {
  1586. if(this.cssPosition == "relative") {
  1587. var p = this.element.position();
  1588. return {
  1589. top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
  1590. left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
  1591. };
  1592. } else {
  1593. return { top: 0, left: 0 };
  1594. }
  1595. },
  1596. _cacheMargins: function() {
  1597. this.margins = {
  1598. left: (parseInt(this.element.css("marginLeft"),10) || 0),
  1599. top: (parseInt(this.element.css("marginTop"),10) || 0),
  1600. right: (parseInt(this.element.css("marginRight"),10) || 0),
  1601. bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
  1602. };
  1603. },
  1604. _cacheHelperProportions: function() {
  1605. this.helperProportions = {
  1606. width: this.helper.outerWidth(),
  1607. height: this.helper.outerHeight()
  1608. };
  1609. },
  1610. _setContainment: function() {
  1611. var o = this.options;
  1612. if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
  1613. if(o.containment == 'document' || o.containment == 'window') this.containment = [
  1614. o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
  1615. o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
  1616. (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
  1617. (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
  1618. ];
  1619. if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
  1620. var c = $(o.containment);
  1621. var ce = c[0]; if(!ce) return;
  1622. var co = c.offset();
  1623. var over = ($(ce).css("overflow") != 'hidden');
  1624. this.containment = [
  1625. (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
  1626. (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
  1627. (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 - this.margins.right,
  1628. (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 - this.margins.bottom
  1629. ];
  1630. this.relative_container = c;
  1631. } else if(o.containment.constructor == Array) {
  1632. this.containment = o.containment;
  1633. }
  1634. },
  1635. _convertPositionTo: function(d, pos) {
  1636. if(!pos) pos = this.position;
  1637. var mod = d == "absolute" ? 1 : -1;
  1638. var o = this.options, 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);
  1639. return {
  1640. top: (
  1641. pos.top // The absolute mouse position
  1642. + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
  1643. + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
  1644. - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
  1645. ),
  1646. left: (
  1647. pos.left // The absolute mouse position
  1648. + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
  1649. + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
  1650. - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
  1651. )
  1652. };
  1653. },
  1654. _generatePosition: function(event) {
  1655. var o = this.options, 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);
  1656. var pageX = event.pageX;
  1657. var pageY = event.pageY;
  1658. /*
  1659. * - Position constraining -
  1660. * Constrain the position to a mix of grid, containment.
  1661. */
  1662. if(this.originalPosition) { //If we are not dragging yet, we won't check for options
  1663. var containment;
  1664. if(this.containment) {
  1665. if (this.relative_container){
  1666. var co = this.relative_container.offset();
  1667. containment = [ this.containment[0] + co.left,
  1668. this.containment[1] + co.top,
  1669. this.containment[2] + co.left,
  1670. this.containment[3] + co.top ];
  1671. }
  1672. else {
  1673. containment = this.containment;
  1674. }
  1675. if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left;
  1676. if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top;
  1677. if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left;
  1678. if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top;
  1679. }
  1680. if(o.grid) {
  1681. //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
  1682. var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
  1683. 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;
  1684. var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
  1685. 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;
  1686. }
  1687. }
  1688. return {
  1689. top: (
  1690. pageY // The absolute mouse position
  1691. - this.offset.click.top // Click offset (relative to the element)
  1692. - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
  1693. - this.offset.parent.top // The offsetParent's offset without borders (offset + border)
  1694. + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
  1695. ),
  1696. left: (
  1697. pageX // The absolute mouse position
  1698. - this.offset.click.left // Click offset (relative to the element)
  1699. - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
  1700. - this.offset.parent.left // The offsetParent's offset without borders (offset + border)
  1701. + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
  1702. )
  1703. };
  1704. },
  1705. _clear: function() {
  1706. this.helper.removeClass("ui-draggable-dragging");
  1707. if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
  1708. //if($.ui.ddmanager) $.ui.ddmanager.current = null;
  1709. this.helper = null;
  1710. this.cancelHelperRemoval = false;
  1711. },
  1712. // From now on bulk stuff - mainly helpers
  1713. _trigger: function(type, event, ui) {
  1714. ui = ui || this._uiHash();
  1715. $.ui.plugin.call(this, type, [event, ui]);
  1716. if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
  1717. return $.Widget.prototype._trigger.call(this, type, event, ui);
  1718. },
  1719. plugins: {},
  1720. _uiHash: function(event) {
  1721. return {
  1722. helper: this.helper,
  1723. position: this.position,
  1724. originalPosition: this.originalPosition,
  1725. offset: this.positionAbs
  1726. };
  1727. }
  1728. });
  1729. $.ui.plugin.add("draggable", "connectToSortable", {
  1730. start: function(event, ui) {
  1731. var inst = $(this).data("draggable"), o = inst.options,
  1732. uiSortable = $.extend({}, ui, { item: inst.element });
  1733. inst.sortables = [];
  1734. $(o.connectToSortable).each(function() {
  1735. var sortable = $.data(this, 'sortable');
  1736. if (sortable && !sortable.options.disabled) {
  1737. inst.sortables.push({
  1738. instance: sortable,
  1739. shouldRevert: sortable.options.revert
  1740. });
  1741. 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).
  1742. sortable._trigger("activate", event, uiSortable);
  1743. }
  1744. });
  1745. },
  1746. stop: function(event, ui) {
  1747. //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
  1748. var inst = $(this).data("draggable"),
  1749. uiSortable = $.extend({}, ui, { item: inst.element });
  1750. $.each(inst.sortables, function() {
  1751. if(this.instance.isOver) {
  1752. this.instance.isOver = 0;
  1753. inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
  1754. this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
  1755. //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
  1756. if(this.shouldRevert) this.instance.options.revert = true;
  1757. //Trigger the stop of the sortable
  1758. this.instance._mouseStop(event);
  1759. this.instance.options.helper = this.instance.options._helper;
  1760. //If the helper has been the original item, restore properties in the sortable
  1761. if(inst.options.helper == 'original')
  1762. this.instance.currentItem.css({ top: 'auto', left: 'auto' });
  1763. } else {
  1764. this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
  1765. this.instance._trigger("deactivate", event, uiSortable);
  1766. }
  1767. });
  1768. },
  1769. drag: function(event, ui) {
  1770. var inst = $(this).data("draggable"), that = this;
  1771. var checkPos = function(o) {
  1772. var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
  1773. var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
  1774. var itemHeight = o.height, itemWidth = o.width;
  1775. var itemTop = o.top, itemLeft = o.left;
  1776. return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
  1777. };
  1778. $.each(inst.sortables, function(i) {
  1779. var innermostIntersecting = false;
  1780. var thisSortable = this;
  1781. //Copy over some variables to allow calling the sortable's native _intersectsWith
  1782. this.instance.positionAbs = inst.positionAbs;
  1783. this.instance.helperProportions = inst.helperProportions;
  1784. this.instance.offset.click = inst.offset.click;
  1785. if(this.instance._intersectsWith(this.instance.containerCache)) {
  1786. innermostIntersecting = true;
  1787. $.each(inst.sortables, function () {
  1788. this.instance.positionAbs = inst.positionAbs;
  1789. this.instance.helperProportions = inst.helperProportions;
  1790. this.instance.offset.click = inst.offset.click;
  1791. if (this != thisSortable
  1792. && this.instance._intersectsWith(this.instance.containerCache)
  1793. && $.ui.contains(thisSortable.instance.element[0], this.instance.element[0]))
  1794. innermostIntersecting = false;
  1795. return innermostIntersecting;
  1796. });
  1797. }
  1798. if(innermostIntersecting) {
  1799. //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
  1800. if(!this.instance.isOver) {
  1801. this.instance.isOver = 1;
  1802. //Now we fake the start of dragging for the sortable instance,
  1803. //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
  1804. //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)
  1805. this.instance.currentItem = $(that).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true);
  1806. this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
  1807. this.instance.options.helper = function() { return ui.helper[0]; };
  1808. event.target = this.instance.currentItem[0];
  1809. this.instance._mouseCapture(event, true);
  1810. this.instance._mouseStart(event, true, true);
  1811. //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
  1812. this.instance.offset.click.top = inst.offset.click.top;
  1813. this.instance.offset.click.left = inst.offset.click.left;
  1814. this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
  1815. this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
  1816. inst._trigger("toSortable", event);
  1817. inst.dropped = this.instance.element; //draggable revert needs that
  1818. //hack so receive/update callbacks work (mostly)
  1819. inst.currentItem = inst.element;
  1820. this.instance.fromOutside = inst;
  1821. }
  1822. //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
  1823. if(this.instance.currentItem) this.instance._mouseDrag(event);
  1824. } else {
  1825. //If it doesn't intersect with the sortable, and it intersected before,
  1826. //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
  1827. if(this.instance.isOver) {
  1828. this.instance.isOver = 0;
  1829. this.instance.cancelHelperRemoval = true;
  1830. //Prevent reverting on this forced stop
  1831. this.instance.options.revert = false;
  1832. // The out event needs to be triggered independently
  1833. this.instance._trigger('out', event, this.instance._uiHash(this.instance));
  1834. this.instance._mouseStop(event, true);
  1835. this.instance.options.helper = this.instance.options._helper;
  1836. //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
  1837. this.instance.currentItem.remove();
  1838. if(this.instance.placeholder) this.instance.placeholder.remove();
  1839. inst._trigger("fromSortable", event);
  1840. inst.dropped = false; //draggable revert needs that
  1841. }
  1842. };
  1843. });
  1844. }
  1845. });
  1846. $.ui.plugin.add("draggable", "cursor", {
  1847. start: function(event, ui) {
  1848. var t = $('body'), o = $(this).data('draggable').options;
  1849. if (t.css("cursor")) o._cursor = t.css("cursor");
  1850. t.css("cursor", o.cursor);
  1851. },
  1852. stop: function(event, ui) {
  1853. var o = $(this).data('draggable').options;
  1854. if (o._cursor) $('body').css("cursor", o._cursor);
  1855. }
  1856. });
  1857. $.ui.plugin.add("draggable", "opacity", {
  1858. start: function(event, ui) {
  1859. var t = $(ui.helper), o = $(this).data('draggable').options;
  1860. if(t.css("opacity")) o._opacity = t.css("opacity");
  1861. t.css('opacity', o.opacity);
  1862. },
  1863. stop: function(event, ui) {
  1864. var o = $(this).data('draggable').options;
  1865. if(o._opacity) $(ui.helper).css('opacity', o._opacity);
  1866. }
  1867. });
  1868. $.ui.plugin.add("draggable", "scroll", {
  1869. start: function(event, ui) {
  1870. var i = $(this).data("draggable");
  1871. if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
  1872. },
  1873. drag: function(event, ui) {
  1874. var i = $(this).data("draggable"), o = i.options, scrolled = false;
  1875. if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
  1876. if(!o.axis || o.axis != 'x') {
  1877. if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
  1878. i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
  1879. else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
  1880. i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
  1881. }
  1882. if(!o.axis || o.axis != 'y') {
  1883. if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
  1884. i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
  1885. else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
  1886. i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
  1887. }
  1888. } else {
  1889. if(!o.axis || o.axis != 'x') {
  1890. if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
  1891. scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
  1892. else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
  1893. scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
  1894. }
  1895. if(!o.axis || o.axis != 'y') {
  1896. if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
  1897. scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
  1898. else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
  1899. scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
  1900. }
  1901. }
  1902. if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
  1903. $.ui.ddmanager.prepareOffsets(i, event);
  1904. }
  1905. });
  1906. $.ui.plugin.add("draggable", "snap", {
  1907. start: function(event, ui) {
  1908. var i = $(this).data("draggable"), o = i.options;
  1909. i.snapElements = [];
  1910. $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
  1911. var $t = $(this); var $o = $t.offset();
  1912. if(this != i.element[0]) i.snapElements.push({
  1913. item: this,
  1914. width: $t.outerWidth(), height: $t.outerHeight(),
  1915. top: $o.top, left: $o.left
  1916. });
  1917. });
  1918. },
  1919. drag: function(event, ui) {
  1920. var inst = $(this).data("draggable"), o = inst.options;
  1921. var d = o.snapTolerance;
  1922. var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
  1923. y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
  1924. for (var i = inst.snapElements.length - 1; i >= 0; i--){
  1925. var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
  1926. t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
  1927. //Yes, I know, this is insane ;)
  1928. if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
  1929. if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
  1930. inst.snapElements[i].snapping = false;
  1931. continue;
  1932. }
  1933. if(o.snapMode != 'inner') {
  1934. var ts = Math.abs(t - y2) <= d;
  1935. var bs = Math.abs(b - y1) <= d;
  1936. var ls = Math.abs(l - x2) <= d;
  1937. var rs = Math.abs(r - x1) <= d;
  1938. if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
  1939. if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
  1940. if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
  1941. if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
  1942. }
  1943. var first = (ts || bs || ls || rs);
  1944. if(o.snapMode != 'outer') {
  1945. var ts = Math.abs(t - y1) <= d;
  1946. var bs = Math.abs(b - y2) <= d;
  1947. var ls = Math.abs(l - x1) <= d;
  1948. var rs = Math.abs(r - x2) <= d;
  1949. if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
  1950. if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
  1951. if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
  1952. if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
  1953. }
  1954. if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
  1955. (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
  1956. inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
  1957. };
  1958. }
  1959. });
  1960. $.ui.plugin.add("draggable", "stack", {
  1961. start: function(event, ui) {
  1962. var o = $(this).data("draggable").options;
  1963. var group = $.makeArray($(o.stack)).sort(function(a,b) {
  1964. return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
  1965. });
  1966. if (!group.length) { return; }
  1967. var min = parseInt(group[0].style.zIndex) || 0;
  1968. $(group).each(function(i) {
  1969. this.style.zIndex = min + i;
  1970. });
  1971. this[0].style.zIndex = min + group.length;
  1972. }
  1973. });
  1974. $.ui.plugin.add("draggable", "zIndex", {
  1975. start: function(event, ui) {
  1976. var t = $(ui.helper), o = $(this).data("draggable").options;
  1977. if(t.css("zIndex")) o._zIndex = t.css("zIndex");
  1978. t.css('zIndex', o.zIndex);
  1979. },
  1980. stop: function(event, ui) {
  1981. var o = $(this).data("draggable").options;
  1982. if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
  1983. }
  1984. });
  1985. })(jQuery);
  1986. (function( $, undefined ) {
  1987. $.widget("ui.droppable", {
  1988. version: "1.9.1",
  1989. widgetEventPrefix: "drop",
  1990. options: {
  1991. accept: '*',
  1992. activeClass: false,
  1993. addClasses: true,
  1994. greedy: false,
  1995. hoverClass: false,
  1996. scope: 'default',
  1997. tolerance: 'intersect'
  1998. },
  1999. _create: function() {
  2000. var o = this.options, accept = o.accept;
  2001. this.isover = 0; this.isout = 1;
  2002. this.accept = $.isFunction(accept) ? accept : function(d) {
  2003. return d.is(accept);
  2004. };
  2005. //Store the droppable's proportions
  2006. this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
  2007. // Add the reference and positions to the manager
  2008. $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
  2009. $.ui.ddmanager.droppables[o.scope].push(this);
  2010. (o.addClasses && this.element.addClass("ui-droppable"));
  2011. },
  2012. _destroy: function() {
  2013. var drop = $.ui.ddmanager.droppables[this.options.scope];
  2014. for ( var i = 0; i < drop.length; i++ )
  2015. if ( drop[i] == this )
  2016. drop.splice(i, 1);
  2017. this.element.removeClass("ui-droppable ui-droppable-disabled");
  2018. },
  2019. _setOption: function(key, value) {
  2020. if(key == 'accept') {
  2021. this.accept = $.isFunction(value) ? value : function(d) {
  2022. return d.is(value);
  2023. };
  2024. }
  2025. $.Widget.prototype._setOption.apply(this, arguments);
  2026. },
  2027. _activate: function(event) {
  2028. var draggable = $.ui.ddmanager.current;
  2029. if(this.options.activeClass) this.element.addClass(this.options.activeClass);
  2030. (draggable && this._trigger('activate', event, this.ui(draggable)));
  2031. },
  2032. _deactivate: function(event) {
  2033. var draggable = $.ui.ddmanager.current;
  2034. if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
  2035. (draggable && this._trigger('deactivate', event, this.ui(draggable)));
  2036. },
  2037. _over: function(event) {
  2038. var draggable = $.ui.ddmanager.current;
  2039. if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
  2040. if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
  2041. if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
  2042. this._trigger('over', event, this.ui(draggable));
  2043. }
  2044. },
  2045. _out: function(event) {
  2046. var draggable = $.ui.ddmanager.current;
  2047. if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
  2048. if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
  2049. if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
  2050. this._trigger('out', event, this.ui(draggable));
  2051. }
  2052. },
  2053. _drop: function(event,custom) {
  2054. var draggable = custom || $.ui.ddmanager.current;
  2055. if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
  2056. var childrenIntersection = false;
  2057. this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
  2058. var inst = $.data(this, 'droppable');
  2059. if(
  2060. inst.options.greedy
  2061. && !inst.options.disabled
  2062. && inst.options.scope == draggable.options.scope
  2063. && inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element))
  2064. && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
  2065. ) { childrenIntersection = true; return false; }
  2066. });
  2067. if(childrenIntersection) return false;
  2068. if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
  2069. if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
  2070. if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
  2071. this._trigger('drop', event, this.ui(draggable));
  2072. return this.element;
  2073. }
  2074. return false;
  2075. },
  2076. ui: function(c) {
  2077. return {
  2078. draggable: (c.currentItem || c.element),
  2079. helper: c.helper,
  2080. position: c.position,
  2081. offset: c.positionAbs
  2082. };
  2083. }
  2084. });
  2085. $.ui.intersect = function(draggable, droppable, toleranceMode) {
  2086. if (!droppable.offset) return false;
  2087. var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
  2088. y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
  2089. var l = droppable.offset.left, r = l + droppable.proportions.width,
  2090. t = droppable.offset.top, b = t + droppable.proportions.height;
  2091. switch (toleranceMode) {
  2092. case 'fit':
  2093. return (l <= x1 && x2 <= r
  2094. && t <= y1 && y2 <= b);
  2095. break;
  2096. case 'intersect':
  2097. return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
  2098. && x2 - (draggable.helperProportions.width / 2) < r // Left Half
  2099. && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
  2100. && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
  2101. break;
  2102. case 'pointer':
  2103. var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
  2104. draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
  2105. isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
  2106. return isOver;
  2107. break;
  2108. case 'touch':
  2109. return (
  2110. (y1 >= t && y1 <= b) || // Top edge touching
  2111. (y2 >= t && y2 <= b) || // Bottom edge touching
  2112. (y1 < t && y2 > b) // Surrounded vertically
  2113. ) && (
  2114. (x1 >= l && x1 <= r) || // Left edge touching
  2115. (x2 >= l && x2 <= r) || // Right edge touching
  2116. (x1 < l && x2 > r) // Surrounded horizontally
  2117. );
  2118. break;
  2119. default:
  2120. return false;
  2121. break;
  2122. }
  2123. };
  2124. /*
  2125. This manager tracks offsets of draggables and droppables
  2126. */
  2127. $.ui.ddmanager = {
  2128. current: null,
  2129. droppables: { 'default': [] },
  2130. prepareOffsets: function(t, event) {
  2131. var m = $.ui.ddmanager.droppables[t.options.scope] || [];
  2132. var type = event ? event.type : null; // workaround for #2317
  2133. var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
  2134. droppablesLoop: for (var i = 0; i < m.length; i++) {
  2135. if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue; //No disabled and non-accepted
  2136. for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item
  2137. m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue
  2138. if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
  2139. m[i].offset = m[i].element.offset();
  2140. m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
  2141. }
  2142. },
  2143. drop: function(draggable, event) {
  2144. var dropped = false;
  2145. $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
  2146. if(!this.options) return;
  2147. if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
  2148. dropped = this._drop.call(this, event) || dropped;
  2149. if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
  2150. this.isout = 1; this.isover = 0;
  2151. this._deactivate.call(this, event);
  2152. }
  2153. });
  2154. return dropped;
  2155. },
  2156. dragStart: function( draggable, event ) {
  2157. //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
  2158. draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
  2159. if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
  2160. });
  2161. },
  2162. drag: function(draggable, event) {
  2163. //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
  2164. if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);
  2165. //Run through all droppables and check their positions based on specific tolerance options
  2166. $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
  2167. if(this.options.disabled || this.greedyChild || !this.visible) return;
  2168. var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
  2169. var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
  2170. if(!c) return;
  2171. var parentInstance;
  2172. if (this.options.greedy) {
  2173. // find droppable parents with same scope
  2174. var scope = this.options.scope;
  2175. var parent = this.element.parents(':data(droppable)').filter(function () {
  2176. return $.data(this, 'droppable').options.scope === scope;
  2177. });
  2178. if (parent.length) {
  2179. parentInstance = $.data(parent[0], 'droppable');
  2180. parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
  2181. }
  2182. }
  2183. // we just moved into a greedy child
  2184. if (parentInstance && c == 'isover') {
  2185. parentInstance['isover'] = 0;
  2186. parentInstance['isout'] = 1;
  2187. parentInstance._out.call(parentInstance, event);
  2188. }
  2189. this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
  2190. this[c == "isover" ? "_over" : "_out"].call(this, event);
  2191. // we just moved out of a greedy child
  2192. if (parentInstance && c == 'isout') {
  2193. parentInstance['isout'] = 0;
  2194. parentInstance['isover'] = 1;
  2195. parentInstance._over.call(parentInstance, event);
  2196. }
  2197. });
  2198. },
  2199. dragStop: function( draggable, event ) {
  2200. draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
  2201. //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
  2202. if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
  2203. }
  2204. };
  2205. })(jQuery);
  2206. (function( $, undefined ) {
  2207. $.widget("ui.resizable", $.ui.mouse, {
  2208. version: "1.9.1",
  2209. widgetEventPrefix: "resize",
  2210. options: {
  2211. alsoResize: false,
  2212. animate: false,
  2213. animateDuration: "slow",
  2214. animateEasing: "swing",
  2215. aspectRatio: false,
  2216. autoHide: false,
  2217. containment: false,
  2218. ghost: false,
  2219. grid: false,
  2220. handles: "e,s,se",
  2221. helper: false,
  2222. maxHeight: null,
  2223. maxWidth: null,
  2224. minHeight: 10,
  2225. minWidth: 10,
  2226. zIndex: 1000
  2227. },
  2228. _create: function() {
  2229. var that = this, o = this.options;
  2230. this.element.addClass("ui-resizable");
  2231. $.extend(this, {
  2232. _aspectRatio: !!(o.aspectRatio),
  2233. aspectRatio: o.aspectRatio,
  2234. originalElement: this.element,
  2235. _proportionallyResizeElements: [],
  2236. _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
  2237. });
  2238. //Wrap the element if it cannot hold child nodes
  2239. if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
  2240. //Create a wrapper element and set the wrapper to the new current internal element
  2241. this.element.wrap(
  2242. $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
  2243. position: this.element.css('position'),
  2244. width: this.element.outerWidth(),
  2245. height: this.element.outerHeight(),
  2246. top: this.element.css('top'),
  2247. left: this.element.css('left')
  2248. })
  2249. );
  2250. //Overwrite the original this.element
  2251. this.element = this.element.parent().data(
  2252. "resizable", this.element.data('resizable')
  2253. );
  2254. this.elementIsWrapper = true;
  2255. //Move margins to the wrapper
  2256. this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
  2257. this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
  2258. //Prevent Safari textarea resize
  2259. this.originalResizeStyle = this.originalElement.css('resize');
  2260. this.originalElement.css('resize', 'none');
  2261. //Push the actual element to our proportionallyResize internal array
  2262. this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
  2263. // avoid IE jump (hard set the margin)
  2264. this.originalElement.css({ margin: this.originalElement.css('margin') });
  2265. // fix handlers offset
  2266. this._proportionallyResize();
  2267. }
  2268. 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' });
  2269. if(this.handles.constructor == String) {
  2270. if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
  2271. var n = this.handles.split(","); this.handles = {};
  2272. for(var i = 0; i < n.length; i++) {
  2273. var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
  2274. var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
  2275. // Apply zIndex to all handles - see #7960
  2276. axis.css({ zIndex: o.zIndex });
  2277. //TODO : What's going on here?
  2278. if ('se' == handle) {
  2279. axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
  2280. };
  2281. //Insert into internal handles object and append to element
  2282. this.handles[handle] = '.ui-resizable-'+handle;
  2283. this.element.append(axis);
  2284. }
  2285. }
  2286. this._renderAxis = function(target) {
  2287. target = target || this.element;
  2288. for(var i in this.handles) {
  2289. if(this.handles[i].constructor == String)
  2290. this.handles[i] = $(this.handles[i], this.element).show();
  2291. //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
  2292. if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
  2293. var axis = $(this.handles[i], this.element), padWrapper = 0;
  2294. //Checking the correct pad and border
  2295. padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
  2296. //The padding type i have to apply...
  2297. var padPos = [ 'padding',
  2298. /ne|nw|n/.test(i) ? 'Top' :
  2299. /se|sw|s/.test(i) ? 'Bottom' :
  2300. /^e$/.test(i) ? 'Right' : 'Left' ].join("");
  2301. target.css(padPos, padWrapper);
  2302. this._proportionallyResize();
  2303. }
  2304. //TODO: What's that good for? There's not anything to be executed left
  2305. if(!$(this.handles[i]).length)
  2306. continue;
  2307. }
  2308. };
  2309. //TODO: make renderAxis a prototype function
  2310. this._renderAxis(this.element);
  2311. this._handles = $('.ui-resizable-handle', this.element)
  2312. .disableSelection();
  2313. //Matching axis name
  2314. this._handles.mouseover(function() {
  2315. if (!that.resizing) {
  2316. if (this.className)
  2317. var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
  2318. //Axis, default = se
  2319. that.axis = axis && axis[1] ? axis[1] : 'se';
  2320. }
  2321. });
  2322. //If we want to auto hide the elements
  2323. if (o.autoHide) {
  2324. this._handles.hide();
  2325. $(this.element)
  2326. .addClass("ui-resizable-autohide")
  2327. .mouseenter(function() {
  2328. if (o.disabled) return;
  2329. $(this).removeClass("ui-resizable-autohide");
  2330. that._handles.show();
  2331. })
  2332. .mouseleave(function(){
  2333. if (o.disabled) return;
  2334. if (!that.resizing) {
  2335. $(this).addClass("ui-resizable-autohide");
  2336. that._handles.hide();
  2337. }
  2338. });
  2339. }
  2340. //Initialize the mouse interaction
  2341. this._mouseInit();
  2342. },
  2343. _destroy: function() {
  2344. this._mouseDestroy();
  2345. var _destroy = function(exp) {
  2346. $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
  2347. .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
  2348. };
  2349. //TODO: Unwrap at same DOM position
  2350. if (this.elementIsWrapper) {
  2351. _destroy(this.element);
  2352. var wrapper = this.element;
  2353. this.originalElement.css({
  2354. position: wrapper.css('position'),
  2355. width: wrapper.outerWidth(),
  2356. height: wrapper.outerHeight(),
  2357. top: wrapper.css('top'),
  2358. left: wrapper.css('left')
  2359. }).insertAfter( wrapper );
  2360. wrapper.remove();
  2361. }
  2362. this.originalElement.css('resize', this.originalResizeStyle);
  2363. _destroy(this.originalElement);
  2364. return this;
  2365. },
  2366. _mouseCapture: function(event) {
  2367. var handle = false;
  2368. for (var i in this.handles) {
  2369. if ($(this.handles[i])[0] == event.target) {
  2370. handle = true;
  2371. }
  2372. }
  2373. return !this.options.disabled && handle;
  2374. },
  2375. _mouseStart: function(event) {
  2376. var o = this.options, iniPos = this.element.position(), el = this.element;
  2377. this.resizing = true;
  2378. this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
  2379. // bugfix for http://dev.jquery.com/ticket/1749
  2380. if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
  2381. el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
  2382. }
  2383. this._renderProxy();
  2384. var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
  2385. if (o.containment) {
  2386. curleft += $(o.containment).scrollLeft() || 0;
  2387. curtop += $(o.containment).scrollTop() || 0;
  2388. }
  2389. //Store needed variables
  2390. this.offset = this.helper.offset();
  2391. this.position = { left: curleft, top: curtop };
  2392. this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
  2393. this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
  2394. this.originalPosition = { left: curleft, top: curtop };
  2395. this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
  2396. this.originalMousePosition = { left: event.pageX, top: event.pageY };
  2397. //Aspect Ratio
  2398. this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
  2399. var cursor = $('.ui-resizable-' + this.axis).css('cursor');
  2400. $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
  2401. el.addClass("ui-resizable-resizing");
  2402. this._propagate("start", event);
  2403. return true;
  2404. },
  2405. _mouseDrag: function(event) {
  2406. //Increase performance, avoid regex
  2407. var el = this.helper, o = this.options, props = {},
  2408. that = this, smp = this.originalMousePosition, a = this.axis;
  2409. var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
  2410. var trigger = this._change[a];
  2411. if (!trigger) return false;
  2412. // Calculate the attrs that will be change
  2413. var data = trigger.apply(this, [event, dx, dy]);
  2414. // Put this in the mouseDrag handler since the user can start pressing shift while resizing
  2415. this._updateVirtualBoundaries(event.shiftKey);
  2416. if (this._aspectRatio || event.shiftKey)
  2417. data = this._updateRatio(data, event);
  2418. data = this._respectSize(data, event);
  2419. // plugins callbacks need to be called first
  2420. this._propagate("resize", event);
  2421. el.css({
  2422. top: this.position.top + "px", left: this.position.left + "px",
  2423. width: this.size.width + "px", height: this.size.height + "px"
  2424. });
  2425. if (!this._helper && this._proportionallyResizeElements.length)
  2426. this._proportionallyResize();
  2427. this._updateCache(data);
  2428. // calling the user callback at the end
  2429. this._trigger('resize', event, this.ui());
  2430. return false;
  2431. },
  2432. _mouseStop: function(event) {
  2433. this.resizing = false;
  2434. var o = this.options, that = this;
  2435. if(this._helper) {
  2436. var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
  2437. soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height,
  2438. soffsetw = ista ? 0 : that.sizeDiff.width;
  2439. var s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) },
  2440. left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null,
  2441. top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null;
  2442. if (!o.animate)
  2443. this.element.css($.extend(s, { top: top, left: left }));
  2444. that.helper.height(that.size.height);
  2445. that.helper.width(that.size.width);
  2446. if (this._helper && !o.animate) this._proportionallyResize();
  2447. }
  2448. $('body').css('cursor', 'auto');
  2449. this.element.removeClass("ui-resizable-resizing");
  2450. this._propagate("stop", event);
  2451. if (this._helper) this.helper.remove();
  2452. return false;
  2453. },
  2454. _updateVirtualBoundaries: function(forceAspectRatio) {
  2455. var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b;
  2456. b = {
  2457. minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
  2458. maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
  2459. minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
  2460. maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
  2461. };
  2462. if(this._aspectRatio || forceAspectRatio) {
  2463. // We want to create an enclosing box whose aspect ration is the requested one
  2464. // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
  2465. pMinWidth = b.minHeight * this.aspectRatio;
  2466. pMinHeight = b.minWidth / this.aspectRatio;
  2467. pMaxWidth = b.maxHeight * this.aspectRatio;
  2468. pMaxHeight = b.maxWidth / this.aspectRatio;
  2469. if(pMinWidth > b.minWidth) b.minWidth = pMinWidth;
  2470. if(pMinHeight > b.minHeight) b.minHeight = pMinHeight;
  2471. if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth;
  2472. if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight;
  2473. }
  2474. this._vBoundaries = b;
  2475. },
  2476. _updateCache: function(data) {
  2477. var o = this.options;
  2478. this.offset = this.helper.offset();
  2479. if (isNumber(data.left)) this.position.left = data.left;
  2480. if (isNumber(data.top)) this.position.top = data.top;
  2481. if (isNumber(data.height)) this.size.height = data.height;
  2482. if (isNumber(data.width)) this.size.width = data.width;
  2483. },
  2484. _updateRatio: function(data, event) {
  2485. var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
  2486. if (isNumber(data.height)) data.width = (data.height * this.aspectRatio);
  2487. else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio);
  2488. if (a == 'sw') {
  2489. data.left = cpos.left + (csize.width - data.width);
  2490. data.top = null;
  2491. }
  2492. if (a == 'nw') {
  2493. data.top = cpos.top + (csize.height - data.height);
  2494. data.left = cpos.left + (csize.width - data.width);
  2495. }
  2496. return data;
  2497. },
  2498. _respectSize: function(data, event) {
  2499. var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
  2500. ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
  2501. isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
  2502. if (isminw) data.width = o.minWidth;
  2503. if (isminh) data.height = o.minHeight;
  2504. if (ismaxw) data.width = o.maxWidth;
  2505. if (ismaxh) data.height = o.maxHeight;
  2506. var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
  2507. var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
  2508. if (isminw && cw) data.left = dw - o.minWidth;
  2509. if (ismaxw && cw) data.left = dw - o.maxWidth;
  2510. if (isminh && ch) data.top = dh - o.minHeight;
  2511. if (ismaxh && ch) data.top = dh - o.maxHeight;
  2512. // fixing jump error on top/left - bug #2330
  2513. var isNotwh = !data.width && !data.height;
  2514. if (isNotwh && !data.left && data.top) data.top = null;
  2515. else if (isNotwh && !data.top && data.left) data.left = null;
  2516. return data;
  2517. },
  2518. _proportionallyResize: function() {
  2519. var o = this.options;
  2520. if (!this._proportionallyResizeElements.length) return;
  2521. var element = this.helper || this.element;
  2522. for (var i=0; i < this._proportionallyResizeElements.length; i++) {
  2523. var prel = this._proportionallyResizeElements[i];
  2524. if (!this.borderDif) {
  2525. var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
  2526. p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
  2527. this.borderDif = $.map(b, function(v, i) {
  2528. var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
  2529. return border + padding;
  2530. });
  2531. }
  2532. prel.css({
  2533. height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
  2534. width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
  2535. });
  2536. };
  2537. },
  2538. _renderProxy: function() {
  2539. var el = this.element, o = this.options;
  2540. this.elementOffset = el.offset();
  2541. if(this._helper) {
  2542. this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
  2543. // fix ie6 offset TODO: This seems broken
  2544. var ie6offset = ($.ui.ie6 ? 1 : 0),
  2545. pxyoffset = ( $.ui.ie6 ? 2 : -1 );
  2546. this.helper.addClass(this._helper).css({
  2547. width: this.element.outerWidth() + pxyoffset,
  2548. height: this.element.outerHeight() + pxyoffset,
  2549. position: 'absolute',
  2550. left: this.elementOffset.left - ie6offset +'px',
  2551. top: this.elementOffset.top - ie6offset +'px',
  2552. zIndex: ++o.zIndex //TODO: Don't modify option
  2553. });
  2554. this.helper
  2555. .appendTo("body")
  2556. .disableSelection();
  2557. } else {
  2558. this.helper = this.element;
  2559. }
  2560. },
  2561. _change: {
  2562. e: function(event, dx, dy) {
  2563. return { width: this.originalSize.width + dx };
  2564. },
  2565. w: function(event, dx, dy) {
  2566. var o = this.options, cs = this.originalSize, sp = this.originalPosition;
  2567. return { left: sp.left + dx, width: cs.width - dx };
  2568. },
  2569. n: function(event, dx, dy) {
  2570. var o = this.options, cs = this.originalSize, sp = this.originalPosition;
  2571. return { top: sp.top + dy, height: cs.height - dy };
  2572. },
  2573. s: function(event, dx, dy) {
  2574. return { height: this.originalSize.height + dy };
  2575. },
  2576. se: function(event, dx, dy) {
  2577. return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
  2578. },
  2579. sw: function(event, dx, dy) {
  2580. return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
  2581. },
  2582. ne: function(event, dx, dy) {
  2583. return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
  2584. },
  2585. nw: function(event, dx, dy) {
  2586. return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
  2587. }
  2588. },
  2589. _propagate: function(n, event) {
  2590. $.ui.plugin.call(this, n, [event, this.ui()]);
  2591. (n != "resize" && this._trigger(n, event, this.ui()));
  2592. },
  2593. plugins: {},
  2594. ui: function() {
  2595. return {
  2596. originalElement: this.originalElement,
  2597. element: this.element,
  2598. helper: this.helper,
  2599. position: this.position,
  2600. size: this.size,
  2601. originalSize: this.originalSize,
  2602. originalPosition: this.originalPosition
  2603. };
  2604. }
  2605. });
  2606. /*
  2607. * Resizable Extensions
  2608. */
  2609. $.ui.plugin.add("resizable", "alsoResize", {
  2610. start: function (event, ui) {
  2611. var that = $(this).data("resizable"), o = that.options;
  2612. var _store = function (exp) {
  2613. $(exp).each(function() {
  2614. var el = $(this);
  2615. el.data("resizable-alsoresize", {
  2616. width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
  2617. left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10)
  2618. });
  2619. });
  2620. };
  2621. if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
  2622. if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
  2623. else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
  2624. }else{
  2625. _store(o.alsoResize);
  2626. }
  2627. },
  2628. resize: function (event, ui) {
  2629. var that = $(this).data("resizable"), o = that.options, os = that.originalSize, op = that.originalPosition;
  2630. var delta = {
  2631. height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
  2632. top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0
  2633. },
  2634. _alsoResize = function (exp, c) {
  2635. $(exp).each(function() {
  2636. var el = $(this), start = $(this).data("resizable-alsoresize"), style = {},
  2637. css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left'];
  2638. $.each(css, function (i, prop) {
  2639. var sum = (start[prop]||0) + (delta[prop]||0);
  2640. if (sum && sum >= 0)
  2641. style[prop] = sum || null;
  2642. });
  2643. el.css(style);
  2644. });
  2645. };
  2646. if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
  2647. $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
  2648. }else{
  2649. _alsoResize(o.alsoResize);
  2650. }
  2651. },
  2652. stop: function (event, ui) {
  2653. $(this).removeData("resizable-alsoresize");
  2654. }
  2655. });
  2656. $.ui.plugin.add("resizable", "animate", {
  2657. stop: function(event, ui) {
  2658. var that = $(this).data("resizable"), o = that.options;
  2659. var pr = that._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
  2660. soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height,
  2661. soffsetw = ista ? 0 : that.sizeDiff.width;
  2662. var style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
  2663. left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null,
  2664. top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null;
  2665. that.element.animate(
  2666. $.extend(style, top && left ? { top: top, left: left } : {}), {
  2667. duration: o.animateDuration,
  2668. easing: o.animateEasing,
  2669. step: function() {
  2670. var data = {
  2671. width: parseInt(that.element.css('width'), 10),
  2672. height: parseInt(that.element.css('height'), 10),
  2673. top: parseInt(that.element.css('top'), 10),
  2674. left: parseInt(that.element.css('left'), 10)
  2675. };
  2676. if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
  2677. // propagating resize, and updating values for each animation step
  2678. that._updateCache(data);
  2679. that._propagate("resize", event);
  2680. }
  2681. }
  2682. );
  2683. }
  2684. });
  2685. $.ui.plugin.add("resizable", "containment", {
  2686. start: function(event, ui) {
  2687. var that = $(this).data("resizable"), o = that.options, el = that.element;
  2688. var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
  2689. if (!ce) return;
  2690. that.containerElement = $(ce);
  2691. if (/document/.test(oc) || oc == document) {
  2692. that.containerOffset = { left: 0, top: 0 };
  2693. that.containerPosition = { left: 0, top: 0 };
  2694. that.parentData = {
  2695. element: $(document), left: 0, top: 0,
  2696. width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
  2697. };
  2698. }
  2699. // i'm a node, so compute top, left, right, bottom
  2700. else {
  2701. var element = $(ce), p = [];
  2702. $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
  2703. that.containerOffset = element.offset();
  2704. that.containerPosition = element.position();
  2705. that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
  2706. var co = that.containerOffset, ch = that.containerSize.height, cw = that.containerSize.width,
  2707. width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
  2708. that.parentData = {
  2709. element: ce, left: co.left, top: co.top, width: width, height: height
  2710. };
  2711. }
  2712. },
  2713. resize: function(event, ui) {
  2714. var that = $(this).data("resizable"), o = that.options,
  2715. ps = that.containerSize, co = that.containerOffset, cs = that.size, cp = that.position,
  2716. pRatio = that._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = that.containerElement;
  2717. if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
  2718. if (cp.left < (that._helper ? co.left : 0)) {
  2719. that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));
  2720. if (pRatio) that.size.height = that.size.width / that.aspectRatio;
  2721. that.position.left = o.helper ? co.left : 0;
  2722. }
  2723. if (cp.top < (that._helper ? co.top : 0)) {
  2724. that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);
  2725. if (pRatio) that.size.width = that.size.height * that.aspectRatio;
  2726. that.position.top = that._helper ? co.top : 0;
  2727. }
  2728. that.offset.left = that.parentData.left+that.position.left;
  2729. that.offset.top = that.parentData.top+that.position.top;
  2730. var woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ),
  2731. hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );
  2732. var isParent = that.containerElement.get(0) == that.element.parent().get(0),
  2733. isOffsetRelative = /relative|absolute/.test(that.containerElement.css('position'));
  2734. if(isParent && isOffsetRelative) woset -= that.parentData.left;
  2735. if (woset + that.size.width >= that.parentData.width) {
  2736. that.size.width = that.parentData.width - woset;
  2737. if (pRatio) that.size.height = that.size.width / that.aspectRatio;
  2738. }
  2739. if (hoset + that.size.height >= that.parentData.height) {
  2740. that.size.height = that.parentData.height - hoset;
  2741. if (pRatio) that.size.width = that.size.height * that.aspectRatio;
  2742. }
  2743. },
  2744. stop: function(event, ui){
  2745. var that = $(this).data("resizable"), o = that.options, cp = that.position,
  2746. co = that.containerOffset, cop = that.containerPosition, ce = that.containerElement;
  2747. var helper = $(that.helper), ho = helper.offset(), w = helper.outerWidth() - that.sizeDiff.width, h = helper.outerHeight() - that.sizeDiff.height;
  2748. if (that._helper && !o.animate && (/relative/).test(ce.css('position')))
  2749. $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
  2750. if (that._helper && !o.animate && (/static/).test(ce.css('position')))
  2751. $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
  2752. }
  2753. });
  2754. $.ui.plugin.add("resizable", "ghost", {
  2755. start: function(event, ui) {
  2756. var that = $(this).data("resizable"), o = that.options, cs = that.size;
  2757. that.ghost = that.originalElement.clone();
  2758. that.ghost
  2759. .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
  2760. .addClass('ui-resizable-ghost')
  2761. .addClass(typeof o.ghost == 'string' ? o.ghost : '');
  2762. that.ghost.appendTo(that.helper);
  2763. },
  2764. resize: function(event, ui){
  2765. var that = $(this).data("resizable"), o = that.options;
  2766. if (that.ghost) that.ghost.css({ position: 'relative', height: that.size.height, width: that.size.width });
  2767. },
  2768. stop: function(event, ui){
  2769. var that = $(this).data("resizable"), o = that.options;
  2770. if (that.ghost && that.helper) that.helper.get(0).removeChild(that.ghost.get(0));
  2771. }
  2772. });
  2773. $.ui.plugin.add("resizable", "grid", {
  2774. resize: function(event, ui) {
  2775. var that = $(this).data("resizable"), o = that.options, cs = that.size, os = that.originalSize, op = that.originalPosition, a = that.axis, ratio = o._aspectRatio || event.shiftKey;
  2776. o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
  2777. var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1);
  2778. if (/^(se|s|e)$/.test(a)) {
  2779. that.size.width = os.width + ox;
  2780. that.size.height = os.height + oy;
  2781. }
  2782. else if (/^(ne)$/.test(a)) {
  2783. that.size.width = os.width + ox;
  2784. that.size.height = os.height + oy;
  2785. that.position.top = op.top - oy;
  2786. }
  2787. else if (/^(sw)$/.test(a)) {
  2788. that.size.width = os.width + ox;
  2789. that.size.height = os.height + oy;
  2790. that.position.left = op.left - ox;
  2791. }
  2792. else {
  2793. that.size.width = os.width + ox;
  2794. that.size.height = os.height + oy;
  2795. that.position.top = op.top - oy;
  2796. that.position.left = op.left - ox;
  2797. }
  2798. }
  2799. });
  2800. var num = function(v) {
  2801. return parseInt(v, 10) || 0;
  2802. };
  2803. var isNumber = function(value) {
  2804. return !isNaN(parseInt(value, 10));
  2805. };
  2806. })(jQuery);
  2807. (function( $, undefined ) {
  2808. $.widget("ui.selectable", $.ui.mouse, {
  2809. version: "1.9.1",
  2810. options: {
  2811. appendTo: 'body',
  2812. autoRefresh: true,
  2813. distance: 0,
  2814. filter: '*',
  2815. tolerance: 'touch'
  2816. },
  2817. _create: function() {
  2818. var that = this;
  2819. this.element.addClass("ui-selectable");
  2820. this.dragged = false;
  2821. // cache selectee children based on filter
  2822. var selectees;
  2823. this.refresh = function() {
  2824. selectees = $(that.options.filter, that.element[0]);
  2825. selectees.addClass("ui-selectee");
  2826. selectees.each(function() {
  2827. var $this = $(this);
  2828. var pos = $this.offset();
  2829. $.data(this, "selectable-item", {
  2830. element: this,
  2831. $element: $this,
  2832. left: pos.left,
  2833. top: pos.top,
  2834. right: pos.left + $this.outerWidth(),
  2835. bottom: pos.top + $this.outerHeight(),
  2836. startselected: false,
  2837. selected: $this.hasClass('ui-selected'),
  2838. selecting: $this.hasClass('ui-selecting'),
  2839. unselecting: $this.hasClass('ui-unselecting')
  2840. });
  2841. });
  2842. };
  2843. this.refresh();
  2844. this.selectees = selectees.addClass("ui-selectee");
  2845. this._mouseInit();
  2846. this.helper = $("<div class='ui-selectable-helper'></div>");
  2847. },
  2848. _destroy: function() {
  2849. this.selectees
  2850. .removeClass("ui-selectee")
  2851. .removeData("selectable-item");
  2852. this.element
  2853. .removeClass("ui-selectable ui-selectable-disabled");
  2854. this._mouseDestroy();
  2855. },
  2856. _mouseStart: function(event) {
  2857. var that = this;
  2858. this.opos = [event.pageX, event.pageY];
  2859. if (this.options.disabled)
  2860. return;
  2861. var options = this.options;
  2862. this.selectees = $(options.filter, this.element[0]);
  2863. this._trigger("start", event);
  2864. $(options.appendTo).append(this.helper);
  2865. // position helper (lasso)
  2866. this.helper.css({
  2867. "left": event.clientX,
  2868. "top": event.clientY,
  2869. "width": 0,
  2870. "height": 0
  2871. });
  2872. if (options.autoRefresh) {
  2873. this.refresh();
  2874. }
  2875. this.selectees.filter('.ui-selected').each(function() {
  2876. var selectee = $.data(this, "selectable-item");
  2877. selectee.startselected = true;
  2878. if (!event.metaKey && !event.ctrlKey) {
  2879. selectee.$element.removeClass('ui-selected');
  2880. selectee.selected = false;
  2881. selectee.$element.addClass('ui-unselecting');
  2882. selectee.unselecting = true;
  2883. // selectable UNSELECTING callback
  2884. that._trigger("unselecting", event, {
  2885. unselecting: selectee.element
  2886. });
  2887. }
  2888. });
  2889. $(event.target).parents().andSelf().each(function() {
  2890. var selectee = $.data(this, "selectable-item");
  2891. if (selectee) {
  2892. var doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass('ui-selected');
  2893. selectee.$element
  2894. .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
  2895. .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
  2896. selectee.unselecting = !doSelect;
  2897. selectee.selecting = doSelect;
  2898. selectee.selected = doSelect;
  2899. // selectable (UN)SELECTING callback
  2900. if (doSelect) {
  2901. that._trigger("selecting", event, {
  2902. selecting: selectee.element
  2903. });
  2904. } else {
  2905. that._trigger("unselecting", event, {
  2906. unselecting: selectee.element
  2907. });
  2908. }
  2909. return false;
  2910. }
  2911. });
  2912. },
  2913. _mouseDrag: function(event) {
  2914. var that = this;
  2915. this.dragged = true;
  2916. if (this.options.disabled)
  2917. return;
  2918. var options = this.options;
  2919. var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
  2920. if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
  2921. if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
  2922. this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
  2923. this.selectees.each(function() {
  2924. var selectee = $.data(this, "selectable-item");
  2925. //prevent helper from being selected if appendTo: selectable
  2926. if (!selectee || selectee.element == that.element[0])
  2927. return;
  2928. var hit = false;
  2929. if (options.tolerance == 'touch') {
  2930. hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
  2931. } else if (options.tolerance == 'fit') {
  2932. hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
  2933. }
  2934. if (hit) {
  2935. // SELECT
  2936. if (selectee.selected) {
  2937. selectee.$element.removeClass('ui-selected');
  2938. selectee.selected = false;
  2939. }
  2940. if (selectee.unselecting) {
  2941. selectee.$element.removeClass('ui-unselecting');
  2942. selectee.unselecting = false;
  2943. }
  2944. if (!selectee.selecting) {
  2945. selectee.$element.addClass('ui-selecting');
  2946. selectee.selecting = true;
  2947. // selectable SELECTING callback
  2948. that._trigger("selecting", event, {
  2949. selecting: selectee.element
  2950. });
  2951. }
  2952. } else {
  2953. // UNSELECT
  2954. if (selectee.selecting) {
  2955. if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
  2956. selectee.$element.removeClass('ui-selecting');
  2957. selectee.selecting = false;
  2958. selectee.$element.addClass('ui-selected');
  2959. selectee.selected = true;
  2960. } else {
  2961. selectee.$element.removeClass('ui-selecting');
  2962. selectee.selecting = false;
  2963. if (selectee.startselected) {
  2964. selectee.$element.addClass('ui-unselecting');
  2965. selectee.unselecting = true;
  2966. }
  2967. // selectable UNSELECTING callback
  2968. that._trigger("unselecting", event, {
  2969. unselecting: selectee.element
  2970. });
  2971. }
  2972. }
  2973. if (selectee.selected) {
  2974. if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
  2975. selectee.$element.removeClass('ui-selected');
  2976. selectee.selected = false;
  2977. selectee.$element.addClass('ui-unselecting');
  2978. selectee.unselecting = true;
  2979. // selectable UNSELECTING callback
  2980. that._trigger("unselecting", event, {
  2981. unselecting: selectee.element
  2982. });
  2983. }
  2984. }
  2985. }
  2986. });
  2987. return false;
  2988. },
  2989. _mouseStop: function(event) {
  2990. var that = this;
  2991. this.dragged = false;
  2992. var options = this.options;
  2993. $('.ui-unselecting', this.element[0]).each(function() {
  2994. var selectee = $.data(this, "selectable-item");
  2995. selectee.$element.removeClass('ui-unselecting');
  2996. selectee.unselecting = false;
  2997. selectee.startselected = false;
  2998. that._trigger("unselected", event, {
  2999. unselected: selectee.element
  3000. });
  3001. });
  3002. $('.ui-selecting', this.element[0]).each(function() {
  3003. var selectee = $.data(this, "selectable-item");
  3004. selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
  3005. selectee.selecting = false;
  3006. selectee.selected = true;
  3007. selectee.startselected = true;
  3008. that._trigger("selected", event, {
  3009. selected: selectee.element
  3010. });
  3011. });
  3012. this._trigger("stop", event);
  3013. this.helper.remove();
  3014. return false;
  3015. }
  3016. });
  3017. })(jQuery);
  3018. (function( $, undefined ) {
  3019. $.widget("ui.sortable", $.ui.mouse, {
  3020. version: "1.9.1",
  3021. widgetEventPrefix: "sort",
  3022. ready: false,
  3023. options: {
  3024. appendTo: "parent",
  3025. axis: false,
  3026. connectWith: false,
  3027. containment: false,
  3028. cursor: 'auto',
  3029. cursorAt: false,
  3030. dropOnEmpty: true,
  3031. forcePlaceholderSize: false,
  3032. forceHelperSize: false,
  3033. grid: false,
  3034. handle: false,
  3035. helper: "original",
  3036. items: '> *',
  3037. opacity: false,
  3038. placeholder: false,
  3039. revert: false,
  3040. scroll: true,
  3041. scrollSensitivity: 20,
  3042. scrollSpeed: 20,
  3043. scope: "default",
  3044. tolerance: "intersect",
  3045. zIndex: 1000
  3046. },
  3047. _create: function() {
  3048. var o = this.options;
  3049. this.containerCache = {};
  3050. this.element.addClass("ui-sortable");
  3051. //Get the items
  3052. this.refresh();
  3053. //Let's determine if the items are being displayed horizontally
  3054. this.floating = this.items.length ? o.axis === 'x' || (/left|right/).test(this.items[0].item.css('float')) || (/inline|table-cell/).test(this.items[0].item.css('display')) : false;
  3055. //Let's determine the parent's offset
  3056. this.offset = this.element.offset();
  3057. //Initialize mouse events for interaction
  3058. this._mouseInit();
  3059. //We're ready to go
  3060. this.ready = true
  3061. },
  3062. _destroy: function() {
  3063. this.element
  3064. .removeClass("ui-sortable ui-sortable-disabled");
  3065. this._mouseDestroy();
  3066. for ( var i = this.items.length - 1; i >= 0; i-- )
  3067. this.items[i].item.removeData(this.widgetName + "-item");
  3068. return this;
  3069. },
  3070. _setOption: function(key, value){
  3071. if ( key === "disabled" ) {
  3072. this.options[ key ] = value;
  3073. this.widget().toggleClass( "ui-sortable-disabled", !!value );
  3074. } else {
  3075. // Don't call widget base _setOption for disable as it adds ui-state-disabled class
  3076. $.Widget.prototype._setOption.apply(this, arguments);
  3077. }
  3078. },
  3079. _mouseCapture: function(event, overrideHandle) {
  3080. var that = this;
  3081. if (this.reverting) {
  3082. return false;
  3083. }
  3084. if(this.options.disabled || this.options.type == 'static') return false;
  3085. //We have to refresh the items data once first
  3086. this._refreshItems(event);
  3087. //Find out if the clicked node (or one of its parents) is a actual item in this.items
  3088. var currentItem = null, nodes = $(event.target).parents().each(function() {
  3089. if($.data(this, that.widgetName + '-item') == that) {
  3090. currentItem = $(this);
  3091. return false;
  3092. }
  3093. });
  3094. if($.data(event.target, that.widgetName + '-item') == that) currentItem = $(event.target);
  3095. if(!currentItem) return false;
  3096. if(this.options.handle && !overrideHandle) {
  3097. var validHandle = false;
  3098. $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
  3099. if(!validHandle) return false;
  3100. }
  3101. this.currentItem = currentItem;
  3102. this._removeCurrentsFromItems();
  3103. return true;
  3104. },
  3105. _mouseStart: function(event, overrideHandle, noActivation) {
  3106. var o = this.options;
  3107. this.currentContainer = this;
  3108. //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
  3109. this.refreshPositions();
  3110. //Create and append the visible helper
  3111. this.helper = this._createHelper(event);
  3112. //Cache the helper size
  3113. this._cacheHelperProportions();
  3114. /*
  3115. * - Position generation -
  3116. * This block generates everything position related - it's the core of draggables.
  3117. */
  3118. //Cache the margins of the original element
  3119. this._cacheMargins();
  3120. //Get the next scrolling parent
  3121. this.scrollParent = this.helper.scrollParent();
  3122. //The element's absolute position on the page minus margins
  3123. this.offset = this.currentItem.offset();
  3124. this.offset = {
  3125. top: this.offset.top - this.margins.top,
  3126. left: this.offset.left - this.margins.left
  3127. };
  3128. $.extend(this.offset, {
  3129. click: { //Where the click happened, relative to the element
  3130. left: event.pageX - this.offset.left,
  3131. top: event.pageY - this.offset.top
  3132. },
  3133. parent: this._getParentOffset(),
  3134. relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
  3135. });
  3136. // Only after we got the offset, we can change the helper's position to absolute
  3137. // TODO: Still need to figure out a way to make relative sorting possible
  3138. this.helper.css("position", "absolute");
  3139. this.cssPosition = this.helper.css("position");
  3140. //Generate the original position
  3141. this.originalPosition = this._generatePosition(event);
  3142. this.originalPageX = event.pageX;
  3143. this.originalPageY = event.pageY;
  3144. //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
  3145. (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
  3146. //Cache the former DOM position
  3147. this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
  3148. //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
  3149. if(this.helper[0] != this.currentItem[0]) {
  3150. this.currentItem.hide();
  3151. }
  3152. //Create the placeholder
  3153. this._createPlaceholder();
  3154. //Set a containment if given in the options
  3155. if(o.containment)
  3156. this._setContainment();
  3157. if(o.cursor) { // cursor option
  3158. if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
  3159. $('body').css("cursor", o.cursor);
  3160. }
  3161. if(o.opacity) { // opacity option
  3162. if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
  3163. this.helper.css("opacity", o.opacity);
  3164. }
  3165. if(o.zIndex) { // zIndex option
  3166. if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
  3167. this.helper.css("zIndex", o.zIndex);
  3168. }
  3169. //Prepare scrolling
  3170. if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
  3171. this.overflowOffset = this.scrollParent.offset();
  3172. //Call callbacks
  3173. this._trigger("start", event, this._uiHash());
  3174. //Recache the helper size
  3175. if(!this._preserveHelperProportions)
  3176. this._cacheHelperProportions();
  3177. //Post 'activate' events to possible containers
  3178. if(!noActivation) {
  3179. for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, this._uiHash(this)); }
  3180. }
  3181. //Prepare possible droppables
  3182. if($.ui.ddmanager)
  3183. $.ui.ddmanager.current = this;
  3184. if ($.ui.ddmanager && !o.dropBehaviour)
  3185. $.ui.ddmanager.prepareOffsets(this, event);
  3186. this.dragging = true;
  3187. this.helper.addClass("ui-sortable-helper");
  3188. this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
  3189. return true;
  3190. },
  3191. _mouseDrag: function(event) {
  3192. //Compute the helpers position
  3193. this.position = this._generatePosition(event);
  3194. this.positionAbs = this._convertPositionTo("absolute");
  3195. if (!this.lastPositionAbs) {
  3196. this.lastPositionAbs = this.positionAbs;
  3197. }
  3198. //Do scrolling
  3199. if(this.options.scroll) {
  3200. var o = this.options, scrolled = false;
  3201. if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
  3202. if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
  3203. this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
  3204. else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
  3205. this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
  3206. if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
  3207. this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
  3208. else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
  3209. this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
  3210. } else {
  3211. if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
  3212. scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
  3213. else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
  3214. scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
  3215. if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
  3216. scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
  3217. else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
  3218. scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
  3219. }
  3220. if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
  3221. $.ui.ddmanager.prepareOffsets(this, event);
  3222. }
  3223. //Regenerate the absolute position used for position checks
  3224. this.positionAbs = this._convertPositionTo("absolute");
  3225. //Set the helper position
  3226. if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
  3227. if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
  3228. //Rearrange
  3229. for (var i = this.items.length - 1; i >= 0; i--) {
  3230. //Cache variables and intersection, continue if no intersection
  3231. var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
  3232. if (!intersection) continue;
  3233. // Only put the placeholder inside the current Container, skip all
  3234. // items form other containers. This works because when moving
  3235. // an item from one container to another the
  3236. // currentContainer is switched before the placeholder is moved.
  3237. //
  3238. // Without this moving items in "sub-sortables" can cause the placeholder to jitter
  3239. // beetween the outer and inner container.
  3240. if (item.instance !== this.currentContainer) continue;
  3241. if (itemElement != this.currentItem[0] //cannot intersect with itself
  3242. && this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
  3243. && !$.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
  3244. && (this.options.type == 'semi-dynamic' ? !$.contains(this.element[0], itemElement) : true)
  3245. //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
  3246. ) {
  3247. this.direction = intersection == 1 ? "down" : "up";
  3248. if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
  3249. this._rearrange(event, item);
  3250. } else {
  3251. break;
  3252. }
  3253. this._trigger("change", event, this._uiHash());
  3254. break;
  3255. }
  3256. }
  3257. //Post events to containers
  3258. this._contactContainers(event);
  3259. //Interconnect with droppables
  3260. if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
  3261. //Call callbacks
  3262. this._trigger('sort', event, this._uiHash());
  3263. this.lastPositionAbs = this.positionAbs;
  3264. return false;
  3265. },
  3266. _mouseStop: function(event, noPropagation) {
  3267. if(!event) return;
  3268. //If we are using droppables, inform the manager about the drop
  3269. if ($.ui.ddmanager && !this.options.dropBehaviour)
  3270. $.ui.ddmanager.drop(this, event);
  3271. if(this.options.revert) {
  3272. var that = this;
  3273. var cur = this.placeholder.offset();
  3274. this.reverting = true;
  3275. $(this.helper).animate({
  3276. left: cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
  3277. top: cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
  3278. }, parseInt(this.options.revert, 10) || 500, function() {
  3279. that._clear(event);
  3280. });
  3281. } else {
  3282. this._clear(event, noPropagation);
  3283. }
  3284. return false;
  3285. },
  3286. cancel: function() {
  3287. if(this.dragging) {
  3288. this._mouseUp({ target: null });
  3289. if(this.options.helper == "original")
  3290. this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
  3291. else
  3292. this.currentItem.show();
  3293. //Post deactivating events to containers
  3294. for (var i = this.containers.length - 1; i >= 0; i--){
  3295. this.containers[i]._trigger("deactivate", null, this._uiHash(this));
  3296. if(this.containers[i].containerCache.over) {
  3297. this.containers[i]._trigger("out", null, this._uiHash(this));
  3298. this.containers[i].containerCache.over = 0;
  3299. }
  3300. }
  3301. }
  3302. if (this.placeholder) {
  3303. //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
  3304. if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
  3305. if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
  3306. $.extend(this, {
  3307. helper: null,
  3308. dragging: false,
  3309. reverting: false,
  3310. _noFinalSort: null
  3311. });
  3312. if(this.domPosition.prev) {
  3313. $(this.domPosition.prev).after(this.currentItem);
  3314. } else {
  3315. $(this.domPosition.parent).prepend(this.currentItem);
  3316. }
  3317. }
  3318. return this;
  3319. },
  3320. serialize: function(o) {
  3321. var items = this._getItemsAsjQuery(o && o.connected);
  3322. var str = []; o = o || {};
  3323. $(items).each(function() {
  3324. var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
  3325. if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
  3326. });
  3327. if(!str.length && o.key) {
  3328. str.push(o.key + '=');
  3329. }
  3330. return str.join('&');
  3331. },
  3332. toArray: function(o) {
  3333. var items = this._getItemsAsjQuery(o && o.connected);
  3334. var ret = []; o = o || {};
  3335. items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
  3336. return ret;
  3337. },
  3338. /* Be careful with the following core functions */
  3339. _intersectsWith: function(item) {
  3340. var x1 = this.positionAbs.left,
  3341. x2 = x1 + this.helperProportions.width,
  3342. y1 = this.positionAbs.top,
  3343. y2 = y1 + this.helperProportions.height;
  3344. var l = item.left,
  3345. r = l + item.width,
  3346. t = item.top,
  3347. b = t + item.height;
  3348. var dyClick = this.offset.click.top,
  3349. dxClick = this.offset.click.left;
  3350. var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
  3351. if( this.options.tolerance == "pointer"
  3352. || this.options.forcePointerForContainers
  3353. || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
  3354. ) {
  3355. return isOverElement;
  3356. } else {
  3357. return (l < x1 + (this.helperProportions.width / 2) // Right Half
  3358. && x2 - (this.helperProportions.width / 2) < r // Left Half
  3359. && t < y1 + (this.helperProportions.height / 2) // Bottom Half
  3360. && y2 - (this.helperProportions.height / 2) < b ); // Top Half
  3361. }
  3362. },
  3363. _intersectsWithPointer: function(item) {
  3364. var isOverElementHeight = (this.options.axis === 'x') || $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
  3365. isOverElementWidth = (this.options.axis === 'y') || $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
  3366. isOverElement = isOverElementHeight && isOverElementWidth,
  3367. verticalDirection = this._getDragVerticalDirection(),
  3368. horizontalDirection = this._getDragHorizontalDirection();
  3369. if (!isOverElement)
  3370. return false;
  3371. return this.floating ?
  3372. ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
  3373. : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
  3374. },
  3375. _intersectsWithSides: function(item) {
  3376. var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
  3377. isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
  3378. verticalDirection = this._getDragVerticalDirection(),
  3379. horizontalDirection = this._getDragHorizontalDirection();
  3380. if (this.floating && horizontalDirection) {
  3381. return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
  3382. } else {
  3383. return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
  3384. }
  3385. },
  3386. _getDragVerticalDirection: function() {
  3387. var delta = this.positionAbs.top - this.lastPositionAbs.top;
  3388. return delta != 0 && (delta > 0 ? "down" : "up");
  3389. },
  3390. _getDragHorizontalDirection: function() {
  3391. var delta = this.positionAbs.left - this.lastPositionAbs.left;
  3392. return delta != 0 && (delta > 0 ? "right" : "left");
  3393. },
  3394. refresh: function(event) {
  3395. this._refreshItems(event);
  3396. this.refreshPositions();
  3397. return this;
  3398. },
  3399. _connectWith: function() {
  3400. var options = this.options;
  3401. return options.connectWith.constructor == String
  3402. ? [options.connectWith]
  3403. : options.connectWith;
  3404. },
  3405. _getItemsAsjQuery: function(connected) {
  3406. var items = [];
  3407. var queries = [];
  3408. var connectWith = this._connectWith();
  3409. if(connectWith && connected) {
  3410. for (var i = connectWith.length - 1; i >= 0; i--){
  3411. var cur = $(connectWith[i]);
  3412. for (var j = cur.length - 1; j >= 0; j--){
  3413. var inst = $.data(cur[j], this.widgetName);
  3414. if(inst && inst != this && !inst.options.disabled) {
  3415. 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]);
  3416. }
  3417. };
  3418. };
  3419. }
  3420. 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]);
  3421. for (var i = queries.length - 1; i >= 0; i--){
  3422. queries[i][0].each(function() {
  3423. items.push(this);
  3424. });
  3425. };
  3426. return $(items);
  3427. },
  3428. _removeCurrentsFromItems: function() {
  3429. var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
  3430. this.items = $.grep(this.items, function (item) {
  3431. for (var j=0; j < list.length; j++) {
  3432. if(list[j] == item.item[0])
  3433. return false;
  3434. };
  3435. return true;
  3436. });
  3437. },
  3438. _refreshItems: function(event) {
  3439. this.items = [];
  3440. this.containers = [this];
  3441. var items = this.items;
  3442. var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
  3443. var connectWith = this._connectWith();
  3444. if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
  3445. for (var i = connectWith.length - 1; i >= 0; i--){
  3446. var cur = $(connectWith[i]);
  3447. for (var j = cur.length - 1; j >= 0; j--){
  3448. var inst = $.data(cur[j], this.widgetName);
  3449. if(inst && inst != this && !inst.options.disabled) {
  3450. queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
  3451. this.containers.push(inst);
  3452. }
  3453. };
  3454. };
  3455. }
  3456. for (var i = queries.length - 1; i >= 0; i--) {
  3457. var targetData = queries[i][1];
  3458. var _queries = queries[i][0];
  3459. for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
  3460. var item = $(_queries[j]);
  3461. item.data(this.widgetName + '-item', targetData); // Data for target checking (mouse manager)
  3462. items.push({
  3463. item: item,
  3464. instance: targetData,
  3465. width: 0, height: 0,
  3466. left: 0, top: 0
  3467. });
  3468. };
  3469. };
  3470. },
  3471. refreshPositions: function(fast) {
  3472. //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
  3473. if(this.offsetParent && this.helper) {
  3474. this.offset.parent = this._getParentOffset();
  3475. }
  3476. for (var i = this.items.length - 1; i >= 0; i--){
  3477. var item = this.items[i];
  3478. //We ignore calculating positions of all connected containers when we're not over them
  3479. if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
  3480. continue;
  3481. var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
  3482. if (!fast) {
  3483. item.width = t.outerWidth();
  3484. item.height = t.outerHeight();
  3485. }
  3486. var p = t.offset();
  3487. item.left = p.left;
  3488. item.top = p.top;
  3489. };
  3490. if(this.options.custom && this.options.custom.refreshContainers) {
  3491. this.options.custom.refreshContainers.call(this);
  3492. } else {
  3493. for (var i = this.containers.length - 1; i >= 0; i--){
  3494. var p = this.containers[i].element.offset();
  3495. this.containers[i].containerCache.left = p.left;
  3496. this.containers[i].containerCache.top = p.top;
  3497. this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
  3498. this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
  3499. };
  3500. }
  3501. return this;
  3502. },
  3503. _createPlaceholder: function(that) {
  3504. that = that || this;
  3505. var o = that.options;
  3506. if(!o.placeholder || o.placeholder.constructor == String) {
  3507. var className = o.placeholder;
  3508. o.placeholder = {
  3509. element: function() {
  3510. var el = $(document.createElement(that.currentItem[0].nodeName))
  3511. .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
  3512. .removeClass("ui-sortable-helper")[0];
  3513. if(!className)
  3514. el.style.visibility = "hidden";
  3515. return el;
  3516. },
  3517. update: function(container, p) {
  3518. // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
  3519. // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
  3520. if(className && !o.forcePlaceholderSize) return;
  3521. //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
  3522. if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css('paddingTop')||0, 10) - parseInt(that.currentItem.css('paddingBottom')||0, 10)); };
  3523. if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css('paddingLeft')||0, 10) - parseInt(that.currentItem.css('paddingRight')||0, 10)); };
  3524. }
  3525. };
  3526. }
  3527. //Create the placeholder
  3528. that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
  3529. //Append it after the actual current item
  3530. that.currentItem.after(that.placeholder);
  3531. //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
  3532. o.placeholder.update(that, that.placeholder);
  3533. },
  3534. _contactContainers: function(event) {
  3535. // get innermost container that intersects with item
  3536. var innermostContainer = null, innermostIndex = null;
  3537. for (var i = this.containers.length - 1; i >= 0; i--){
  3538. // never consider a container that's located within the item itself
  3539. if($.contains(this.currentItem[0], this.containers[i].element[0]))
  3540. continue;
  3541. if(this._intersectsWith(this.containers[i].containerCache)) {
  3542. // if we've already found a container and it's more "inner" than this, then continue
  3543. if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0]))
  3544. continue;
  3545. innermostContainer = this.containers[i];
  3546. innermostIndex = i;
  3547. } else {
  3548. // container doesn't intersect. trigger "out" event if necessary
  3549. if(this.containers[i].containerCache.over) {
  3550. this.containers[i]._trigger("out", event, this._uiHash(this));
  3551. this.containers[i].containerCache.over = 0;
  3552. }
  3553. }
  3554. }
  3555. // if no intersecting containers found, return
  3556. if(!innermostContainer) return;
  3557. // move the item into the container if it's not there already
  3558. if(this.containers.length === 1) {
  3559. this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
  3560. this.containers[innermostIndex].containerCache.over = 1;
  3561. } else {
  3562. //When entering a new container, we will find the item with the least distance and append our item near it
  3563. var dist = 10000; var itemWithLeastDistance = null;
  3564. var posProperty = this.containers[innermostIndex].floating ? 'left' : 'top';
  3565. var sizeProperty = this.containers[innermostIndex].floating ? 'width' : 'height';
  3566. var base = this.positionAbs[posProperty] + this.offset.click[posProperty];
  3567. for (var j = this.items.length - 1; j >= 0; j--) {
  3568. if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue;
  3569. if(this.items[j].item[0] == this.currentItem[0]) continue;
  3570. var cur = this.items[j].item.offset()[posProperty];
  3571. var nearBottom = false;
  3572. if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
  3573. nearBottom = true;
  3574. cur += this.items[j][sizeProperty];
  3575. }
  3576. if(Math.abs(cur - base) < dist) {
  3577. dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
  3578. this.direction = nearBottom ? "up": "down";
  3579. }
  3580. }
  3581. if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled
  3582. return;
  3583. this.currentContainer = this.containers[innermostIndex];
  3584. itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
  3585. this._trigger("change", event, this._uiHash());
  3586. this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
  3587. //Update the placeholder
  3588. this.options.placeholder.update(this.currentContainer, this.placeholder);
  3589. this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
  3590. this.containers[innermostIndex].containerCache.over = 1;
  3591. }
  3592. },
  3593. _createHelper: function(event) {
  3594. var o = this.options;
  3595. var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
  3596. if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
  3597. $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
  3598. if(helper[0] == this.currentItem[0])
  3599. 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") };
  3600. if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
  3601. if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
  3602. return helper;
  3603. },
  3604. _adjustOffsetFromHelper: function(obj) {
  3605. if (typeof obj == 'string') {
  3606. obj = obj.split(' ');
  3607. }
  3608. if ($.isArray(obj)) {
  3609. obj = {left: +obj[0], top: +obj[1] || 0};
  3610. }
  3611. if ('left' in obj) {
  3612. this.offset.click.left = obj.left + this.margins.left;
  3613. }
  3614. if ('right' in obj) {
  3615. this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
  3616. }
  3617. if ('top' in obj) {
  3618. this.offset.click.top = obj.top + this.margins.top;
  3619. }
  3620. if ('bottom' in obj) {
  3621. this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
  3622. }
  3623. },
  3624. _getParentOffset: function() {
  3625. //Get the offsetParent and cache its position
  3626. this.offsetParent = this.helper.offsetParent();
  3627. var po = this.offsetParent.offset();
  3628. // This is a special case where we need to modify a offset calculated on start, since the following happened:
  3629. // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
  3630. // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
  3631. // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
  3632. if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
  3633. po.left += this.scrollParent.scrollLeft();
  3634. po.top += this.scrollParent.scrollTop();
  3635. }
  3636. if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
  3637. || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix
  3638. po = { top: 0, left: 0 };
  3639. return {
  3640. top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
  3641. left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
  3642. };
  3643. },
  3644. _getRelativeOffset: function() {
  3645. if(this.cssPosition == "relative") {
  3646. var p = this.currentItem.position();
  3647. return {
  3648. top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
  3649. left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
  3650. };
  3651. } else {
  3652. return { top: 0, left: 0 };
  3653. }
  3654. },
  3655. _cacheMargins: function() {
  3656. this.margins = {
  3657. left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
  3658. top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
  3659. };
  3660. },
  3661. _cacheHelperProportions: function() {
  3662. this.helperProportions = {
  3663. width: this.helper.outerWidth(),
  3664. height: this.helper.outerHeight()
  3665. };
  3666. },
  3667. _setContainment: function() {
  3668. var o = this.options;
  3669. if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
  3670. if(o.containment == 'document' || o.containment == 'window') this.containment = [
  3671. 0 - this.offset.relative.left - this.offset.parent.left,
  3672. 0 - this.offset.relative.top - this.offset.parent.top,
  3673. $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
  3674. ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
  3675. ];
  3676. if(!(/^(document|window|parent)$/).test(o.containment)) {
  3677. var ce = $(o.containment)[0];
  3678. var co = $(o.containment).offset();
  3679. var over = ($(ce).css("overflow") != 'hidden');
  3680. this.containment = [
  3681. co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
  3682. co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
  3683. 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,
  3684. 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
  3685. ];
  3686. }
  3687. },
  3688. _convertPositionTo: function(d, pos) {
  3689. if(!pos) pos = this.position;
  3690. var mod = d == "absolute" ? 1 : -1;
  3691. var o = this.options, 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);
  3692. return {
  3693. top: (
  3694. pos.top // The absolute mouse position
  3695. + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
  3696. + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
  3697. - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
  3698. ),
  3699. left: (
  3700. pos.left // The absolute mouse position
  3701. + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
  3702. + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
  3703. - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
  3704. )
  3705. };
  3706. },
  3707. _generatePosition: function(event) {
  3708. var o = this.options, 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);
  3709. // This is another very weird special case that only happens for relative elements:
  3710. // 1. If the css position is relative
  3711. // 2. and the scroll parent is the document or similar to the offset parent
  3712. // we have to refresh the relative offset during the scroll so there are no jumps
  3713. if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
  3714. this.offset.relative = this._getRelativeOffset();
  3715. }
  3716. var pageX = event.pageX;
  3717. var pageY = event.pageY;
  3718. /*
  3719. * - Position constraining -
  3720. * Constrain the position to a mix of grid, containment.
  3721. */
  3722. if(this.originalPosition) { //If we are not dragging yet, we won't check for options
  3723. if(this.containment) {
  3724. if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
  3725. if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
  3726. if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
  3727. if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
  3728. }
  3729. if(o.grid) {
  3730. var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
  3731. 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;
  3732. var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
  3733. 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;
  3734. }
  3735. }
  3736. return {
  3737. top: (
  3738. pageY // The absolute mouse position
  3739. - this.offset.click.top // Click offset (relative to the element)
  3740. - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
  3741. - this.offset.parent.top // The offsetParent's offset without borders (offset + border)
  3742. + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
  3743. ),
  3744. left: (
  3745. pageX // The absolute mouse position
  3746. - this.offset.click.left // Click offset (relative to the element)
  3747. - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
  3748. - this.offset.parent.left // The offsetParent's offset without borders (offset + border)
  3749. + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
  3750. )
  3751. };
  3752. },
  3753. _rearrange: function(event, i, a, hardRefresh) {
  3754. 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));
  3755. //Various things done here to improve the performance:
  3756. // 1. we create a setTimeout, that calls refreshPositions
  3757. // 2. on the instance, we have a counter variable, that get's higher after every append
  3758. // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
  3759. // 4. this lets only the last addition to the timeout stack through
  3760. this.counter = this.counter ? ++this.counter : 1;
  3761. var counter = this.counter;
  3762. this._delay(function() {
  3763. if(counter == this.counter) this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
  3764. });
  3765. },
  3766. _clear: function(event, noPropagation) {
  3767. this.reverting = false;
  3768. // We delay all events that have to be triggered to after the point where the placeholder has been removed and
  3769. // everything else normalized again
  3770. var delayedTriggers = [];
  3771. // We first have to update the dom position of the actual currentItem
  3772. // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
  3773. if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem);
  3774. this._noFinalSort = null;
  3775. if(this.helper[0] == this.currentItem[0]) {
  3776. for(var i in this._storedCSS) {
  3777. if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
  3778. }
  3779. this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
  3780. } else {
  3781. this.currentItem.show();
  3782. }
  3783. if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
  3784. if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
  3785. // Check if the items Container has Changed and trigger appropriate
  3786. // events.
  3787. if (this !== this.currentContainer) {
  3788. if(!noPropagation) {
  3789. delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
  3790. delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
  3791. delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
  3792. }
  3793. }
  3794. //Post events to containers
  3795. for (var i = this.containers.length - 1; i >= 0; i--){
  3796. if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
  3797. if(this.containers[i].containerCache.over) {
  3798. delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
  3799. this.containers[i].containerCache.over = 0;
  3800. }
  3801. }
  3802. //Do what was originally in plugins
  3803. if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
  3804. if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity
  3805. if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index
  3806. this.dragging = false;
  3807. if(this.cancelHelperRemoval) {
  3808. if(!noPropagation) {
  3809. this._trigger("beforeStop", event, this._uiHash());
  3810. for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
  3811. this._trigger("stop", event, this._uiHash());
  3812. }
  3813. this.fromOutside = false;
  3814. return false;
  3815. }
  3816. if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());
  3817. //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
  3818. this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
  3819. if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
  3820. if(!noPropagation) {
  3821. for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
  3822. this._trigger("stop", event, this._uiHash());
  3823. }
  3824. this.fromOutside = false;
  3825. return true;
  3826. },
  3827. _trigger: function() {
  3828. if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
  3829. this.cancel();
  3830. }
  3831. },
  3832. _uiHash: function(_inst) {
  3833. var inst = _inst || this;
  3834. return {
  3835. helper: inst.helper,
  3836. placeholder: inst.placeholder || $([]),
  3837. position: inst.position,
  3838. originalPosition: inst.originalPosition,
  3839. offset: inst.positionAbs,
  3840. item: inst.currentItem,
  3841. sender: _inst ? _inst.element : null
  3842. };
  3843. }
  3844. });
  3845. })(jQuery);
  3846. (function( $, undefined ) {
  3847. var uid = 0,
  3848. hideProps = {},
  3849. showProps = {};
  3850. hideProps.height = hideProps.paddingTop = hideProps.paddingBottom =
  3851. hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide";
  3852. showProps.height = showProps.paddingTop = showProps.paddingBottom =
  3853. showProps.borderTopWidth = showProps.borderBottomWidth = "show";
  3854. $.widget( "ui.accordion", {
  3855. version: "1.9.1",
  3856. options: {
  3857. active: 0,
  3858. animate: {},
  3859. collapsible: false,
  3860. event: "click",
  3861. header: "> li > :first-child,> :not(li):even",
  3862. heightStyle: "auto",
  3863. icons: {
  3864. activeHeader: "ui-icon-triangle-1-s",
  3865. header: "ui-icon-triangle-1-e"
  3866. },
  3867. // callbacks
  3868. activate: null,
  3869. beforeActivate: null
  3870. },
  3871. _create: function() {
  3872. var accordionId = this.accordionId = "ui-accordion-" +
  3873. (this.element.attr( "id" ) || ++uid),
  3874. options = this.options;
  3875. this.prevShow = this.prevHide = $();
  3876. this.element.addClass( "ui-accordion ui-widget ui-helper-reset" );
  3877. this.headers = this.element.find( options.header )
  3878. .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" );
  3879. this._hoverable( this.headers );
  3880. this._focusable( this.headers );
  3881. this.headers.next()
  3882. .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
  3883. .hide();
  3884. // don't allow collapsible: false and active: false / null
  3885. if ( !options.collapsible && (options.active === false || options.active == null) ) {
  3886. options.active = 0;
  3887. }
  3888. // handle negative values
  3889. if ( options.active < 0 ) {
  3890. options.active += this.headers.length;
  3891. }
  3892. this.active = this._findActive( options.active )
  3893. .addClass( "ui-accordion-header-active ui-state-active" )
  3894. .toggleClass( "ui-corner-all ui-corner-top" );
  3895. this.active.next()
  3896. .addClass( "ui-accordion-content-active" )
  3897. .show();
  3898. this._createIcons();
  3899. this.refresh();
  3900. // ARIA
  3901. this.element.attr( "role", "tablist" );
  3902. this.headers
  3903. .attr( "role", "tab" )
  3904. .each(function( i ) {
  3905. var header = $( this ),
  3906. headerId = header.attr( "id" ),
  3907. panel = header.next(),
  3908. panelId = panel.attr( "id" );
  3909. if ( !headerId ) {
  3910. headerId = accordionId + "-header-" + i;
  3911. header.attr( "id", headerId );
  3912. }
  3913. if ( !panelId ) {
  3914. panelId = accordionId + "-panel-" + i;
  3915. panel.attr( "id", panelId );
  3916. }
  3917. header.attr( "aria-controls", panelId );
  3918. panel.attr( "aria-labelledby", headerId );
  3919. })
  3920. .next()
  3921. .attr( "role", "tabpanel" );
  3922. this.headers
  3923. .not( this.active )
  3924. .attr({
  3925. "aria-selected": "false",
  3926. tabIndex: -1
  3927. })
  3928. .next()
  3929. .attr({
  3930. "aria-expanded": "false",
  3931. "aria-hidden": "true"
  3932. })
  3933. .hide();
  3934. // make sure at least one header is in the tab order
  3935. if ( !this.active.length ) {
  3936. this.headers.eq( 0 ).attr( "tabIndex", 0 );
  3937. } else {
  3938. this.active.attr({
  3939. "aria-selected": "true",
  3940. tabIndex: 0
  3941. })
  3942. .next()
  3943. .attr({
  3944. "aria-expanded": "true",
  3945. "aria-hidden": "false"
  3946. });
  3947. }
  3948. this._on( this.headers, { keydown: "_keydown" });
  3949. this._on( this.headers.next(), { keydown: "_panelKeyDown" });
  3950. this._setupEvents( options.event );
  3951. },
  3952. _getCreateEventData: function() {
  3953. return {
  3954. header: this.active,
  3955. content: !this.active.length ? $() : this.active.next()
  3956. };
  3957. },
  3958. _createIcons: function() {
  3959. var icons = this.options.icons;
  3960. if ( icons ) {
  3961. $( "<span>" )
  3962. .addClass( "ui-accordion-header-icon ui-icon " + icons.header )
  3963. .prependTo( this.headers );
  3964. this.active.children( ".ui-accordion-header-icon" )
  3965. .removeClass( icons.header )
  3966. .addClass( icons.activeHeader );
  3967. this.headers.addClass( "ui-accordion-icons" );
  3968. }
  3969. },
  3970. _destroyIcons: function() {
  3971. this.headers
  3972. .removeClass( "ui-accordion-icons" )
  3973. .children( ".ui-accordion-header-icon" )
  3974. .remove();
  3975. },
  3976. _destroy: function() {
  3977. var contents;
  3978. // clean up main element
  3979. this.element
  3980. .removeClass( "ui-accordion ui-widget ui-helper-reset" )
  3981. .removeAttr( "role" );
  3982. // clean up headers
  3983. this.headers
  3984. .removeClass( "ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
  3985. .removeAttr( "role" )
  3986. .removeAttr( "aria-selected" )
  3987. .removeAttr( "aria-controls" )
  3988. .removeAttr( "tabIndex" )
  3989. .each(function() {
  3990. if ( /^ui-accordion/.test( this.id ) ) {
  3991. this.removeAttribute( "id" );
  3992. }
  3993. });
  3994. this._destroyIcons();
  3995. // clean up content panels
  3996. contents = this.headers.next()
  3997. .css( "display", "" )
  3998. .removeAttr( "role" )
  3999. .removeAttr( "aria-expanded" )
  4000. .removeAttr( "aria-hidden" )
  4001. .removeAttr( "aria-labelledby" )
  4002. .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" )
  4003. .each(function() {
  4004. if ( /^ui-accordion/.test( this.id ) ) {
  4005. this.removeAttribute( "id" );
  4006. }
  4007. });
  4008. if ( this.options.heightStyle !== "content" ) {
  4009. contents.css( "height", "" );
  4010. }
  4011. },
  4012. _setOption: function( key, value ) {
  4013. if ( key === "active" ) {
  4014. // _activate() will handle invalid values and update this.options
  4015. this._activate( value );
  4016. return;
  4017. }
  4018. if ( key === "event" ) {
  4019. if ( this.options.event ) {
  4020. this._off( this.headers, this.options.event );
  4021. }
  4022. this._setupEvents( value );
  4023. }
  4024. this._super( key, value );
  4025. // setting collapsible: false while collapsed; open first panel
  4026. if ( key === "collapsible" && !value && this.options.active === false ) {
  4027. this._activate( 0 );
  4028. }
  4029. if ( key === "icons" ) {
  4030. this._destroyIcons();
  4031. if ( value ) {
  4032. this._createIcons();
  4033. }
  4034. }
  4035. // #5332 - opacity doesn't cascade to positioned elements in IE
  4036. // so we need to add the disabled class to the headers and panels
  4037. if ( key === "disabled" ) {
  4038. this.headers.add( this.headers.next() )
  4039. .toggleClass( "ui-state-disabled", !!value );
  4040. }
  4041. },
  4042. _keydown: function( event ) {
  4043. if ( event.altKey || event.ctrlKey ) {
  4044. return;
  4045. }
  4046. var keyCode = $.ui.keyCode,
  4047. length = this.headers.length,
  4048. currentIndex = this.headers.index( event.target ),
  4049. toFocus = false;
  4050. switch ( event.keyCode ) {
  4051. case keyCode.RIGHT:
  4052. case keyCode.DOWN:
  4053. toFocus = this.headers[ ( currentIndex + 1 ) % length ];
  4054. break;
  4055. case keyCode.LEFT:
  4056. case keyCode.UP:
  4057. toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
  4058. break;
  4059. case keyCode.SPACE:
  4060. case keyCode.ENTER:
  4061. this._eventHandler( event );
  4062. break;
  4063. case keyCode.HOME:
  4064. toFocus = this.headers[ 0 ];
  4065. break;
  4066. case keyCode.END:
  4067. toFocus = this.headers[ length - 1 ];
  4068. break;
  4069. }
  4070. if ( toFocus ) {
  4071. $( event.target ).attr( "tabIndex", -1 );
  4072. $( toFocus ).attr( "tabIndex", 0 );
  4073. toFocus.focus();
  4074. event.preventDefault();
  4075. }
  4076. },
  4077. _panelKeyDown : function( event ) {
  4078. if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
  4079. $( event.currentTarget ).prev().focus();
  4080. }
  4081. },
  4082. refresh: function() {
  4083. var maxHeight, overflow,
  4084. heightStyle = this.options.heightStyle,
  4085. parent = this.element.parent();
  4086. if ( heightStyle === "fill" ) {
  4087. // IE 6 treats height like minHeight, so we need to turn off overflow
  4088. // in order to get a reliable height
  4089. // we use the minHeight support test because we assume that only
  4090. // browsers that don't support minHeight will treat height as minHeight
  4091. if ( !$.support.minHeight ) {
  4092. overflow = parent.css( "overflow" );
  4093. parent.css( "overflow", "hidden");
  4094. }
  4095. maxHeight = parent.height();
  4096. this.element.siblings( ":visible" ).each(function() {
  4097. var elem = $( this ),
  4098. position = elem.css( "position" );
  4099. if ( position === "absolute" || position === "fixed" ) {
  4100. return;
  4101. }
  4102. maxHeight -= elem.outerHeight( true );
  4103. });
  4104. if ( overflow ) {
  4105. parent.css( "overflow", overflow );
  4106. }
  4107. this.headers.each(function() {
  4108. maxHeight -= $( this ).outerHeight( true );
  4109. });
  4110. this.headers.next()
  4111. .each(function() {
  4112. $( this ).height( Math.max( 0, maxHeight -
  4113. $( this ).innerHeight() + $( this ).height() ) );
  4114. })
  4115. .css( "overflow", "auto" );
  4116. } else if ( heightStyle === "auto" ) {
  4117. maxHeight = 0;
  4118. this.headers.next()
  4119. .each(function() {
  4120. maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
  4121. })
  4122. .height( maxHeight );
  4123. }
  4124. },
  4125. _activate: function( index ) {
  4126. var active = this._findActive( index )[ 0 ];
  4127. // trying to activate the already active panel
  4128. if ( active === this.active[ 0 ] ) {
  4129. return;
  4130. }
  4131. // trying to collapse, simulate a click on the currently active header
  4132. active = active || this.active[ 0 ];
  4133. this._eventHandler({
  4134. target: active,
  4135. currentTarget: active,
  4136. preventDefault: $.noop
  4137. });
  4138. },
  4139. _findActive: function( selector ) {
  4140. return typeof selector === "number" ? this.headers.eq( selector ) : $();
  4141. },
  4142. _setupEvents: function( event ) {
  4143. var events = {};
  4144. if ( !event ) {
  4145. return;
  4146. }
  4147. $.each( event.split(" "), function( index, eventName ) {
  4148. events[ eventName ] = "_eventHandler";
  4149. });
  4150. this._on( this.headers, events );
  4151. },
  4152. _eventHandler: function( event ) {
  4153. var options = this.options,
  4154. active = this.active,
  4155. clicked = $( event.currentTarget ),
  4156. clickedIsActive = clicked[ 0 ] === active[ 0 ],
  4157. collapsing = clickedIsActive && options.collapsible,
  4158. toShow = collapsing ? $() : clicked.next(),
  4159. toHide = active.next(),
  4160. eventData = {
  4161. oldHeader: active,
  4162. oldPanel: toHide,
  4163. newHeader: collapsing ? $() : clicked,
  4164. newPanel: toShow
  4165. };
  4166. event.preventDefault();
  4167. if (
  4168. // click on active header, but not collapsible
  4169. ( clickedIsActive && !options.collapsible ) ||
  4170. // allow canceling activation
  4171. ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
  4172. return;
  4173. }
  4174. options.active = collapsing ? false : this.headers.index( clicked );
  4175. // when the call to ._toggle() comes after the class changes
  4176. // it causes a very odd bug in IE 8 (see #6720)
  4177. this.active = clickedIsActive ? $() : clicked;
  4178. this._toggle( eventData );
  4179. // switch classes
  4180. // corner classes on the previously active header stay after the animation
  4181. active.removeClass( "ui-accordion-header-active ui-state-active" );
  4182. if ( options.icons ) {
  4183. active.children( ".ui-accordion-header-icon" )
  4184. .removeClass( options.icons.activeHeader )
  4185. .addClass( options.icons.header );
  4186. }
  4187. if ( !clickedIsActive ) {
  4188. clicked
  4189. .removeClass( "ui-corner-all" )
  4190. .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
  4191. if ( options.icons ) {
  4192. clicked.children( ".ui-accordion-header-icon" )
  4193. .removeClass( options.icons.header )
  4194. .addClass( options.icons.activeHeader );
  4195. }
  4196. clicked
  4197. .next()
  4198. .addClass( "ui-accordion-content-active" );
  4199. }
  4200. },
  4201. _toggle: function( data ) {
  4202. var toShow = data.newPanel,
  4203. toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
  4204. // handle activating a panel during the animation for another activation
  4205. this.prevShow.add( this.prevHide ).stop( true, true );
  4206. this.prevShow = toShow;
  4207. this.prevHide = toHide;
  4208. if ( this.options.animate ) {
  4209. this._animate( toShow, toHide, data );
  4210. } else {
  4211. toHide.hide();
  4212. toShow.show();
  4213. this._toggleComplete( data );
  4214. }
  4215. toHide.attr({
  4216. "aria-expanded": "false",
  4217. "aria-hidden": "true"
  4218. });
  4219. toHide.prev().attr( "aria-selected", "false" );
  4220. // if we're switching panels, remove the old header from the tab order
  4221. // if we're opening from collapsed state, remove the previous header from the tab order
  4222. // if we're collapsing, then keep the collapsing header in the tab order
  4223. if ( toShow.length && toHide.length ) {
  4224. toHide.prev().attr( "tabIndex", -1 );
  4225. } else if ( toShow.length ) {
  4226. this.headers.filter(function() {
  4227. return $( this ).attr( "tabIndex" ) === 0;
  4228. })
  4229. .attr( "tabIndex", -1 );
  4230. }
  4231. toShow
  4232. .attr({
  4233. "aria-expanded": "true",
  4234. "aria-hidden": "false"
  4235. })
  4236. .prev()
  4237. .attr({
  4238. "aria-selected": "true",
  4239. tabIndex: 0
  4240. });
  4241. },
  4242. _animate: function( toShow, toHide, data ) {
  4243. var total, easing, duration,
  4244. that = this,
  4245. adjust = 0,
  4246. down = toShow.length &&
  4247. ( !toHide.length || ( toShow.index() < toHide.index() ) ),
  4248. animate = this.options.animate || {},
  4249. options = down && animate.down || animate,
  4250. complete = function() {
  4251. that._toggleComplete( data );
  4252. };
  4253. if ( typeof options === "number" ) {
  4254. duration = options;
  4255. }
  4256. if ( typeof options === "string" ) {
  4257. easing = options;
  4258. }
  4259. // fall back from options to animation in case of partial down settings
  4260. easing = easing || options.easing || animate.easing;
  4261. duration = duration || options.duration || animate.duration;
  4262. if ( !toHide.length ) {
  4263. return toShow.animate( showProps, duration, easing, complete );
  4264. }
  4265. if ( !toShow.length ) {
  4266. return toHide.animate( hideProps, duration, easing, complete );
  4267. }
  4268. total = toShow.show().outerHeight();
  4269. toHide.animate( hideProps, {
  4270. duration: duration,
  4271. easing: easing,
  4272. step: function( now, fx ) {
  4273. fx.now = Math.round( now );
  4274. }
  4275. });
  4276. toShow
  4277. .hide()
  4278. .animate( showProps, {
  4279. duration: duration,
  4280. easing: easing,
  4281. complete: complete,
  4282. step: function( now, fx ) {
  4283. fx.now = Math.round( now );
  4284. if ( fx.prop !== "height" ) {
  4285. adjust += fx.now;
  4286. } else if ( that.options.heightStyle !== "content" ) {
  4287. fx.now = Math.round( total - toHide.outerHeight() - adjust );
  4288. adjust = 0;
  4289. }
  4290. }
  4291. });
  4292. },
  4293. _toggleComplete: function( data ) {
  4294. var toHide = data.oldPanel;
  4295. toHide
  4296. .removeClass( "ui-accordion-content-active" )
  4297. .prev()
  4298. .removeClass( "ui-corner-top" )
  4299. .addClass( "ui-corner-all" );
  4300. // Work around for rendering bug in IE (#5421)
  4301. if ( toHide.length ) {
  4302. toHide.parent()[0].className = toHide.parent()[0].className;
  4303. }
  4304. this._trigger( "activate", null, data );
  4305. }
  4306. });
  4307. // DEPRECATED
  4308. if ( $.uiBackCompat !== false ) {
  4309. // navigation options
  4310. (function( $, prototype ) {
  4311. $.extend( prototype.options, {
  4312. navigation: false,
  4313. navigationFilter: function() {
  4314. return this.href.toLowerCase() === location.href.toLowerCase();
  4315. }
  4316. });
  4317. var _create = prototype._create;
  4318. prototype._create = function() {
  4319. if ( this.options.navigation ) {
  4320. var that = this,
  4321. headers = this.element.find( this.options.header ),
  4322. content = headers.next(),
  4323. current = headers.add( content )
  4324. .find( "a" )
  4325. .filter( this.options.navigationFilter )
  4326. [ 0 ];
  4327. if ( current ) {
  4328. headers.add( content ).each( function( index ) {
  4329. if ( $.contains( this, current ) ) {
  4330. that.options.active = Math.floor( index / 2 );
  4331. return false;
  4332. }
  4333. });
  4334. }
  4335. }
  4336. _create.call( this );
  4337. };
  4338. }( jQuery, jQuery.ui.accordion.prototype ) );
  4339. // height options
  4340. (function( $, prototype ) {
  4341. $.extend( prototype.options, {
  4342. heightStyle: null, // remove default so we fall back to old values
  4343. autoHeight: true, // use heightStyle: "auto"
  4344. clearStyle: false, // use heightStyle: "content"
  4345. fillSpace: false // use heightStyle: "fill"
  4346. });
  4347. var _create = prototype._create,
  4348. _setOption = prototype._setOption;
  4349. $.extend( prototype, {
  4350. _create: function() {
  4351. this.options.heightStyle = this.options.heightStyle ||
  4352. this._mergeHeightStyle();
  4353. _create.call( this );
  4354. },
  4355. _setOption: function( key ) {
  4356. if ( key === "autoHeight" || key === "clearStyle" || key === "fillSpace" ) {
  4357. this.options.heightStyle = this._mergeHeightStyle();
  4358. }
  4359. _setOption.apply( this, arguments );
  4360. },
  4361. _mergeHeightStyle: function() {
  4362. var options = this.options;
  4363. if ( options.fillSpace ) {
  4364. return "fill";
  4365. }
  4366. if ( options.clearStyle ) {
  4367. return "content";
  4368. }
  4369. if ( options.autoHeight ) {
  4370. return "auto";
  4371. }
  4372. }
  4373. });
  4374. }( jQuery, jQuery.ui.accordion.prototype ) );
  4375. // icon options
  4376. (function( $, prototype ) {
  4377. $.extend( prototype.options.icons, {
  4378. activeHeader: null, // remove default so we fall back to old values
  4379. headerSelected: "ui-icon-triangle-1-s"
  4380. });
  4381. var _createIcons = prototype._createIcons;
  4382. prototype._createIcons = function() {
  4383. if ( this.options.icons ) {
  4384. this.options.icons.activeHeader = this.options.icons.activeHeader ||
  4385. this.options.icons.headerSelected;
  4386. }
  4387. _createIcons.call( this );
  4388. };
  4389. }( jQuery, jQuery.ui.accordion.prototype ) );
  4390. // expanded active option, activate method
  4391. (function( $, prototype ) {
  4392. prototype.activate = prototype._activate;
  4393. var _findActive = prototype._findActive;
  4394. prototype._findActive = function( index ) {
  4395. if ( index === -1 ) {
  4396. index = false;
  4397. }
  4398. if ( index && typeof index !== "number" ) {
  4399. index = this.headers.index( this.headers.filter( index ) );
  4400. if ( index === -1 ) {
  4401. index = false;
  4402. }
  4403. }
  4404. return _findActive.call( this, index );
  4405. };
  4406. }( jQuery, jQuery.ui.accordion.prototype ) );
  4407. // resize method
  4408. jQuery.ui.accordion.prototype.resize = jQuery.ui.accordion.prototype.refresh;
  4409. // change events
  4410. (function( $, prototype ) {
  4411. $.extend( prototype.options, {
  4412. change: null,
  4413. changestart: null
  4414. });
  4415. var _trigger = prototype._trigger;
  4416. prototype._trigger = function( type, event, data ) {
  4417. var ret = _trigger.apply( this, arguments );
  4418. if ( !ret ) {
  4419. return false;
  4420. }
  4421. if ( type === "beforeActivate" ) {
  4422. ret = _trigger.call( this, "changestart", event, {
  4423. oldHeader: data.oldHeader,
  4424. oldContent: data.oldPanel,
  4425. newHeader: data.newHeader,
  4426. newContent: data.newPanel
  4427. });
  4428. } else if ( type === "activate" ) {
  4429. ret = _trigger.call( this, "change", event, {
  4430. oldHeader: data.oldHeader,
  4431. oldContent: data.oldPanel,
  4432. newHeader: data.newHeader,
  4433. newContent: data.newPanel
  4434. });
  4435. }
  4436. return ret;
  4437. };
  4438. }( jQuery, jQuery.ui.accordion.prototype ) );
  4439. // animated option
  4440. // NOTE: this only provides support for "slide", "bounceslide", and easings
  4441. // not the full $.ui.accordion.animations API
  4442. (function( $, prototype ) {
  4443. $.extend( prototype.options, {
  4444. animate: null,
  4445. animated: "slide"
  4446. });
  4447. var _create = prototype._create;
  4448. prototype._create = function() {
  4449. var options = this.options;
  4450. if ( options.animate === null ) {
  4451. if ( !options.animated ) {
  4452. options.animate = false;
  4453. } else if ( options.animated === "slide" ) {
  4454. options.animate = 300;
  4455. } else if ( options.animated === "bounceslide" ) {
  4456. options.animate = {
  4457. duration: 200,
  4458. down: {
  4459. easing: "easeOutBounce",
  4460. duration: 1000
  4461. }
  4462. };
  4463. } else {
  4464. options.animate = options.animated;
  4465. }
  4466. }
  4467. _create.call( this );
  4468. };
  4469. }( jQuery, jQuery.ui.accordion.prototype ) );
  4470. }
  4471. })( jQuery );
  4472. (function( $, undefined ) {
  4473. // used to prevent race conditions with remote data sources
  4474. var requestIndex = 0;
  4475. $.widget( "ui.autocomplete", {
  4476. version: "1.9.1",
  4477. defaultElement: "<input>",
  4478. options: {
  4479. appendTo: "body",
  4480. autoFocus: false,
  4481. delay: 300,
  4482. minLength: 1,
  4483. position: {
  4484. my: "left top",
  4485. at: "left bottom",
  4486. collision: "none"
  4487. },
  4488. source: null,
  4489. // callbacks
  4490. change: null,
  4491. close: null,
  4492. focus: null,
  4493. open: null,
  4494. response: null,
  4495. search: null,
  4496. select: null
  4497. },
  4498. pending: 0,
  4499. _create: function() {
  4500. // Some browsers only repeat keydown events, not keypress events,
  4501. // so we use the suppressKeyPress flag to determine if we've already
  4502. // handled the keydown event. #7269
  4503. // Unfortunately the code for & in keypress is the same as the up arrow,
  4504. // so we use the suppressKeyPressRepeat flag to avoid handling keypress
  4505. // events when we know the keydown event was used to modify the
  4506. // search term. #7799
  4507. var suppressKeyPress, suppressKeyPressRepeat, suppressInput;
  4508. this.isMultiLine = this._isMultiLine();
  4509. this.valueMethod = this.element[ this.element.is( "input,textarea" ) ? "val" : "text" ];
  4510. this.isNewMenu = true;
  4511. this.element
  4512. .addClass( "ui-autocomplete-input" )
  4513. .attr( "autocomplete", "off" );
  4514. this._on( this.element, {
  4515. keydown: function( event ) {
  4516. if ( this.element.prop( "readOnly" ) ) {
  4517. suppressKeyPress = true;
  4518. suppressInput = true;
  4519. suppressKeyPressRepeat = true;
  4520. return;
  4521. }
  4522. suppressKeyPress = false;
  4523. suppressInput = false;
  4524. suppressKeyPressRepeat = false;
  4525. var keyCode = $.ui.keyCode;
  4526. switch( event.keyCode ) {
  4527. case keyCode.PAGE_UP:
  4528. suppressKeyPress = true;
  4529. this._move( "previousPage", event );
  4530. break;
  4531. case keyCode.PAGE_DOWN:
  4532. suppressKeyPress = true;
  4533. this._move( "nextPage", event );
  4534. break;
  4535. case keyCode.UP:
  4536. suppressKeyPress = true;
  4537. this._keyEvent( "previous", event );
  4538. break;
  4539. case keyCode.DOWN:
  4540. suppressKeyPress = true;
  4541. this._keyEvent( "next", event );
  4542. break;
  4543. case keyCode.ENTER:
  4544. case keyCode.NUMPAD_ENTER:
  4545. // when menu is open and has focus
  4546. if ( this.menu.active ) {
  4547. // #6055 - Opera still allows the keypress to occur
  4548. // which causes forms to submit
  4549. suppressKeyPress = true;
  4550. event.preventDefault();
  4551. this.menu.select( event );
  4552. }
  4553. break;
  4554. case keyCode.TAB:
  4555. if ( this.menu.active ) {
  4556. this.menu.select( event );
  4557. }
  4558. break;
  4559. case keyCode.ESCAPE:
  4560. if ( this.menu.element.is( ":visible" ) ) {
  4561. this._value( this.term );
  4562. this.close( event );
  4563. // Different browsers have different default behavior for escape
  4564. // Single press can mean undo or clear
  4565. // Double press in IE means clear the whole form
  4566. event.preventDefault();
  4567. }
  4568. break;
  4569. default:
  4570. suppressKeyPressRepeat = true;
  4571. // search timeout should be triggered before the input value is changed
  4572. this._searchTimeout( event );
  4573. break;
  4574. }
  4575. },
  4576. keypress: function( event ) {
  4577. if ( suppressKeyPress ) {
  4578. suppressKeyPress = false;
  4579. event.preventDefault();
  4580. return;
  4581. }
  4582. if ( suppressKeyPressRepeat ) {
  4583. return;
  4584. }
  4585. // replicate some key handlers to allow them to repeat in Firefox and Opera
  4586. var keyCode = $.ui.keyCode;
  4587. switch( event.keyCode ) {
  4588. case keyCode.PAGE_UP:
  4589. this._move( "previousPage", event );
  4590. break;
  4591. case keyCode.PAGE_DOWN:
  4592. this._move( "nextPage", event );
  4593. break;
  4594. case keyCode.UP:
  4595. this._keyEvent( "previous", event );
  4596. break;
  4597. case keyCode.DOWN:
  4598. this._keyEvent( "next", event );
  4599. break;
  4600. }
  4601. },
  4602. input: function( event ) {
  4603. if ( suppressInput ) {
  4604. suppressInput = false;
  4605. event.preventDefault();
  4606. return;
  4607. }
  4608. this._searchTimeout( event );
  4609. },
  4610. focus: function() {
  4611. this.selectedItem = null;
  4612. this.previous = this._value();
  4613. },
  4614. blur: function( event ) {
  4615. if ( this.cancelBlur ) {
  4616. delete this.cancelBlur;
  4617. return;
  4618. }
  4619. clearTimeout( this.searching );
  4620. this.close( event );
  4621. this._change( event );
  4622. }
  4623. });
  4624. this._initSource();
  4625. this.menu = $( "<ul>" )
  4626. .addClass( "ui-autocomplete" )
  4627. .appendTo( this.document.find( this.options.appendTo || "body" )[ 0 ] )
  4628. .menu({
  4629. // custom key handling for now
  4630. input: $(),
  4631. // disable ARIA support, the live region takes care of that
  4632. role: null
  4633. })
  4634. .zIndex( this.element.zIndex() + 1 )
  4635. .hide()
  4636. .data( "menu" );
  4637. this._on( this.menu.element, {
  4638. mousedown: function( event ) {
  4639. // prevent moving focus out of the text field
  4640. event.preventDefault();
  4641. // IE doesn't prevent moving focus even with event.preventDefault()
  4642. // so we set a flag to know when we should ignore the blur event
  4643. this.cancelBlur = true;
  4644. this._delay(function() {
  4645. delete this.cancelBlur;
  4646. });
  4647. // clicking on the scrollbar causes focus to shift to the body
  4648. // but we can't detect a mouseup or a click immediately afterward
  4649. // so we have to track the next mousedown and close the menu if
  4650. // the user clicks somewhere outside of the autocomplete
  4651. var menuElement = this.menu.element[ 0 ];
  4652. if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
  4653. this._delay(function() {
  4654. var that = this;
  4655. this.document.one( "mousedown", function( event ) {
  4656. if ( event.target !== that.element[ 0 ] &&
  4657. event.target !== menuElement &&
  4658. !$.contains( menuElement, event.target ) ) {
  4659. that.close();
  4660. }
  4661. });
  4662. });
  4663. }
  4664. },
  4665. menufocus: function( event, ui ) {
  4666. // #7024 - Prevent accidental activation of menu items in Firefox
  4667. if ( this.isNewMenu ) {
  4668. this.isNewMenu = false;
  4669. if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
  4670. this.menu.blur();
  4671. this.document.one( "mousemove", function() {
  4672. $( event.target ).trigger( event.originalEvent );
  4673. });
  4674. return;
  4675. }
  4676. }
  4677. // back compat for _renderItem using item.autocomplete, via #7810
  4678. // TODO remove the fallback, see #8156
  4679. var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" );
  4680. if ( false !== this._trigger( "focus", event, { item: item } ) ) {
  4681. // use value to match what will end up in the input, if it was a key event
  4682. if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
  4683. this._value( item.value );
  4684. }
  4685. } else {
  4686. // Normally the input is populated with the item's value as the
  4687. // menu is navigated, causing screen readers to notice a change and
  4688. // announce the item. Since the focus event was canceled, this doesn't
  4689. // happen, so we update the live region so that screen readers can
  4690. // still notice the change and announce it.
  4691. this.liveRegion.text( item.value );
  4692. }
  4693. },
  4694. menuselect: function( event, ui ) {
  4695. // back compat for _renderItem using item.autocomplete, via #7810
  4696. // TODO remove the fallback, see #8156
  4697. var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" ),
  4698. previous = this.previous;
  4699. // only trigger when focus was lost (click on menu)
  4700. if ( this.element[0] !== this.document[0].activeElement ) {
  4701. this.element.focus();
  4702. this.previous = previous;
  4703. // #6109 - IE triggers two focus events and the second
  4704. // is asynchronous, so we need to reset the previous
  4705. // term synchronously and asynchronously :-(
  4706. this._delay(function() {
  4707. this.previous = previous;
  4708. this.selectedItem = item;
  4709. });
  4710. }
  4711. if ( false !== this._trigger( "select", event, { item: item } ) ) {
  4712. this._value( item.value );
  4713. }
  4714. // reset the term after the select event
  4715. // this allows custom select handling to work properly
  4716. this.term = this._value();
  4717. this.close( event );
  4718. this.selectedItem = item;
  4719. }
  4720. });
  4721. this.liveRegion = $( "<span>", {
  4722. role: "status",
  4723. "aria-live": "polite"
  4724. })
  4725. .addClass( "ui-helper-hidden-accessible" )
  4726. .insertAfter( this.element );
  4727. if ( $.fn.bgiframe ) {
  4728. this.menu.element.bgiframe();
  4729. }
  4730. // turning off autocomplete prevents the browser from remembering the
  4731. // value when navigating through history, so we re-enable autocomplete
  4732. // if the page is unloaded before the widget is destroyed. #7790
  4733. this._on( this.window, {
  4734. beforeunload: function() {
  4735. this.element.removeAttr( "autocomplete" );
  4736. }
  4737. });
  4738. },
  4739. _destroy: function() {
  4740. clearTimeout( this.searching );
  4741. this.element
  4742. .removeClass( "ui-autocomplete-input" )
  4743. .removeAttr( "autocomplete" );
  4744. this.menu.element.remove();
  4745. this.liveRegion.remove();
  4746. },
  4747. _setOption: function( key, value ) {
  4748. this._super( key, value );
  4749. if ( key === "source" ) {
  4750. this._initSource();
  4751. }
  4752. if ( key === "appendTo" ) {
  4753. this.menu.element.appendTo( this.document.find( value || "body" )[0] );
  4754. }
  4755. if ( key === "disabled" && value && this.xhr ) {
  4756. this.xhr.abort();
  4757. }
  4758. },
  4759. _isMultiLine: function() {
  4760. // Textareas are always multi-line
  4761. if ( this.element.is( "textarea" ) ) {
  4762. return true;
  4763. }
  4764. // Inputs are always single-line, even if inside a contentEditable element
  4765. // IE also treats inputs as contentEditable
  4766. if ( this.element.is( "input" ) ) {
  4767. return false;
  4768. }
  4769. // All other element types are determined by whether or not they're contentEditable
  4770. return this.element.prop( "isContentEditable" );
  4771. },
  4772. _initSource: function() {
  4773. var array, url,
  4774. that = this;
  4775. if ( $.isArray(this.options.source) ) {
  4776. array = this.options.source;
  4777. this.source = function( request, response ) {
  4778. response( $.ui.autocomplete.filter( array, request.term ) );
  4779. };
  4780. } else if ( typeof this.options.source === "string" ) {
  4781. url = this.options.source;
  4782. this.source = function( request, response ) {
  4783. if ( that.xhr ) {
  4784. that.xhr.abort();
  4785. }
  4786. that.xhr = $.ajax({
  4787. url: url,
  4788. data: request,
  4789. dataType: "json",
  4790. success: function( data ) {
  4791. response( data );
  4792. },
  4793. error: function() {
  4794. response( [] );
  4795. }
  4796. });
  4797. };
  4798. } else {
  4799. this.source = this.options.source;
  4800. }
  4801. },
  4802. _searchTimeout: function( event ) {
  4803. clearTimeout( this.searching );
  4804. this.searching = this._delay(function() {
  4805. // only search if the value has changed
  4806. if ( this.term !== this._value() ) {
  4807. this.selectedItem = null;
  4808. this.search( null, event );
  4809. }
  4810. }, this.options.delay );
  4811. },
  4812. search: function( value, event ) {
  4813. value = value != null ? value : this._value();
  4814. // always save the actual value, not the one passed as an argument
  4815. this.term = this._value();
  4816. if ( value.length < this.options.minLength ) {
  4817. return this.close( event );
  4818. }
  4819. if ( this._trigger( "search", event ) === false ) {
  4820. return;
  4821. }
  4822. return this._search( value );
  4823. },
  4824. _search: function( value ) {
  4825. this.pending++;
  4826. this.element.addClass( "ui-autocomplete-loading" );
  4827. this.cancelSearch = false;
  4828. this.source( { term: value }, this._response() );
  4829. },
  4830. _response: function() {
  4831. var that = this,
  4832. index = ++requestIndex;
  4833. return function( content ) {
  4834. if ( index === requestIndex ) {
  4835. that.__response( content );
  4836. }
  4837. that.pending--;
  4838. if ( !that.pending ) {
  4839. that.element.removeClass( "ui-autocomplete-loading" );
  4840. }
  4841. };
  4842. },
  4843. __response: function( content ) {
  4844. if ( content ) {
  4845. content = this._normalize( content );
  4846. }
  4847. this._trigger( "response", null, { content: content } );
  4848. if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
  4849. this._suggest( content );
  4850. this._trigger( "open" );
  4851. } else {
  4852. // use ._close() instead of .close() so we don't cancel future searches
  4853. this._close();
  4854. }
  4855. },
  4856. close: function( event ) {
  4857. this.cancelSearch = true;
  4858. this._close( event );
  4859. },
  4860. _close: function( event ) {
  4861. if ( this.menu.element.is( ":visible" ) ) {
  4862. this.menu.element.hide();
  4863. this.menu.blur();
  4864. this.isNewMenu = true;
  4865. this._trigger( "close", event );
  4866. }
  4867. },
  4868. _change: function( event ) {
  4869. if ( this.previous !== this._value() ) {
  4870. this._trigger( "change", event, { item: this.selectedItem } );
  4871. }
  4872. },
  4873. _normalize: function( items ) {
  4874. // assume all items have the right format when the first item is complete
  4875. if ( items.length && items[0].label && items[0].value ) {
  4876. return items;
  4877. }
  4878. return $.map( items, function( item ) {
  4879. if ( typeof item === "string" ) {
  4880. return {
  4881. label: item,
  4882. value: item
  4883. };
  4884. }
  4885. return $.extend({
  4886. label: item.label || item.value,
  4887. value: item.value || item.label
  4888. }, item );
  4889. });
  4890. },
  4891. _suggest: function( items ) {
  4892. var ul = this.menu.element
  4893. .empty()
  4894. .zIndex( this.element.zIndex() + 1 );
  4895. this._renderMenu( ul, items );
  4896. this.menu.refresh();
  4897. // size and position menu
  4898. ul.show();
  4899. this._resizeMenu();
  4900. ul.position( $.extend({
  4901. of: this.element
  4902. }, this.options.position ));
  4903. if ( this.options.autoFocus ) {
  4904. this.menu.next();
  4905. }
  4906. },
  4907. _resizeMenu: function() {
  4908. var ul = this.menu.element;
  4909. ul.outerWidth( Math.max(
  4910. // Firefox wraps long text (possibly a rounding bug)
  4911. // so we add 1px to avoid the wrapping (#7513)
  4912. ul.width( "" ).outerWidth() + 1,
  4913. this.element.outerWidth()
  4914. ) );
  4915. },
  4916. _renderMenu: function( ul, items ) {
  4917. var that = this;
  4918. $.each( items, function( index, item ) {
  4919. that._renderItemData( ul, item );
  4920. });
  4921. },
  4922. _renderItemData: function( ul, item ) {
  4923. return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
  4924. },
  4925. _renderItem: function( ul, item ) {
  4926. return $( "<li>" )
  4927. .append( $( "<a>" ).text( item.label ) )
  4928. .appendTo( ul );
  4929. },
  4930. _move: function( direction, event ) {
  4931. if ( !this.menu.element.is( ":visible" ) ) {
  4932. this.search( null, event );
  4933. return;
  4934. }
  4935. if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
  4936. this.menu.isLastItem() && /^next/.test( direction ) ) {
  4937. this._value( this.term );
  4938. this.menu.blur();
  4939. return;
  4940. }
  4941. this.menu[ direction ]( event );
  4942. },
  4943. widget: function() {
  4944. return this.menu.element;
  4945. },
  4946. _value: function() {
  4947. return this.valueMethod.apply( this.element, arguments );
  4948. },
  4949. _keyEvent: function( keyEvent, event ) {
  4950. if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
  4951. this._move( keyEvent, event );
  4952. // prevents moving cursor to beginning/end of the text field in some browsers
  4953. event.preventDefault();
  4954. }
  4955. }
  4956. });
  4957. $.extend( $.ui.autocomplete, {
  4958. escapeRegex: function( value ) {
  4959. return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
  4960. },
  4961. filter: function(array, term) {
  4962. var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
  4963. return $.grep( array, function(value) {
  4964. return matcher.test( value.label || value.value || value );
  4965. });
  4966. }
  4967. });
  4968. // live region extension, adding a `messages` option
  4969. // NOTE: This is an experimental API. We are still investigating
  4970. // a full solution for string manipulation and internationalization.
  4971. $.widget( "ui.autocomplete", $.ui.autocomplete, {
  4972. options: {
  4973. messages: {
  4974. noResults: "No search results.",
  4975. results: function( amount ) {
  4976. return amount + ( amount > 1 ? " results are" : " result is" ) +
  4977. " available, use up and down arrow keys to navigate.";
  4978. }
  4979. }
  4980. },
  4981. __response: function( content ) {
  4982. var message;
  4983. this._superApply( arguments );
  4984. if ( this.options.disabled || this.cancelSearch ) {
  4985. return;
  4986. }
  4987. if ( content && content.length ) {
  4988. message = this.options.messages.results( content.length );
  4989. } else {
  4990. message = this.options.messages.noResults;
  4991. }
  4992. this.liveRegion.text( message );
  4993. }
  4994. });
  4995. }( jQuery ));
  4996. (function( $, undefined ) {
  4997. var lastActive, startXPos, startYPos, clickDragged,
  4998. baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
  4999. stateClasses = "ui-state-hover ui-state-active ",
  5000. 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",
  5001. formResetHandler = function() {
  5002. var buttons = $( this ).find( ":ui-button" );
  5003. setTimeout(function() {
  5004. buttons.button( "refresh" );
  5005. }, 1 );
  5006. },
  5007. radioGroup = function( radio ) {
  5008. var name = radio.name,
  5009. form = radio.form,
  5010. radios = $( [] );
  5011. if ( name ) {
  5012. if ( form ) {
  5013. radios = $( form ).find( "[name='" + name + "']" );
  5014. } else {
  5015. radios = $( "[name='" + name + "']", radio.ownerDocument )
  5016. .filter(function() {
  5017. return !this.form;
  5018. });
  5019. }
  5020. }
  5021. return radios;
  5022. };
  5023. $.widget( "ui.button", {
  5024. version: "1.9.1",
  5025. defaultElement: "<button>",
  5026. options: {
  5027. disabled: null,
  5028. text: true,
  5029. label: null,
  5030. icons: {
  5031. primary: null,
  5032. secondary: null
  5033. }
  5034. },
  5035. _create: function() {
  5036. this.element.closest( "form" )
  5037. .unbind( "reset" + this.eventNamespace )
  5038. .bind( "reset" + this.eventNamespace, formResetHandler );
  5039. if ( typeof this.options.disabled !== "boolean" ) {
  5040. this.options.disabled = !!this.element.prop( "disabled" );
  5041. } else {
  5042. this.element.prop( "disabled", this.options.disabled );
  5043. }
  5044. this._determineButtonType();
  5045. this.hasTitle = !!this.buttonElement.attr( "title" );
  5046. var that = this,
  5047. options = this.options,
  5048. toggleButton = this.type === "checkbox" || this.type === "radio",
  5049. hoverClass = "ui-state-hover" + ( !toggleButton ? " ui-state-active" : "" ),
  5050. focusClass = "ui-state-focus";
  5051. if ( options.label === null ) {
  5052. options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
  5053. }
  5054. this.buttonElement
  5055. .addClass( baseClasses )
  5056. .attr( "role", "button" )
  5057. .bind( "mouseenter" + this.eventNamespace, function() {
  5058. if ( options.disabled ) {
  5059. return;
  5060. }
  5061. $( this ).addClass( "ui-state-hover" );
  5062. if ( this === lastActive ) {
  5063. $( this ).addClass( "ui-state-active" );
  5064. }
  5065. })
  5066. .bind( "mouseleave" + this.eventNamespace, function() {
  5067. if ( options.disabled ) {
  5068. return;
  5069. }
  5070. $( this ).removeClass( hoverClass );
  5071. })
  5072. .bind( "click" + this.eventNamespace, function( event ) {
  5073. if ( options.disabled ) {
  5074. event.preventDefault();
  5075. event.stopImmediatePropagation();
  5076. }
  5077. });
  5078. this.element
  5079. .bind( "focus" + this.eventNamespace, function() {
  5080. // no need to check disabled, focus won't be triggered anyway
  5081. that.buttonElement.addClass( focusClass );
  5082. })
  5083. .bind( "blur" + this.eventNamespace, function() {
  5084. that.buttonElement.removeClass( focusClass );
  5085. });
  5086. if ( toggleButton ) {
  5087. this.element.bind( "change" + this.eventNamespace, function() {
  5088. if ( clickDragged ) {
  5089. return;
  5090. }
  5091. that.refresh();
  5092. });
  5093. // if mouse moves between mousedown and mouseup (drag) set clickDragged flag
  5094. // prevents issue where button state changes but checkbox/radio checked state
  5095. // does not in Firefox (see ticket #6970)
  5096. this.buttonElement
  5097. .bind( "mousedown" + this.eventNamespace, function( event ) {
  5098. if ( options.disabled ) {
  5099. return;
  5100. }
  5101. clickDragged = false;
  5102. startXPos = event.pageX;
  5103. startYPos = event.pageY;
  5104. })
  5105. .bind( "mouseup" + this.eventNamespace, function( event ) {
  5106. if ( options.disabled ) {
  5107. return;
  5108. }
  5109. if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
  5110. clickDragged = true;
  5111. }
  5112. });
  5113. }
  5114. if ( this.type === "checkbox" ) {
  5115. this.buttonElement.bind( "click" + this.eventNamespace, function() {
  5116. if ( options.disabled || clickDragged ) {
  5117. return false;
  5118. }
  5119. $( this ).toggleClass( "ui-state-active" );
  5120. that.buttonElement.attr( "aria-pressed", that.element[0].checked );
  5121. });
  5122. } else if ( this.type === "radio" ) {
  5123. this.buttonElement.bind( "click" + this.eventNamespace, function() {
  5124. if ( options.disabled || clickDragged ) {
  5125. return false;
  5126. }
  5127. $( this ).addClass( "ui-state-active" );
  5128. that.buttonElement.attr( "aria-pressed", "true" );
  5129. var radio = that.element[ 0 ];
  5130. radioGroup( radio )
  5131. .not( radio )
  5132. .map(function() {
  5133. return $( this ).button( "widget" )[ 0 ];
  5134. })
  5135. .removeClass( "ui-state-active" )
  5136. .attr( "aria-pressed", "false" );
  5137. });
  5138. } else {
  5139. this.buttonElement
  5140. .bind( "mousedown" + this.eventNamespace, function() {
  5141. if ( options.disabled ) {
  5142. return false;
  5143. }
  5144. $( this ).addClass( "ui-state-active" );
  5145. lastActive = this;
  5146. that.document.one( "mouseup", function() {
  5147. lastActive = null;
  5148. });
  5149. })
  5150. .bind( "mouseup" + this.eventNamespace, function() {
  5151. if ( options.disabled ) {
  5152. return false;
  5153. }
  5154. $( this ).removeClass( "ui-state-active" );
  5155. })
  5156. .bind( "keydown" + this.eventNamespace, function(event) {
  5157. if ( options.disabled ) {
  5158. return false;
  5159. }
  5160. if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
  5161. $( this ).addClass( "ui-state-active" );
  5162. }
  5163. })
  5164. .bind( "keyup" + this.eventNamespace, function() {
  5165. $( this ).removeClass( "ui-state-active" );
  5166. });
  5167. if ( this.buttonElement.is("a") ) {
  5168. this.buttonElement.keyup(function(event) {
  5169. if ( event.keyCode === $.ui.keyCode.SPACE ) {
  5170. // TODO pass through original event correctly (just as 2nd argument doesn't work)
  5171. $( this ).click();
  5172. }
  5173. });
  5174. }
  5175. }
  5176. // TODO: pull out $.Widget's handling for the disabled option into
  5177. // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
  5178. // be overridden by individual plugins
  5179. this._setOption( "disabled", options.disabled );
  5180. this._resetButton();
  5181. },
  5182. _determineButtonType: function() {
  5183. var ancestor, labelSelector, checked;
  5184. if ( this.element.is("[type=checkbox]") ) {
  5185. this.type = "checkbox";
  5186. } else if ( this.element.is("[type=radio]") ) {
  5187. this.type = "radio";
  5188. } else if ( this.element.is("input") ) {
  5189. this.type = "input";
  5190. } else {
  5191. this.type = "button";
  5192. }
  5193. if ( this.type === "checkbox" || this.type === "radio" ) {
  5194. // we don't search against the document in case the element
  5195. // is disconnected from the DOM
  5196. ancestor = this.element.parents().last();
  5197. labelSelector = "label[for='" + this.element.attr("id") + "']";
  5198. this.buttonElement = ancestor.find( labelSelector );
  5199. if ( !this.buttonElement.length ) {
  5200. ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
  5201. this.buttonElement = ancestor.filter( labelSelector );
  5202. if ( !this.buttonElement.length ) {
  5203. this.buttonElement = ancestor.find( labelSelector );
  5204. }
  5205. }
  5206. this.element.addClass( "ui-helper-hidden-accessible" );
  5207. checked = this.element.is( ":checked" );
  5208. if ( checked ) {
  5209. this.buttonElement.addClass( "ui-state-active" );
  5210. }
  5211. this.buttonElement.prop( "aria-pressed", checked );
  5212. } else {
  5213. this.buttonElement = this.element;
  5214. }
  5215. },
  5216. widget: function() {
  5217. return this.buttonElement;
  5218. },
  5219. _destroy: function() {
  5220. this.element
  5221. .removeClass( "ui-helper-hidden-accessible" );
  5222. this.buttonElement
  5223. .removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
  5224. .removeAttr( "role" )
  5225. .removeAttr( "aria-pressed" )
  5226. .html( this.buttonElement.find(".ui-button-text").html() );
  5227. if ( !this.hasTitle ) {
  5228. this.buttonElement.removeAttr( "title" );
  5229. }
  5230. },
  5231. _setOption: function( key, value ) {
  5232. this._super( key, value );
  5233. if ( key === "disabled" ) {
  5234. if ( value ) {
  5235. this.element.prop( "disabled", true );
  5236. } else {
  5237. this.element.prop( "disabled", false );
  5238. }
  5239. return;
  5240. }
  5241. this._resetButton();
  5242. },
  5243. refresh: function() {
  5244. var isDisabled = this.element.is( ":disabled" ) || this.element.hasClass( "ui-button-disabled" );
  5245. if ( isDisabled !== this.options.disabled ) {
  5246. this._setOption( "disabled", isDisabled );
  5247. }
  5248. if ( this.type === "radio" ) {
  5249. radioGroup( this.element[0] ).each(function() {
  5250. if ( $( this ).is( ":checked" ) ) {
  5251. $( this ).button( "widget" )
  5252. .addClass( "ui-state-active" )
  5253. .attr( "aria-pressed", "true" );
  5254. } else {
  5255. $( this ).button( "widget" )
  5256. .removeClass( "ui-state-active" )
  5257. .attr( "aria-pressed", "false" );
  5258. }
  5259. });
  5260. } else if ( this.type === "checkbox" ) {
  5261. if ( this.element.is( ":checked" ) ) {
  5262. this.buttonElement
  5263. .addClass( "ui-state-active" )
  5264. .attr( "aria-pressed", "true" );
  5265. } else {
  5266. this.buttonElement
  5267. .removeClass( "ui-state-active" )
  5268. .attr( "aria-pressed", "false" );
  5269. }
  5270. }
  5271. },
  5272. _resetButton: function() {
  5273. if ( this.type === "input" ) {
  5274. if ( this.options.label ) {
  5275. this.element.val( this.options.label );
  5276. }
  5277. return;
  5278. }
  5279. var buttonElement = this.buttonElement.removeClass( typeClasses ),
  5280. buttonText = $( "<span></span>", this.document[0] )
  5281. .addClass( "ui-button-text" )
  5282. .html( this.options.label )
  5283. .appendTo( buttonElement.empty() )
  5284. .text(),
  5285. icons = this.options.icons,
  5286. multipleIcons = icons.primary && icons.secondary,
  5287. buttonClasses = [];
  5288. if ( icons.primary || icons.secondary ) {
  5289. if ( this.options.text ) {
  5290. buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
  5291. }
  5292. if ( icons.primary ) {
  5293. buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
  5294. }
  5295. if ( icons.secondary ) {
  5296. buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
  5297. }
  5298. if ( !this.options.text ) {
  5299. buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
  5300. if ( !this.hasTitle ) {
  5301. buttonElement.attr( "title", $.trim( buttonText ) );
  5302. }
  5303. }
  5304. } else {
  5305. buttonClasses.push( "ui-button-text-only" );
  5306. }
  5307. buttonElement.addClass( buttonClasses.join( " " ) );
  5308. }
  5309. });
  5310. $.widget( "ui.buttonset", {
  5311. version: "1.9.1",
  5312. options: {
  5313. items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(button)"
  5314. },
  5315. _create: function() {
  5316. this.element.addClass( "ui-buttonset" );
  5317. },
  5318. _init: function() {
  5319. this.refresh();
  5320. },
  5321. _setOption: function( key, value ) {
  5322. if ( key === "disabled" ) {
  5323. this.buttons.button( "option", key, value );
  5324. }
  5325. this._super( key, value );
  5326. },
  5327. refresh: function() {
  5328. var rtl = this.element.css( "direction" ) === "rtl";
  5329. this.buttons = this.element.find( this.options.items )
  5330. .filter( ":ui-button" )
  5331. .button( "refresh" )
  5332. .end()
  5333. .not( ":ui-button" )
  5334. .button()
  5335. .end()
  5336. .map(function() {
  5337. return $( this ).button( "widget" )[ 0 ];
  5338. })
  5339. .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
  5340. .filter( ":first" )
  5341. .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
  5342. .end()
  5343. .filter( ":last" )
  5344. .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
  5345. .end()
  5346. .end();
  5347. },
  5348. _destroy: function() {
  5349. this.element.removeClass( "ui-buttonset" );
  5350. this.buttons
  5351. .map(function() {
  5352. return $( this ).button( "widget" )[ 0 ];
  5353. })
  5354. .removeClass( "ui-corner-left ui-corner-right" )
  5355. .end()
  5356. .button( "destroy" );
  5357. }
  5358. });
  5359. }( jQuery ) );
  5360. (function( $, undefined ) {
  5361. $.extend($.ui, { datepicker: { version: "1.9.1" } });
  5362. var PROP_NAME = 'datepicker';
  5363. var dpuuid = new Date().getTime();
  5364. var instActive;
  5365. /* Date picker manager.
  5366. Use the singleton instance of this class, $.datepicker, to interact with the date picker.
  5367. Settings for (groups of) date pickers are maintained in an instance object,
  5368. allowing multiple different settings on the same page. */
  5369. function Datepicker() {
  5370. this.debug = false; // Change this to true to start debugging
  5371. this._curInst = null; // The current instance in use
  5372. this._keyEvent = false; // If the last event was a key event
  5373. this._disabledInputs = []; // List of date picker inputs that have been disabled
  5374. this._datepickerShowing = false; // True if the popup picker is showing , false if not
  5375. this._inDialog = false; // True if showing within a "dialog", false if not
  5376. this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
  5377. this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
  5378. this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
  5379. this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
  5380. this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
  5381. this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
  5382. this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
  5383. this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
  5384. this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
  5385. this.regional = []; // Available regional settings, indexed by language code
  5386. this.regional[''] = { // Default regional settings
  5387. closeText: 'Done', // Display text for close link
  5388. prevText: 'Prev', // Display text for previous month link
  5389. nextText: 'Next', // Display text for next month link
  5390. currentText: 'Today', // Display text for current month link
  5391. monthNames: ['January','February','March','April','May','June',
  5392. 'July','August','September','October','November','December'], // Names of months for drop-down and formatting
  5393. monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
  5394. dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
  5395. dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
  5396. dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
  5397. weekHeader: 'Wk', // Column header for week of the year
  5398. dateFormat: 'mm/dd/yy', // See format options on parseDate
  5399. firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
  5400. isRTL: false, // True if right-to-left language, false if left-to-right
  5401. showMonthAfterYear: false, // True if the year select precedes month, false for month then year
  5402. yearSuffix: '' // Additional text to append to the year in the month headers
  5403. };
  5404. this._defaults = { // Global defaults for all the date picker instances
  5405. showOn: 'focus', // 'focus' for popup on focus,
  5406. // 'button' for trigger button, or 'both' for either
  5407. showAnim: 'fadeIn', // Name of jQuery animation for popup
  5408. showOptions: {}, // Options for enhanced animations
  5409. defaultDate: null, // Used when field is blank: actual date,
  5410. // +/-number for offset from today, null for today
  5411. appendText: '', // Display text following the input box, e.g. showing the format
  5412. buttonText: '...', // Text for trigger button
  5413. buttonImage: '', // URL for trigger button image
  5414. buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
  5415. hideIfNoPrevNext: false, // True to hide next/previous month links
  5416. // if not applicable, false to just disable them
  5417. navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
  5418. gotoCurrent: false, // True if today link goes back to current selection instead
  5419. changeMonth: false, // True if month can be selected directly, false if only prev/next
  5420. changeYear: false, // True if year can be selected directly, false if only prev/next
  5421. yearRange: 'c-10:c+10', // Range of years to display in drop-down,
  5422. // either relative to today's year (-nn:+nn), relative to currently displayed year
  5423. // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
  5424. showOtherMonths: false, // True to show dates in other months, false to leave blank
  5425. selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
  5426. showWeek: false, // True to show week of the year, false to not show it
  5427. calculateWeek: this.iso8601Week, // How to calculate the week of the year,
  5428. // takes a Date and returns the number of the week for it
  5429. shortYearCutoff: '+10', // Short year values < this are in the current century,
  5430. // > this are in the previous century,
  5431. // string value starting with '+' for current year + value
  5432. minDate: null, // The earliest selectable date, or null for no limit
  5433. maxDate: null, // The latest selectable date, or null for no limit
  5434. duration: 'fast', // Duration of display/closure
  5435. beforeShowDay: null, // Function that takes a date and returns an array with
  5436. // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
  5437. // [2] = cell title (optional), e.g. $.datepicker.noWeekends
  5438. beforeShow: null, // Function that takes an input field and
  5439. // returns a set of custom settings for the date picker
  5440. onSelect: null, // Define a callback function when a date is selected
  5441. onChangeMonthYear: null, // Define a callback function when the month or year is changed
  5442. onClose: null, // Define a callback function when the datepicker is closed
  5443. numberOfMonths: 1, // Number of months to show at a time
  5444. showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
  5445. stepMonths: 1, // Number of months to step back/forward
  5446. stepBigMonths: 12, // Number of months to step back/forward for the big links
  5447. altField: '', // Selector for an alternate field to store selected dates into
  5448. altFormat: '', // The date format to use for the alternate field
  5449. constrainInput: true, // The input is constrained by the current date format
  5450. showButtonPanel: false, // True to show button panel, false to not show it
  5451. autoSize: false, // True to size the input for the date format, false to leave as is
  5452. disabled: false // The initial disabled state
  5453. };
  5454. $.extend(this._defaults, this.regional['']);
  5455. this.dpDiv = bindHover($('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'));
  5456. }
  5457. $.extend(Datepicker.prototype, {
  5458. /* Class name added to elements to indicate already configured with a date picker. */
  5459. markerClassName: 'hasDatepicker',
  5460. //Keep track of the maximum number of rows displayed (see #7043)
  5461. maxRows: 4,
  5462. /* Debug logging (if enabled). */
  5463. log: function () {
  5464. if (this.debug)
  5465. console.log.apply('', arguments);
  5466. },
  5467. // TODO rename to "widget" when switching to widget factory
  5468. _widgetDatepicker: function() {
  5469. return this.dpDiv;
  5470. },
  5471. /* Override the default settings for all instances of the date picker.
  5472. @param settings object - the new settings to use as defaults (anonymous object)
  5473. @return the manager object */
  5474. setDefaults: function(settings) {
  5475. extendRemove(this._defaults, settings || {});
  5476. return this;
  5477. },
  5478. /* Attach the date picker to a jQuery selection.
  5479. @param target element - the target input field or division or span
  5480. @param settings object - the new settings to use for this date picker instance (anonymous) */
  5481. _attachDatepicker: function(target, settings) {
  5482. // check for settings on the control itself - in namespace 'date:'
  5483. var inlineSettings = null;
  5484. for (var attrName in this._defaults) {
  5485. var attrValue = target.getAttribute('date:' + attrName);
  5486. if (attrValue) {
  5487. inlineSettings = inlineSettings || {};
  5488. try {
  5489. inlineSettings[attrName] = eval(attrValue);
  5490. } catch (err) {
  5491. inlineSettings[attrName] = attrValue;
  5492. }
  5493. }
  5494. }
  5495. var nodeName = target.nodeName.toLowerCase();
  5496. var inline = (nodeName == 'div' || nodeName == 'span');
  5497. if (!target.id) {
  5498. this.uuid += 1;
  5499. target.id = 'dp' + this.uuid;
  5500. }
  5501. var inst = this._newInst($(target), inline);
  5502. inst.settings = $.extend({}, settings || {}, inlineSettings || {});
  5503. if (nodeName == 'input') {
  5504. this._connectDatepicker(target, inst);
  5505. } else if (inline) {
  5506. this._inlineDatepicker(target, inst);
  5507. }
  5508. },
  5509. /* Create a new instance object. */
  5510. _newInst: function(target, inline) {
  5511. var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars
  5512. return {id: id, input: target, // associated target
  5513. selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
  5514. drawMonth: 0, drawYear: 0, // month being drawn
  5515. inline: inline, // is datepicker inline or not
  5516. dpDiv: (!inline ? this.dpDiv : // presentation div
  5517. bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))};
  5518. },
  5519. /* Attach the date picker to an input field. */
  5520. _connectDatepicker: function(target, inst) {
  5521. var input = $(target);
  5522. inst.append = $([]);
  5523. inst.trigger = $([]);
  5524. if (input.hasClass(this.markerClassName))
  5525. return;
  5526. this._attachments(input, inst);
  5527. input.addClass(this.markerClassName).keydown(this._doKeyDown).
  5528. keypress(this._doKeyPress).keyup(this._doKeyUp).
  5529. bind("setData.datepicker", function(event, key, value) {
  5530. inst.settings[key] = value;
  5531. }).bind("getData.datepicker", function(event, key) {
  5532. return this._get(inst, key);
  5533. });
  5534. this._autoSize(inst);
  5535. $.data(target, PROP_NAME, inst);
  5536. //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
  5537. if( inst.settings.disabled ) {
  5538. this._disableDatepicker( target );
  5539. }
  5540. },
  5541. /* Make attachments based on settings. */
  5542. _attachments: function(input, inst) {
  5543. var appendText = this._get(inst, 'appendText');
  5544. var isRTL = this._get(inst, 'isRTL');
  5545. if (inst.append)
  5546. inst.append.remove();
  5547. if (appendText) {
  5548. inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>');
  5549. input[isRTL ? 'before' : 'after'](inst.append);
  5550. }
  5551. input.unbind('focus', this._showDatepicker);
  5552. if (inst.trigger)
  5553. inst.trigger.remove();
  5554. var showOn = this._get(inst, 'showOn');
  5555. if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
  5556. input.focus(this._showDatepicker);
  5557. if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
  5558. var buttonText = this._get(inst, 'buttonText');
  5559. var buttonImage = this._get(inst, 'buttonImage');
  5560. inst.trigger = $(this._get(inst, 'buttonImageOnly') ?
  5561. $('<img/>').addClass(this._triggerClass).
  5562. attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
  5563. $('<button type="button"></button>').addClass(this._triggerClass).
  5564. html(buttonImage == '' ? buttonText : $('<img/>').attr(
  5565. { src:buttonImage, alt:buttonText, title:buttonText })));
  5566. input[isRTL ? 'before' : 'after'](inst.trigger);
  5567. inst.trigger.click(function() {
  5568. if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0])
  5569. $.datepicker._hideDatepicker();
  5570. else if ($.datepicker._datepickerShowing && $.datepicker._lastInput != input[0]) {
  5571. $.datepicker._hideDatepicker();
  5572. $.datepicker._showDatepicker(input[0]);
  5573. } else
  5574. $.datepicker._showDatepicker(input[0]);
  5575. return false;
  5576. });
  5577. }
  5578. },
  5579. /* Apply the maximum length for the date format. */
  5580. _autoSize: function(inst) {
  5581. if (this._get(inst, 'autoSize') && !inst.inline) {
  5582. var date = new Date(2009, 12 - 1, 20); // Ensure double digits
  5583. var dateFormat = this._get(inst, 'dateFormat');
  5584. if (dateFormat.match(/[DM]/)) {
  5585. var findMax = function(names) {
  5586. var max = 0;
  5587. var maxI = 0;
  5588. for (var i = 0; i < names.length; i++) {
  5589. if (names[i].length > max) {
  5590. max = names[i].length;
  5591. maxI = i;
  5592. }
  5593. }
  5594. return maxI;
  5595. };
  5596. date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
  5597. 'monthNames' : 'monthNamesShort'))));
  5598. date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
  5599. 'dayNames' : 'dayNamesShort'))) + 20 - date.getDay());
  5600. }
  5601. inst.input.attr('size', this._formatDate(inst, date).length);
  5602. }
  5603. },
  5604. /* Attach an inline date picker to a div. */
  5605. _inlineDatepicker: function(target, inst) {
  5606. var divSpan = $(target);
  5607. if (divSpan.hasClass(this.markerClassName))
  5608. return;
  5609. divSpan.addClass(this.markerClassName).append(inst.dpDiv).
  5610. bind("setData.datepicker", function(event, key, value){
  5611. inst.settings[key] = value;
  5612. }).bind("getData.datepicker", function(event, key){
  5613. return this._get(inst, key);
  5614. });
  5615. $.data(target, PROP_NAME, inst);
  5616. this._setDate(inst, this._getDefaultDate(inst), true);
  5617. this._updateDatepicker(inst);
  5618. this._updateAlternate(inst);
  5619. //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
  5620. if( inst.settings.disabled ) {
  5621. this._disableDatepicker( target );
  5622. }
  5623. // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
  5624. // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
  5625. inst.dpDiv.css( "display", "block" );
  5626. },
  5627. /* Pop-up the date picker in a "dialog" box.
  5628. @param input element - ignored
  5629. @param date string or Date - the initial date to display
  5630. @param onSelect function - the function to call when a date is selected
  5631. @param settings object - update the dialog date picker instance's settings (anonymous object)
  5632. @param pos int[2] - coordinates for the dialog's position within the screen or
  5633. event - with x/y coordinates or
  5634. leave empty for default (screen centre)
  5635. @return the manager object */
  5636. _dialogDatepicker: function(input, date, onSelect, settings, pos) {
  5637. var inst = this._dialogInst; // internal instance
  5638. if (!inst) {
  5639. this.uuid += 1;
  5640. var id = 'dp' + this.uuid;
  5641. this._dialogInput = $('<input type="text" id="' + id +
  5642. '" style="position: absolute; top: -100px; width: 0px;"/>');
  5643. this._dialogInput.keydown(this._doKeyDown);
  5644. $('body').append(this._dialogInput);
  5645. inst = this._dialogInst = this._newInst(this._dialogInput, false);
  5646. inst.settings = {};
  5647. $.data(this._dialogInput[0], PROP_NAME, inst);
  5648. }
  5649. extendRemove(inst.settings, settings || {});
  5650. date = (date && date.constructor == Date ? this._formatDate(inst, date) : date);
  5651. this._dialogInput.val(date);
  5652. this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
  5653. if (!this._pos) {
  5654. var browserWidth = document.documentElement.clientWidth;
  5655. var browserHeight = document.documentElement.clientHeight;
  5656. var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
  5657. var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
  5658. this._pos = // should use actual width/height below
  5659. [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
  5660. }
  5661. // move input on screen for focus, but hidden behind dialog
  5662. this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px');
  5663. inst.settings.onSelect = onSelect;
  5664. this._inDialog = true;
  5665. this.dpDiv.addClass(this._dialogClass);
  5666. this._showDatepicker(this._dialogInput[0]);
  5667. if ($.blockUI)
  5668. $.blockUI(this.dpDiv);
  5669. $.data(this._dialogInput[0], PROP_NAME, inst);
  5670. return this;
  5671. },
  5672. /* Detach a datepicker from its control.
  5673. @param target element - the target input field or division or span */
  5674. _destroyDatepicker: function(target) {
  5675. var $target = $(target);
  5676. var inst = $.data(target, PROP_NAME);
  5677. if (!$target.hasClass(this.markerClassName)) {
  5678. return;
  5679. }
  5680. var nodeName = target.nodeName.toLowerCase();
  5681. $.removeData(target, PROP_NAME);
  5682. if (nodeName == 'input') {
  5683. inst.append.remove();
  5684. inst.trigger.remove();
  5685. $target.removeClass(this.markerClassName).
  5686. unbind('focus', this._showDatepicker).
  5687. unbind('keydown', this._doKeyDown).
  5688. unbind('keypress', this._doKeyPress).
  5689. unbind('keyup', this._doKeyUp);
  5690. } else if (nodeName == 'div' || nodeName == 'span')
  5691. $target.removeClass(this.markerClassName).empty();
  5692. },
  5693. /* Enable the date picker to a jQuery selection.
  5694. @param target element - the target input field or division or span */
  5695. _enableDatepicker: function(target) {
  5696. var $target = $(target);
  5697. var inst = $.data(target, PROP_NAME);
  5698. if (!$target.hasClass(this.markerClassName)) {
  5699. return;
  5700. }
  5701. var nodeName = target.nodeName.toLowerCase();
  5702. if (nodeName == 'input') {
  5703. target.disabled = false;
  5704. inst.trigger.filter('button').
  5705. each(function() { this.disabled = false; }).end().
  5706. filter('img').css({opacity: '1.0', cursor: ''});
  5707. }
  5708. else if (nodeName == 'div' || nodeName == 'span') {
  5709. var inline = $target.children('.' + this._inlineClass);
  5710. inline.children().removeClass('ui-state-disabled');
  5711. inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
  5712. prop("disabled", false);
  5713. }
  5714. this._disabledInputs = $.map(this._disabledInputs,
  5715. function(value) { return (value == target ? null : value); }); // delete entry
  5716. },
  5717. /* Disable the date picker to a jQuery selection.
  5718. @param target element - the target input field or division or span */
  5719. _disableDatepicker: function(target) {
  5720. var $target = $(target);
  5721. var inst = $.data(target, PROP_NAME);
  5722. if (!$target.hasClass(this.markerClassName)) {
  5723. return;
  5724. }
  5725. var nodeName = target.nodeName.toLowerCase();
  5726. if (nodeName == 'input') {
  5727. target.disabled = true;
  5728. inst.trigger.filter('button').
  5729. each(function() { this.disabled = true; }).end().
  5730. filter('img').css({opacity: '0.5', cursor: 'default'});
  5731. }
  5732. else if (nodeName == 'div' || nodeName == 'span') {
  5733. var inline = $target.children('.' + this._inlineClass);
  5734. inline.children().addClass('ui-state-disabled');
  5735. inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
  5736. prop("disabled", true);
  5737. }
  5738. this._disabledInputs = $.map(this._disabledInputs,
  5739. function(value) { return (value == target ? null : value); }); // delete entry
  5740. this._disabledInputs[this._disabledInputs.length] = target;
  5741. },
  5742. /* Is the first field in a jQuery collection disabled as a datepicker?
  5743. @param target element - the target input field or division or span
  5744. @return boolean - true if disabled, false if enabled */
  5745. _isDisabledDatepicker: function(target) {
  5746. if (!target) {
  5747. return false;
  5748. }
  5749. for (var i = 0; i < this._disabledInputs.length; i++) {
  5750. if (this._disabledInputs[i] == target)
  5751. return true;
  5752. }
  5753. return false;
  5754. },
  5755. /* Retrieve the instance data for the target control.
  5756. @param target element - the target input field or division or span
  5757. @return object - the associated instance data
  5758. @throws error if a jQuery problem getting data */
  5759. _getInst: function(target) {
  5760. try {
  5761. return $.data(target, PROP_NAME);
  5762. }
  5763. catch (err) {
  5764. throw 'Missing instance data for this datepicker';
  5765. }
  5766. },
  5767. /* Update or retrieve the settings for a date picker attached to an input field or division.
  5768. @param target element - the target input field or division or span
  5769. @param name object - the new settings to update or
  5770. string - the name of the setting to change or retrieve,
  5771. when retrieving also 'all' for all instance settings or
  5772. 'defaults' for all global defaults
  5773. @param value any - the new value for the setting
  5774. (omit if above is an object or to retrieve a value) */
  5775. _optionDatepicker: function(target, name, value) {
  5776. var inst = this._getInst(target);
  5777. if (arguments.length == 2 && typeof name == 'string') {
  5778. return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) :
  5779. (inst ? (name == 'all' ? $.extend({}, inst.settings) :
  5780. this._get(inst, name)) : null));
  5781. }
  5782. var settings = name || {};
  5783. if (typeof name == 'string') {
  5784. settings = {};
  5785. settings[name] = value;
  5786. }
  5787. if (inst) {
  5788. if (this._curInst == inst) {
  5789. this._hideDatepicker();
  5790. }
  5791. var date = this._getDateDatepicker(target, true);
  5792. var minDate = this._getMinMaxDate(inst, 'min');
  5793. var maxDate = this._getMinMaxDate(inst, 'max');
  5794. extendRemove(inst.settings, settings);
  5795. // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
  5796. if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined)
  5797. inst.settings.minDate = this._formatDate(inst, minDate);
  5798. if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined)
  5799. inst.settings.maxDate = this._formatDate(inst, maxDate);
  5800. this._attachments($(target), inst);
  5801. this._autoSize(inst);
  5802. this._setDate(inst, date);
  5803. this._updateAlternate(inst);
  5804. this._updateDatepicker(inst);
  5805. }
  5806. },
  5807. // change method deprecated
  5808. _changeDatepicker: function(target, name, value) {
  5809. this._optionDatepicker(target, name, value);
  5810. },
  5811. /* Redraw the date picker attached to an input field or division.
  5812. @param target element - the target input field or division or span */
  5813. _refreshDatepicker: function(target) {
  5814. var inst = this._getInst(target);
  5815. if (inst) {
  5816. this._updateDatepicker(inst);
  5817. }
  5818. },
  5819. /* Set the dates for a jQuery selection.
  5820. @param target element - the target input field or division or span
  5821. @param date Date - the new date */
  5822. _setDateDatepicker: function(target, date) {
  5823. var inst = this._getInst(target);
  5824. if (inst) {
  5825. this._setDate(inst, date);
  5826. this._updateDatepicker(inst);
  5827. this._updateAlternate(inst);
  5828. }
  5829. },
  5830. /* Get the date(s) for the first entry in a jQuery selection.
  5831. @param target element - the target input field or division or span
  5832. @param noDefault boolean - true if no default date is to be used
  5833. @return Date - the current date */
  5834. _getDateDatepicker: function(target, noDefault) {
  5835. var inst = this._getInst(target);
  5836. if (inst && !inst.inline)
  5837. this._setDateFromField(inst, noDefault);
  5838. return (inst ? this._getDate(inst) : null);
  5839. },
  5840. /* Handle keystrokes. */
  5841. _doKeyDown: function(event) {
  5842. var inst = $.datepicker._getInst(event.target);
  5843. var handled = true;
  5844. var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
  5845. inst._keyEvent = true;
  5846. if ($.datepicker._datepickerShowing)
  5847. switch (event.keyCode) {
  5848. case 9: $.datepicker._hideDatepicker();
  5849. handled = false;
  5850. break; // hide on tab out
  5851. case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' +
  5852. $.datepicker._currentClass + ')', inst.dpDiv);
  5853. if (sel[0])
  5854. $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
  5855. var onSelect = $.datepicker._get(inst, 'onSelect');
  5856. if (onSelect) {
  5857. var dateStr = $.datepicker._formatDate(inst);
  5858. // trigger custom callback
  5859. onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
  5860. }
  5861. else
  5862. $.datepicker._hideDatepicker();
  5863. return false; // don't submit the form
  5864. break; // select the value on enter
  5865. case 27: $.datepicker._hideDatepicker();
  5866. break; // hide on escape
  5867. case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
  5868. -$.datepicker._get(inst, 'stepBigMonths') :
  5869. -$.datepicker._get(inst, 'stepMonths')), 'M');
  5870. break; // previous month/year on page up/+ ctrl
  5871. case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
  5872. +$.datepicker._get(inst, 'stepBigMonths') :
  5873. +$.datepicker._get(inst, 'stepMonths')), 'M');
  5874. break; // next month/year on page down/+ ctrl
  5875. case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
  5876. handled = event.ctrlKey || event.metaKey;
  5877. break; // clear on ctrl or command +end
  5878. case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
  5879. handled = event.ctrlKey || event.metaKey;
  5880. break; // current on ctrl or command +home
  5881. case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
  5882. handled = event.ctrlKey || event.metaKey;
  5883. // -1 day on ctrl or command +left
  5884. if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
  5885. -$.datepicker._get(inst, 'stepBigMonths') :
  5886. -$.datepicker._get(inst, 'stepMonths')), 'M');
  5887. // next month/year on alt +left on Mac
  5888. break;
  5889. case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
  5890. handled = event.ctrlKey || event.metaKey;
  5891. break; // -1 week on ctrl or command +up
  5892. case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
  5893. handled = event.ctrlKey || event.metaKey;
  5894. // +1 day on ctrl or command +right
  5895. if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
  5896. +$.datepicker._get(inst, 'stepBigMonths') :
  5897. +$.datepicker._get(inst, 'stepMonths')), 'M');
  5898. // next month/year on alt +right
  5899. break;
  5900. case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
  5901. handled = event.ctrlKey || event.metaKey;
  5902. break; // +1 week on ctrl or command +down
  5903. default: handled = false;
  5904. }
  5905. else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
  5906. $.datepicker._showDatepicker(this);
  5907. else {
  5908. handled = false;
  5909. }
  5910. if (handled) {
  5911. event.preventDefault();
  5912. event.stopPropagation();
  5913. }
  5914. },
  5915. /* Filter entered characters - based on date format. */
  5916. _doKeyPress: function(event) {
  5917. var inst = $.datepicker._getInst(event.target);
  5918. if ($.datepicker._get(inst, 'constrainInput')) {
  5919. var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
  5920. var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
  5921. return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
  5922. }
  5923. },
  5924. /* Synchronise manual entry and field/alternate field. */
  5925. _doKeyUp: function(event) {
  5926. var inst = $.datepicker._getInst(event.target);
  5927. if (inst.input.val() != inst.lastVal) {
  5928. try {
  5929. var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
  5930. (inst.input ? inst.input.val() : null),
  5931. $.datepicker._getFormatConfig(inst));
  5932. if (date) { // only if valid
  5933. $.datepicker._setDateFromField(inst);
  5934. $.datepicker._updateAlternate(inst);
  5935. $.datepicker._updateDatepicker(inst);
  5936. }
  5937. }
  5938. catch (err) {
  5939. $.datepicker.log(err);
  5940. }
  5941. }
  5942. return true;
  5943. },
  5944. /* Pop-up the date picker for a given input field.
  5945. If false returned from beforeShow event handler do not show.
  5946. @param input element - the input field attached to the date picker or
  5947. event - if triggered by focus */
  5948. _showDatepicker: function(input) {
  5949. input = input.target || input;
  5950. if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
  5951. input = $('input', input.parentNode)[0];
  5952. if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
  5953. return;
  5954. var inst = $.datepicker._getInst(input);
  5955. if ($.datepicker._curInst && $.datepicker._curInst != inst) {
  5956. $.datepicker._curInst.dpDiv.stop(true, true);
  5957. if ( inst && $.datepicker._datepickerShowing ) {
  5958. $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
  5959. }
  5960. }
  5961. var beforeShow = $.datepicker._get(inst, 'beforeShow');
  5962. var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
  5963. if(beforeShowSettings === false){
  5964. //false
  5965. return;
  5966. }
  5967. extendRemove(inst.settings, beforeShowSettings);
  5968. inst.lastVal = null;
  5969. $.datepicker._lastInput = input;
  5970. $.datepicker._setDateFromField(inst);
  5971. if ($.datepicker._inDialog) // hide cursor
  5972. input.value = '';
  5973. if (!$.datepicker._pos) { // position below input
  5974. $.datepicker._pos = $.datepicker._findPos(input);
  5975. $.datepicker._pos[1] += input.offsetHeight; // add the height
  5976. }
  5977. var isFixed = false;
  5978. $(input).parents().each(function() {
  5979. isFixed |= $(this).css('position') == 'fixed';
  5980. return !isFixed;
  5981. });
  5982. var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
  5983. $.datepicker._pos = null;
  5984. //to avoid flashes on Firefox
  5985. inst.dpDiv.empty();
  5986. // determine sizing offscreen
  5987. inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
  5988. $.datepicker._updateDatepicker(inst);
  5989. // fix width for dynamic number of date pickers
  5990. // and adjust position before showing
  5991. offset = $.datepicker._checkOffset(inst, offset, isFixed);
  5992. inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
  5993. 'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
  5994. left: offset.left + 'px', top: offset.top + 'px'});
  5995. if (!inst.inline) {
  5996. var showAnim = $.datepicker._get(inst, 'showAnim');
  5997. var duration = $.datepicker._get(inst, 'duration');
  5998. var postProcess = function() {
  5999. var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
  6000. if( !! cover.length ){
  6001. var borders = $.datepicker._getBorders(inst.dpDiv);
  6002. cover.css({left: -borders[0], top: -borders[1],
  6003. width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
  6004. }
  6005. };
  6006. inst.dpDiv.zIndex($(input).zIndex()+1);
  6007. $.datepicker._datepickerShowing = true;
  6008. // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
  6009. if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) )
  6010. inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
  6011. else
  6012. inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess);
  6013. if (!showAnim || !duration)
  6014. postProcess();
  6015. if (inst.input.is(':visible') && !inst.input.is(':disabled'))
  6016. inst.input.focus();
  6017. $.datepicker._curInst = inst;
  6018. }
  6019. },
  6020. /* Generate the date picker content. */
  6021. _updateDatepicker: function(inst) {
  6022. this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
  6023. var borders = $.datepicker._getBorders(inst.dpDiv);
  6024. instActive = inst; // for delegate hover events
  6025. inst.dpDiv.empty().append(this._generateHTML(inst));
  6026. this._attachHandlers(inst);
  6027. var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
  6028. if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6
  6029. cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
  6030. }
  6031. inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover();
  6032. var numMonths = this._getNumberOfMonths(inst);
  6033. var cols = numMonths[1];
  6034. var width = 17;
  6035. inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
  6036. if (cols > 1)
  6037. inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
  6038. inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
  6039. 'Class']('ui-datepicker-multi');
  6040. inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
  6041. 'Class']('ui-datepicker-rtl');
  6042. if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
  6043. // #6694 - don't focus the input if it's already focused
  6044. // this breaks the change event in IE
  6045. inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement)
  6046. inst.input.focus();
  6047. // deffered render of the years select (to avoid flashes on Firefox)
  6048. if( inst.yearshtml ){
  6049. var origyearshtml = inst.yearshtml;
  6050. setTimeout(function(){
  6051. //assure that inst.yearshtml didn't change.
  6052. if( origyearshtml === inst.yearshtml && inst.yearshtml ){
  6053. inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml);
  6054. }
  6055. origyearshtml = inst.yearshtml = null;
  6056. }, 0);
  6057. }
  6058. },
  6059. /* Retrieve the size of left and top borders for an element.
  6060. @param elem (jQuery object) the element of interest
  6061. @return (number[2]) the left and top borders */
  6062. _getBorders: function(elem) {
  6063. var convert = function(value) {
  6064. return {thin: 1, medium: 2, thick: 3}[value] || value;
  6065. };
  6066. return [parseFloat(convert(elem.css('border-left-width'))),
  6067. parseFloat(convert(elem.css('border-top-width')))];
  6068. },
  6069. /* Check positioning to remain on screen. */
  6070. _checkOffset: function(inst, offset, isFixed) {
  6071. var dpWidth = inst.dpDiv.outerWidth();
  6072. var dpHeight = inst.dpDiv.outerHeight();
  6073. var inputWidth = inst.input ? inst.input.outerWidth() : 0;
  6074. var inputHeight = inst.input ? inst.input.outerHeight() : 0;
  6075. var viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft());
  6076. var viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
  6077. offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
  6078. offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
  6079. offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
  6080. // now check if datepicker is showing outside window viewport - move to a better place if so.
  6081. offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
  6082. Math.abs(offset.left + dpWidth - viewWidth) : 0);
  6083. offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
  6084. Math.abs(dpHeight + inputHeight) : 0);
  6085. return offset;
  6086. },
  6087. /* Find an object's position on the screen. */
  6088. _findPos: function(obj) {
  6089. var inst = this._getInst(obj);
  6090. var isRTL = this._get(inst, 'isRTL');
  6091. while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) {
  6092. obj = obj[isRTL ? 'previousSibling' : 'nextSibling'];
  6093. }
  6094. var position = $(obj).offset();
  6095. return [position.left, position.top];
  6096. },
  6097. /* Hide the date picker from view.
  6098. @param input element - the input field attached to the date picker */
  6099. _hideDatepicker: function(input) {
  6100. var inst = this._curInst;
  6101. if (!inst || (input && inst != $.data(input, PROP_NAME)))
  6102. return;
  6103. if (this._datepickerShowing) {
  6104. var showAnim = this._get(inst, 'showAnim');
  6105. var duration = this._get(inst, 'duration');
  6106. var postProcess = function() {
  6107. $.datepicker._tidyDialog(inst);
  6108. };
  6109. // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
  6110. if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) )
  6111. inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
  6112. else
  6113. inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' :
  6114. (showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess);
  6115. if (!showAnim)
  6116. postProcess();
  6117. this._datepickerShowing = false;
  6118. var onClose = this._get(inst, 'onClose');
  6119. if (onClose)
  6120. onClose.apply((inst.input ? inst.input[0] : null),
  6121. [(inst.input ? inst.input.val() : ''), inst]);
  6122. this._lastInput = null;
  6123. if (this._inDialog) {
  6124. this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
  6125. if ($.blockUI) {
  6126. $.unblockUI();
  6127. $('body').append(this.dpDiv);
  6128. }
  6129. }
  6130. this._inDialog = false;
  6131. }
  6132. },
  6133. /* Tidy up after a dialog display. */
  6134. _tidyDialog: function(inst) {
  6135. inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
  6136. },
  6137. /* Close date picker if clicked elsewhere. */
  6138. _checkExternalClick: function(event) {
  6139. if (!$.datepicker._curInst)
  6140. return;
  6141. var $target = $(event.target),
  6142. inst = $.datepicker._getInst($target[0]);
  6143. if ( ( ( $target[0].id != $.datepicker._mainDivId &&
  6144. $target.parents('#' + $.datepicker._mainDivId).length == 0 &&
  6145. !$target.hasClass($.datepicker.markerClassName) &&
  6146. !$target.closest("." + $.datepicker._triggerClass).length &&
  6147. $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
  6148. ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst != inst ) )
  6149. $.datepicker._hideDatepicker();
  6150. },
  6151. /* Adjust one of the date sub-fields. */
  6152. _adjustDate: function(id, offset, period) {
  6153. var target = $(id);
  6154. var inst = this._getInst(target[0]);
  6155. if (this._isDisabledDatepicker(target[0])) {
  6156. return;
  6157. }
  6158. this._adjustInstDate(inst, offset +
  6159. (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
  6160. period);
  6161. this._updateDatepicker(inst);
  6162. },
  6163. /* Action for current link. */
  6164. _gotoToday: function(id) {
  6165. var target = $(id);
  6166. var inst = this._getInst(target[0]);
  6167. if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
  6168. inst.selectedDay = inst.currentDay;
  6169. inst.drawMonth = inst.selectedMonth = inst.currentMonth;
  6170. inst.drawYear = inst.selectedYear = inst.currentYear;
  6171. }
  6172. else {
  6173. var date = new Date();
  6174. inst.selectedDay = date.getDate();
  6175. inst.drawMonth = inst.selectedMonth = date.getMonth();
  6176. inst.drawYear = inst.selectedYear = date.getFullYear();
  6177. }
  6178. this._notifyChange(inst);
  6179. this._adjustDate(target);
  6180. },
  6181. /* Action for selecting a new month/year. */
  6182. _selectMonthYear: function(id, select, period) {
  6183. var target = $(id);
  6184. var inst = this._getInst(target[0]);
  6185. inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
  6186. inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
  6187. parseInt(select.options[select.selectedIndex].value,10);
  6188. this._notifyChange(inst);
  6189. this._adjustDate(target);
  6190. },
  6191. /* Action for selecting a day. */
  6192. _selectDay: function(id, month, year, td) {
  6193. var target = $(id);
  6194. if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
  6195. return;
  6196. }
  6197. var inst = this._getInst(target[0]);
  6198. inst.selectedDay = inst.currentDay = $('a', td).html();
  6199. inst.selectedMonth = inst.currentMonth = month;
  6200. inst.selectedYear = inst.currentYear = year;
  6201. this._selectDate(id, this._formatDate(inst,
  6202. inst.currentDay, inst.currentMonth, inst.currentYear));
  6203. },
  6204. /* Erase the input field and hide the date picker. */
  6205. _clearDate: function(id) {
  6206. var target = $(id);
  6207. var inst = this._getInst(target[0]);
  6208. this._selectDate(target, '');
  6209. },
  6210. /* Update the input field with the selected date. */
  6211. _selectDate: function(id, dateStr) {
  6212. var target = $(id);
  6213. var inst = this._getInst(target[0]);
  6214. dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
  6215. if (inst.input)
  6216. inst.input.val(dateStr);
  6217. this._updateAlternate(inst);
  6218. var onSelect = this._get(inst, 'onSelect');
  6219. if (onSelect)
  6220. onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback
  6221. else if (inst.input)
  6222. inst.input.trigger('change'); // fire the change event
  6223. if (inst.inline)
  6224. this._updateDatepicker(inst);
  6225. else {
  6226. this._hideDatepicker();
  6227. this._lastInput = inst.input[0];
  6228. if (typeof(inst.input[0]) != 'object')
  6229. inst.input.focus(); // restore focus
  6230. this._lastInput = null;
  6231. }
  6232. },
  6233. /* Update any alternate field to synchronise with the main field. */
  6234. _updateAlternate: function(inst) {
  6235. var altField = this._get(inst, 'altField');
  6236. if (altField) { // update alternate field too
  6237. var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
  6238. var date = this._getDate(inst);
  6239. var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
  6240. $(altField).each(function() { $(this).val(dateStr); });
  6241. }
  6242. },
  6243. /* Set as beforeShowDay function to prevent selection of weekends.
  6244. @param date Date - the date to customise
  6245. @return [boolean, string] - is this date selectable?, what is its CSS class? */
  6246. noWeekends: function(date) {
  6247. var day = date.getDay();
  6248. return [(day > 0 && day < 6), ''];
  6249. },
  6250. /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
  6251. @param date Date - the date to get the week for
  6252. @return number - the number of the week within the year that contains this date */
  6253. iso8601Week: function(date) {
  6254. var checkDate = new Date(date.getTime());
  6255. // Find Thursday of this week starting on Monday
  6256. checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
  6257. var time = checkDate.getTime();
  6258. checkDate.setMonth(0); // Compare with Jan 1
  6259. checkDate.setDate(1);
  6260. return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
  6261. },
  6262. /* Parse a string value into a date object.
  6263. See formatDate below for the possible formats.
  6264. @param format string - the expected format of the date
  6265. @param value string - the date in the above format
  6266. @param settings Object - attributes include:
  6267. shortYearCutoff number - the cutoff year for determining the century (optional)
  6268. dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
  6269. dayNames string[7] - names of the days from Sunday (optional)
  6270. monthNamesShort string[12] - abbreviated names of the months (optional)
  6271. monthNames string[12] - names of the months (optional)
  6272. @return Date - the extracted date value or null if value is blank */
  6273. parseDate: function (format, value, settings) {
  6274. if (format == null || value == null)
  6275. throw 'Invalid arguments';
  6276. value = (typeof value == 'object' ? value.toString() : value + '');
  6277. if (value == '')
  6278. return null;
  6279. var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
  6280. shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
  6281. new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
  6282. var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
  6283. var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
  6284. var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
  6285. var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
  6286. var year = -1;
  6287. var month = -1;
  6288. var day = -1;
  6289. var doy = -1;
  6290. var literal = false;
  6291. // Check whether a format character is doubled
  6292. var lookAhead = function(match) {
  6293. var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
  6294. if (matches)
  6295. iFormat++;
  6296. return matches;
  6297. };
  6298. // Extract a number from the string value
  6299. var getNumber = function(match) {
  6300. var isDoubled = lookAhead(match);
  6301. var size = (match == '@' ? 14 : (match == '!' ? 20 :
  6302. (match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2))));
  6303. var digits = new RegExp('^\\d{1,' + size + '}');
  6304. var num = value.substring(iValue).match(digits);
  6305. if (!num)
  6306. throw 'Missing number at position ' + iValue;
  6307. iValue += num[0].length;
  6308. return parseInt(num[0], 10);
  6309. };
  6310. // Extract a name from the string value and convert to an index
  6311. var getName = function(match, shortNames, longNames) {
  6312. var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
  6313. return [ [k, v] ];
  6314. }).sort(function (a, b) {
  6315. return -(a[1].length - b[1].length);
  6316. });
  6317. var index = -1;
  6318. $.each(names, function (i, pair) {
  6319. var name = pair[1];
  6320. if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) {
  6321. index = pair[0];
  6322. iValue += name.length;
  6323. return false;
  6324. }
  6325. });
  6326. if (index != -1)
  6327. return index + 1;
  6328. else
  6329. throw 'Unknown name at position ' + iValue;
  6330. };
  6331. // Confirm that a literal character matches the string value
  6332. var checkLiteral = function() {
  6333. if (value.charAt(iValue) != format.charAt(iFormat))
  6334. throw 'Unexpected literal at position ' + iValue;
  6335. iValue++;
  6336. };
  6337. var iValue = 0;
  6338. for (var iFormat = 0; iFormat < format.length; iFormat++) {
  6339. if (literal)
  6340. if (format.charAt(iFormat) == "'" && !lookAhead("'"))
  6341. literal = false;
  6342. else
  6343. checkLiteral();
  6344. else
  6345. switch (format.charAt(iFormat)) {
  6346. case 'd':
  6347. day = getNumber('d');
  6348. break;
  6349. case 'D':
  6350. getName('D', dayNamesShort, dayNames);
  6351. break;
  6352. case 'o':
  6353. doy = getNumber('o');
  6354. break;
  6355. case 'm':
  6356. month = getNumber('m');
  6357. break;
  6358. case 'M':
  6359. month = getName('M', monthNamesShort, monthNames);
  6360. break;
  6361. case 'y':
  6362. year = getNumber('y');
  6363. break;
  6364. case '@':
  6365. var date = new Date(getNumber('@'));
  6366. year = date.getFullYear();
  6367. month = date.getMonth() + 1;
  6368. day = date.getDate();
  6369. break;
  6370. case '!':
  6371. var date = new Date((getNumber('!') - this._ticksTo1970) / 10000);
  6372. year = date.getFullYear();
  6373. month = date.getMonth() + 1;
  6374. day = date.getDate();
  6375. break;
  6376. case "'":
  6377. if (lookAhead("'"))
  6378. checkLiteral();
  6379. else
  6380. literal = true;
  6381. break;
  6382. default:
  6383. checkLiteral();
  6384. }
  6385. }
  6386. if (iValue < value.length){
  6387. var extra = value.substr(iValue);
  6388. if (!/^\s+/.test(extra)) {
  6389. throw "Extra/unparsed characters found in date: " + extra;
  6390. }
  6391. }
  6392. if (year == -1)
  6393. year = new Date().getFullYear();
  6394. else if (year < 100)
  6395. year += new Date().getFullYear() - new Date().getFullYear() % 100 +
  6396. (year <= shortYearCutoff ? 0 : -100);
  6397. if (doy > -1) {
  6398. month = 1;
  6399. day = doy;
  6400. do {
  6401. var dim = this._getDaysInMonth(year, month - 1);
  6402. if (day <= dim)
  6403. break;
  6404. month++;
  6405. day -= dim;
  6406. } while (true);
  6407. }
  6408. var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
  6409. if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
  6410. throw 'Invalid date'; // E.g. 31/02/00
  6411. return date;
  6412. },
  6413. /* Standard date formats. */
  6414. ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
  6415. COOKIE: 'D, dd M yy',
  6416. ISO_8601: 'yy-mm-dd',
  6417. RFC_822: 'D, d M y',
  6418. RFC_850: 'DD, dd-M-y',
  6419. RFC_1036: 'D, d M y',
  6420. RFC_1123: 'D, d M yy',
  6421. RFC_2822: 'D, d M yy',
  6422. RSS: 'D, d M y', // RFC 822
  6423. TICKS: '!',
  6424. TIMESTAMP: '@',
  6425. W3C: 'yy-mm-dd', // ISO 8601
  6426. _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
  6427. Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
  6428. /* Format a date object into a string value.
  6429. The format can be combinations of the following:
  6430. d - day of month (no leading zero)
  6431. dd - day of month (two digit)
  6432. o - day of year (no leading zeros)
  6433. oo - day of year (three digit)
  6434. D - day name short
  6435. DD - day name long
  6436. m - month of year (no leading zero)
  6437. mm - month of year (two digit)
  6438. M - month name short
  6439. MM - month name long
  6440. y - year (two digit)
  6441. yy - year (four digit)
  6442. @ - Unix timestamp (ms since 01/01/1970)
  6443. ! - Windows ticks (100ns since 01/01/0001)
  6444. '...' - literal text
  6445. '' - single quote
  6446. @param format string - the desired format of the date
  6447. @param date Date - the date value to format
  6448. @param settings Object - attributes include:
  6449. dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
  6450. dayNames string[7] - names of the days from Sunday (optional)
  6451. monthNamesShort string[12] - abbreviated names of the months (optional)
  6452. monthNames string[12] - names of the months (optional)
  6453. @return string - the date in the above format */
  6454. formatDate: function (format, date, settings) {
  6455. if (!date)
  6456. return '';
  6457. var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
  6458. var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
  6459. var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
  6460. var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
  6461. // Check whether a format character is doubled
  6462. var lookAhead = function(match) {
  6463. var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
  6464. if (matches)
  6465. iFormat++;
  6466. return matches;
  6467. };
  6468. // Format a number, with leading zero if necessary
  6469. var formatNumber = function(match, value, len) {
  6470. var num = '' + value;
  6471. if (lookAhead(match))
  6472. while (num.length < len)
  6473. num = '0' + num;
  6474. return num;
  6475. };
  6476. // Format a name, short or long as requested
  6477. var formatName = function(match, value, shortNames, longNames) {
  6478. return (lookAhead(match) ? longNames[value] : shortNames[value]);
  6479. };
  6480. var output = '';
  6481. var literal = false;
  6482. if (date)
  6483. for (var iFormat = 0; iFormat < format.length; iFormat++) {
  6484. if (literal)
  6485. if (format.charAt(iFormat) == "'" && !lookAhead("'"))
  6486. literal = false;
  6487. else
  6488. output += format.charAt(iFormat);
  6489. else
  6490. switch (format.charAt(iFormat)) {
  6491. case 'd':
  6492. output += formatNumber('d', date.getDate(), 2);
  6493. break;
  6494. case 'D':
  6495. output += formatName('D', date.getDay(), dayNamesShort, dayNames);
  6496. break;
  6497. case 'o':
  6498. output += formatNumber('o',
  6499. Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
  6500. break;
  6501. case 'm':
  6502. output += formatNumber('m', date.getMonth() + 1, 2);
  6503. break;
  6504. case 'M':
  6505. output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
  6506. break;
  6507. case 'y':
  6508. output += (lookAhead('y') ? date.getFullYear() :
  6509. (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
  6510. break;
  6511. case '@':
  6512. output += date.getTime();
  6513. break;
  6514. case '!':
  6515. output += date.getTime() * 10000 + this._ticksTo1970;
  6516. break;
  6517. case "'":
  6518. if (lookAhead("'"))
  6519. output += "'";
  6520. else
  6521. literal = true;
  6522. break;
  6523. default:
  6524. output += format.charAt(iFormat);
  6525. }
  6526. }
  6527. return output;
  6528. },
  6529. /* Extract all possible characters from the date format. */
  6530. _possibleChars: function (format) {
  6531. var chars = '';
  6532. var literal = false;
  6533. // Check whether a format character is doubled
  6534. var lookAhead = function(match) {
  6535. var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
  6536. if (matches)
  6537. iFormat++;
  6538. return matches;
  6539. };
  6540. for (var iFormat = 0; iFormat < format.length; iFormat++)
  6541. if (literal)
  6542. if (format.charAt(iFormat) == "'" && !lookAhead("'"))
  6543. literal = false;
  6544. else
  6545. chars += format.charAt(iFormat);
  6546. else
  6547. switch (format.charAt(iFormat)) {
  6548. case 'd': case 'm': case 'y': case '@':
  6549. chars += '0123456789';
  6550. break;
  6551. case 'D': case 'M':
  6552. return null; // Accept anything
  6553. case "'":
  6554. if (lookAhead("'"))
  6555. chars += "'";
  6556. else
  6557. literal = true;
  6558. break;
  6559. default:
  6560. chars += format.charAt(iFormat);
  6561. }
  6562. return chars;
  6563. },
  6564. /* Get a setting value, defaulting if necessary. */
  6565. _get: function(inst, name) {
  6566. return inst.settings[name] !== undefined ?
  6567. inst.settings[name] : this._defaults[name];
  6568. },
  6569. /* Parse existing date and initialise date picker. */
  6570. _setDateFromField: function(inst, noDefault) {
  6571. if (inst.input.val() == inst.lastVal) {
  6572. return;
  6573. }
  6574. var dateFormat = this._get(inst, 'dateFormat');
  6575. var dates = inst.lastVal = inst.input ? inst.input.val() : null;
  6576. var date, defaultDate;
  6577. date = defaultDate = this._getDefaultDate(inst);
  6578. var settings = this._getFormatConfig(inst);
  6579. try {
  6580. date = this.parseDate(dateFormat, dates, settings) || defaultDate;
  6581. } catch (event) {
  6582. this.log(event);
  6583. dates = (noDefault ? '' : dates);
  6584. }
  6585. inst.selectedDay = date.getDate();
  6586. inst.drawMonth = inst.selectedMonth = date.getMonth();
  6587. inst.drawYear = inst.selectedYear = date.getFullYear();
  6588. inst.currentDay = (dates ? date.getDate() : 0);
  6589. inst.currentMonth = (dates ? date.getMonth() : 0);
  6590. inst.currentYear = (dates ? date.getFullYear() : 0);
  6591. this._adjustInstDate(inst);
  6592. },
  6593. /* Retrieve the default date shown on opening. */
  6594. _getDefaultDate: function(inst) {
  6595. return this._restrictMinMax(inst,
  6596. this._determineDate(inst, this._get(inst, 'defaultDate'), new Date()));
  6597. },
  6598. /* A date may be specified as an exact value or a relative one. */
  6599. _determineDate: function(inst, date, defaultDate) {
  6600. var offsetNumeric = function(offset) {
  6601. var date = new Date();
  6602. date.setDate(date.getDate() + offset);
  6603. return date;
  6604. };
  6605. var offsetString = function(offset) {
  6606. try {
  6607. return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
  6608. offset, $.datepicker._getFormatConfig(inst));
  6609. }
  6610. catch (e) {
  6611. // Ignore
  6612. }
  6613. var date = (offset.toLowerCase().match(/^c/) ?
  6614. $.datepicker._getDate(inst) : null) || new Date();
  6615. var year = date.getFullYear();
  6616. var month = date.getMonth();
  6617. var day = date.getDate();
  6618. var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
  6619. var matches = pattern.exec(offset);
  6620. while (matches) {
  6621. switch (matches[2] || 'd') {
  6622. case 'd' : case 'D' :
  6623. day += parseInt(matches[1],10); break;
  6624. case 'w' : case 'W' :
  6625. day += parseInt(matches[1],10) * 7; break;
  6626. case 'm' : case 'M' :
  6627. month += parseInt(matches[1],10);
  6628. day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
  6629. break;
  6630. case 'y': case 'Y' :
  6631. year += parseInt(matches[1],10);
  6632. day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
  6633. break;
  6634. }
  6635. matches = pattern.exec(offset);
  6636. }
  6637. return new Date(year, month, day);
  6638. };
  6639. var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) :
  6640. (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
  6641. newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate);
  6642. if (newDate) {
  6643. newDate.setHours(0);
  6644. newDate.setMinutes(0);
  6645. newDate.setSeconds(0);
  6646. newDate.setMilliseconds(0);
  6647. }
  6648. return this._daylightSavingAdjust(newDate);
  6649. },
  6650. /* Handle switch to/from daylight saving.
  6651. Hours may be non-zero on daylight saving cut-over:
  6652. > 12 when midnight changeover, but then cannot generate
  6653. midnight datetime, so jump to 1AM, otherwise reset.
  6654. @param date (Date) the date to check
  6655. @return (Date) the corrected date */
  6656. _daylightSavingAdjust: function(date) {
  6657. if (!date) return null;
  6658. date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
  6659. return date;
  6660. },
  6661. /* Set the date(s) directly. */
  6662. _setDate: function(inst, date, noChange) {
  6663. var clear = !date;
  6664. var origMonth = inst.selectedMonth;
  6665. var origYear = inst.selectedYear;
  6666. var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
  6667. inst.selectedDay = inst.currentDay = newDate.getDate();
  6668. inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
  6669. inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
  6670. if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange)
  6671. this._notifyChange(inst);
  6672. this._adjustInstDate(inst);
  6673. if (inst.input) {
  6674. inst.input.val(clear ? '' : this._formatDate(inst));
  6675. }
  6676. },
  6677. /* Retrieve the date(s) directly. */
  6678. _getDate: function(inst) {
  6679. var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
  6680. this._daylightSavingAdjust(new Date(
  6681. inst.currentYear, inst.currentMonth, inst.currentDay)));
  6682. return startDate;
  6683. },
  6684. /* Attach the onxxx handlers. These are declared statically so
  6685. * they work with static code transformers like Caja.
  6686. */
  6687. _attachHandlers: function(inst) {
  6688. var stepMonths = this._get(inst, 'stepMonths');
  6689. var id = '#' + inst.id.replace( /\\\\/g, "\\" );
  6690. inst.dpDiv.find('[data-handler]').map(function () {
  6691. var handler = {
  6692. prev: function () {
  6693. window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, -stepMonths, 'M');
  6694. },
  6695. next: function () {
  6696. window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, +stepMonths, 'M');
  6697. },
  6698. hide: function () {
  6699. window['DP_jQuery_' + dpuuid].datepicker._hideDatepicker();
  6700. },
  6701. today: function () {
  6702. window['DP_jQuery_' + dpuuid].datepicker._gotoToday(id);
  6703. },
  6704. selectDay: function () {
  6705. window['DP_jQuery_' + dpuuid].datepicker._selectDay(id, +this.getAttribute('data-month'), +this.getAttribute('data-year'), this);
  6706. return false;
  6707. },
  6708. selectMonth: function () {
  6709. window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'M');
  6710. return false;
  6711. },
  6712. selectYear: function () {
  6713. window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'Y');
  6714. return false;
  6715. }
  6716. };
  6717. $(this).bind(this.getAttribute('data-event'), handler[this.getAttribute('data-handler')]);
  6718. });
  6719. },
  6720. /* Generate the HTML for the current state of the date picker. */
  6721. _generateHTML: function(inst) {
  6722. var today = new Date();
  6723. today = this._daylightSavingAdjust(
  6724. new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time
  6725. var isRTL = this._get(inst, 'isRTL');
  6726. var showButtonPanel = this._get(inst, 'showButtonPanel');
  6727. var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
  6728. var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
  6729. var numMonths = this._getNumberOfMonths(inst);
  6730. var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
  6731. var stepMonths = this._get(inst, 'stepMonths');
  6732. var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
  6733. var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
  6734. new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
  6735. var minDate = this._getMinMaxDate(inst, 'min');
  6736. var maxDate = this._getMinMaxDate(inst, 'max');
  6737. var drawMonth = inst.drawMonth - showCurrentAtPos;
  6738. var drawYear = inst.drawYear;
  6739. if (drawMonth < 0) {
  6740. drawMonth += 12;
  6741. drawYear--;
  6742. }
  6743. if (maxDate) {
  6744. var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
  6745. maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
  6746. maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
  6747. while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
  6748. drawMonth--;
  6749. if (drawMonth < 0) {
  6750. drawMonth = 11;
  6751. drawYear--;
  6752. }
  6753. }
  6754. }
  6755. inst.drawMonth = drawMonth;
  6756. inst.drawYear = drawYear;
  6757. var prevText = this._get(inst, 'prevText');
  6758. prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
  6759. this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
  6760. this._getFormatConfig(inst)));
  6761. var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
  6762. '<a class="ui-datepicker-prev ui-corner-all" data-handler="prev" data-event="click"' +
  6763. ' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' :
  6764. (hideIfNoPrevNext ? '' : '<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+ prevText +'"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>'));
  6765. var nextText = this._get(inst, 'nextText');
  6766. nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
  6767. this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
  6768. this._getFormatConfig(inst)));
  6769. var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
  6770. '<a class="ui-datepicker-next ui-corner-all" data-handler="next" data-event="click"' +
  6771. ' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' :
  6772. (hideIfNoPrevNext ? '' : '<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+ nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>'));
  6773. var currentText = this._get(inst, 'currentText');
  6774. var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
  6775. currentText = (!navigationAsDateFormat ? currentText :
  6776. this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
  6777. var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" data-handler="hide" data-event="click">' +
  6778. this._get(inst, 'closeText') + '</button>' : '');
  6779. var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') +
  6780. (this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" data-handler="today" data-event="click"' +
  6781. '>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';
  6782. var firstDay = parseInt(this._get(inst, 'firstDay'),10);
  6783. firstDay = (isNaN(firstDay) ? 0 : firstDay);
  6784. var showWeek = this._get(inst, 'showWeek');
  6785. var dayNames = this._get(inst, 'dayNames');
  6786. var dayNamesShort = this._get(inst, 'dayNamesShort');
  6787. var dayNamesMin = this._get(inst, 'dayNamesMin');
  6788. var monthNames = this._get(inst, 'monthNames');
  6789. var monthNamesShort = this._get(inst, 'monthNamesShort');
  6790. var beforeShowDay = this._get(inst, 'beforeShowDay');
  6791. var showOtherMonths = this._get(inst, 'showOtherMonths');
  6792. var selectOtherMonths = this._get(inst, 'selectOtherMonths');
  6793. var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
  6794. var defaultDate = this._getDefaultDate(inst);
  6795. var html = '';
  6796. for (var row = 0; row < numMonths[0]; row++) {
  6797. var group = '';
  6798. this.maxRows = 4;
  6799. for (var col = 0; col < numMonths[1]; col++) {
  6800. var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
  6801. var cornerClass = ' ui-corner-all';
  6802. var calender = '';
  6803. if (isMultiMonth) {
  6804. calender += '<div class="ui-datepicker-group';
  6805. if (numMonths[1] > 1)
  6806. switch (col) {
  6807. case 0: calender += ' ui-datepicker-group-first';
  6808. cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break;
  6809. case numMonths[1]-1: calender += ' ui-datepicker-group-last';
  6810. cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break;
  6811. default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break;
  6812. }
  6813. calender += '">';
  6814. }
  6815. calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' +
  6816. (/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +
  6817. (/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +
  6818. this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
  6819. row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
  6820. '</div><table class="ui-datepicker-calendar"><thead>' +
  6821. '<tr>';
  6822. var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : '');
  6823. for (var dow = 0; dow < 7; dow++) { // days of the week
  6824. var day = (dow + firstDay) % 7;
  6825. thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' +
  6826. '<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>';
  6827. }
  6828. calender += thead + '</tr></thead><tbody>';
  6829. var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
  6830. if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
  6831. inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
  6832. var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
  6833. var curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
  6834. var numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
  6835. this.maxRows = numRows;
  6836. var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
  6837. for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
  6838. calender += '<tr>';
  6839. var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' +
  6840. this._get(inst, 'calculateWeek')(printDate) + '</td>');
  6841. for (var dow = 0; dow < 7; dow++) { // create date picker days
  6842. var daySettings = (beforeShowDay ?
  6843. beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
  6844. var otherMonth = (printDate.getMonth() != drawMonth);
  6845. var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
  6846. (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
  6847. tbody += '<td class="' +
  6848. ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends
  6849. (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
  6850. ((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key
  6851. (defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
  6852. // or defaultDate is current printedDate and defaultDate is selectedDate
  6853. ' ' + this._dayOverClass : '') + // highlight selected day
  6854. (unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') + // highlight unselectable days
  6855. (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
  6856. (printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day
  6857. (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
  6858. ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
  6859. (unselectable ? '' : ' data-handler="selectDay" data-event="click" data-month="' + printDate.getMonth() + '" data-year="' + printDate.getFullYear() + '"') + '>' + // actions
  6860. (otherMonth && !showOtherMonths ? '&#xa0;' : // display for other months
  6861. (unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' +
  6862. (printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') +
  6863. (printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day
  6864. (otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months
  6865. '" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date
  6866. printDate.setDate(printDate.getDate() + 1);
  6867. printDate = this._daylightSavingAdjust(printDate);
  6868. }
  6869. calender += tbody + '</tr>';
  6870. }
  6871. drawMonth++;
  6872. if (drawMonth > 11) {
  6873. drawMonth = 0;
  6874. drawYear++;
  6875. }
  6876. calender += '</tbody></table>' + (isMultiMonth ? '</div>' +
  6877. ((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
  6878. group += calender;
  6879. }
  6880. html += group;
  6881. }
  6882. html += buttonPanel + ($.ui.ie6 && !inst.inline ?
  6883. '<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
  6884. inst._keyEvent = false;
  6885. return html;
  6886. },
  6887. /* Generate the month and year header. */
  6888. _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
  6889. secondary, monthNames, monthNamesShort) {
  6890. var changeMonth = this._get(inst, 'changeMonth');
  6891. var changeYear = this._get(inst, 'changeYear');
  6892. var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
  6893. var html = '<div class="ui-datepicker-title">';
  6894. var monthHtml = '';
  6895. // month selection
  6896. if (secondary || !changeMonth)
  6897. monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>';
  6898. else {
  6899. var inMinYear = (minDate && minDate.getFullYear() == drawYear);
  6900. var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
  6901. monthHtml += '<select class="ui-datepicker-month" data-handler="selectMonth" data-event="change">';
  6902. for (var month = 0; month < 12; month++) {
  6903. if ((!inMinYear || month >= minDate.getMonth()) &&
  6904. (!inMaxYear || month <= maxDate.getMonth()))
  6905. monthHtml += '<option value="' + month + '"' +
  6906. (month == drawMonth ? ' selected="selected"' : '') +
  6907. '>' + monthNamesShort[month] + '</option>';
  6908. }
  6909. monthHtml += '</select>';
  6910. }
  6911. if (!showMonthAfterYear)
  6912. html += monthHtml + (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '');
  6913. // year selection
  6914. if ( !inst.yearshtml ) {
  6915. inst.yearshtml = '';
  6916. if (secondary || !changeYear)
  6917. html += '<span class="ui-datepicker-year">' + drawYear + '</span>';
  6918. else {
  6919. // determine range of years to display
  6920. var years = this._get(inst, 'yearRange').split(':');
  6921. var thisYear = new Date().getFullYear();
  6922. var determineYear = function(value) {
  6923. var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) :
  6924. (value.match(/[+-].*/) ? thisYear + parseInt(value, 10) :
  6925. parseInt(value, 10)));
  6926. return (isNaN(year) ? thisYear : year);
  6927. };
  6928. var year = determineYear(years[0]);
  6929. var endYear = Math.max(year, determineYear(years[1] || ''));
  6930. year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
  6931. endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
  6932. inst.yearshtml += '<select class="ui-datepicker-year" data-handler="selectYear" data-event="change">';
  6933. for (; year <= endYear; year++) {
  6934. inst.yearshtml += '<option value="' + year + '"' +
  6935. (year == drawYear ? ' selected="selected"' : '') +
  6936. '>' + year + '</option>';
  6937. }
  6938. inst.yearshtml += '</select>';
  6939. html += inst.yearshtml;
  6940. inst.yearshtml = null;
  6941. }
  6942. }
  6943. html += this._get(inst, 'yearSuffix');
  6944. if (showMonthAfterYear)
  6945. html += (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '') + monthHtml;
  6946. html += '</div>'; // Close datepicker_header
  6947. return html;
  6948. },
  6949. /* Adjust one of the date sub-fields. */
  6950. _adjustInstDate: function(inst, offset, period) {
  6951. var year = inst.drawYear + (period == 'Y' ? offset : 0);
  6952. var month = inst.drawMonth + (period == 'M' ? offset : 0);
  6953. var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
  6954. (period == 'D' ? offset : 0);
  6955. var date = this._restrictMinMax(inst,
  6956. this._daylightSavingAdjust(new Date(year, month, day)));
  6957. inst.selectedDay = date.getDate();
  6958. inst.drawMonth = inst.selectedMonth = date.getMonth();
  6959. inst.drawYear = inst.selectedYear = date.getFullYear();
  6960. if (period == 'M' || period == 'Y')
  6961. this._notifyChange(inst);
  6962. },
  6963. /* Ensure a date is within any min/max bounds. */
  6964. _restrictMinMax: function(inst, date) {
  6965. var minDate = this._getMinMaxDate(inst, 'min');
  6966. var maxDate = this._getMinMaxDate(inst, 'max');
  6967. var newDate = (minDate && date < minDate ? minDate : date);
  6968. newDate = (maxDate && newDate > maxDate ? maxDate : newDate);
  6969. return newDate;
  6970. },
  6971. /* Notify change of month/year. */
  6972. _notifyChange: function(inst) {
  6973. var onChange = this._get(inst, 'onChangeMonthYear');
  6974. if (onChange)
  6975. onChange.apply((inst.input ? inst.input[0] : null),
  6976. [inst.selectedYear, inst.selectedMonth + 1, inst]);
  6977. },
  6978. /* Determine the number of months to show. */
  6979. _getNumberOfMonths: function(inst) {
  6980. var numMonths = this._get(inst, 'numberOfMonths');
  6981. return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
  6982. },
  6983. /* Determine the current maximum date - ensure no time components are set. */
  6984. _getMinMaxDate: function(inst, minMax) {
  6985. return this._determineDate(inst, this._get(inst, minMax + 'Date'), null);
  6986. },
  6987. /* Find the number of days in a given month. */
  6988. _getDaysInMonth: function(year, month) {
  6989. return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
  6990. },
  6991. /* Find the day of the week of the first of a month. */
  6992. _getFirstDayOfMonth: function(year, month) {
  6993. return new Date(year, month, 1).getDay();
  6994. },
  6995. /* Determines if we should allow a "next/prev" month display change. */
  6996. _canAdjustMonth: function(inst, offset, curYear, curMonth) {
  6997. var numMonths = this._getNumberOfMonths(inst);
  6998. var date = this._daylightSavingAdjust(new Date(curYear,
  6999. curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
  7000. if (offset < 0)
  7001. date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
  7002. return this._isInRange(inst, date);
  7003. },
  7004. /* Is the given date in the accepted range? */
  7005. _isInRange: function(inst, date) {
  7006. var minDate = this._getMinMaxDate(inst, 'min');
  7007. var maxDate = this._getMinMaxDate(inst, 'max');
  7008. return ((!minDate || date.getTime() >= minDate.getTime()) &&
  7009. (!maxDate || date.getTime() <= maxDate.getTime()));
  7010. },
  7011. /* Provide the configuration settings for formatting/parsing. */
  7012. _getFormatConfig: function(inst) {
  7013. var shortYearCutoff = this._get(inst, 'shortYearCutoff');
  7014. shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
  7015. new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
  7016. return {shortYearCutoff: shortYearCutoff,
  7017. dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
  7018. monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
  7019. },
  7020. /* Format the given date for display. */
  7021. _formatDate: function(inst, day, month, year) {
  7022. if (!day) {
  7023. inst.currentDay = inst.selectedDay;
  7024. inst.currentMonth = inst.selectedMonth;
  7025. inst.currentYear = inst.selectedYear;
  7026. }
  7027. var date = (day ? (typeof day == 'object' ? day :
  7028. this._daylightSavingAdjust(new Date(year, month, day))) :
  7029. this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
  7030. return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
  7031. }
  7032. });
  7033. /*
  7034. * Bind hover events for datepicker elements.
  7035. * Done via delegate so the binding only occurs once in the lifetime of the parent div.
  7036. * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
  7037. */
  7038. function bindHover(dpDiv) {
  7039. var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a';
  7040. return dpDiv.delegate(selector, 'mouseout', function() {
  7041. $(this).removeClass('ui-state-hover');
  7042. if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover');
  7043. if (this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover');
  7044. })
  7045. .delegate(selector, 'mouseover', function(){
  7046. if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) {
  7047. $(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');
  7048. $(this).addClass('ui-state-hover');
  7049. if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover');
  7050. if (this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover');
  7051. }
  7052. });
  7053. }
  7054. /* jQuery extend now ignores nulls! */
  7055. function extendRemove(target, props) {
  7056. $.extend(target, props);
  7057. for (var name in props)
  7058. if (props[name] == null || props[name] == undefined)
  7059. target[name] = props[name];
  7060. return target;
  7061. };
  7062. /* Invoke the datepicker functionality.
  7063. @param options string - a command, optionally followed by additional parameters or
  7064. Object - settings for attaching new datepicker functionality
  7065. @return jQuery object */
  7066. $.fn.datepicker = function(options){
  7067. /* Verify an empty collection wasn't passed - Fixes #6976 */
  7068. if ( !this.length ) {
  7069. return this;
  7070. }
  7071. /* Initialise the date picker. */
  7072. if (!$.datepicker.initialized) {
  7073. $(document).mousedown($.datepicker._checkExternalClick).
  7074. find(document.body).append($.datepicker.dpDiv);
  7075. $.datepicker.initialized = true;
  7076. }
  7077. var otherArgs = Array.prototype.slice.call(arguments, 1);
  7078. if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget'))
  7079. return $.datepicker['_' + options + 'Datepicker'].
  7080. apply($.datepicker, [this[0]].concat(otherArgs));
  7081. if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string')
  7082. return $.datepicker['_' + options + 'Datepicker'].
  7083. apply($.datepicker, [this[0]].concat(otherArgs));
  7084. return this.each(function() {
  7085. typeof options == 'string' ?
  7086. $.datepicker['_' + options + 'Datepicker'].
  7087. apply($.datepicker, [this].concat(otherArgs)) :
  7088. $.datepicker._attachDatepicker(this, options);
  7089. });
  7090. };
  7091. $.datepicker = new Datepicker(); // singleton instance
  7092. $.datepicker.initialized = false;
  7093. $.datepicker.uuid = new Date().getTime();
  7094. $.datepicker.version = "1.9.1";
  7095. // Workaround for #4055
  7096. // Add another global to avoid noConflict issues with inline event handlers
  7097. window['DP_jQuery_' + dpuuid] = $;
  7098. })(jQuery);
  7099. (function( $, undefined ) {
  7100. var uiDialogClasses = "ui-dialog ui-widget ui-widget-content ui-corner-all ",
  7101. sizeRelatedOptions = {
  7102. buttons: true,
  7103. height: true,
  7104. maxHeight: true,
  7105. maxWidth: true,
  7106. minHeight: true,
  7107. minWidth: true,
  7108. width: true
  7109. },
  7110. resizableRelatedOptions = {
  7111. maxHeight: true,
  7112. maxWidth: true,
  7113. minHeight: true,
  7114. minWidth: true
  7115. };
  7116. $.widget("ui.dialog", {
  7117. version: "1.9.1",
  7118. options: {
  7119. autoOpen: true,
  7120. buttons: {},
  7121. closeOnEscape: true,
  7122. closeText: "close",
  7123. dialogClass: "",
  7124. draggable: true,
  7125. hide: null,
  7126. height: "auto",
  7127. maxHeight: false,
  7128. maxWidth: false,
  7129. minHeight: 150,
  7130. minWidth: 150,
  7131. modal: false,
  7132. position: {
  7133. my: "center",
  7134. at: "center",
  7135. of: window,
  7136. collision: "fit",
  7137. // ensure that the titlebar is never outside the document
  7138. using: function( pos ) {
  7139. var topOffset = $( this ).css( pos ).offset().top;
  7140. if ( topOffset < 0 ) {
  7141. $( this ).css( "top", pos.top - topOffset );
  7142. }
  7143. }
  7144. },
  7145. resizable: true,
  7146. show: null,
  7147. stack: true,
  7148. title: "",
  7149. width: 300,
  7150. zIndex: 1000
  7151. },
  7152. _create: function() {
  7153. this.originalTitle = this.element.attr( "title" );
  7154. // #5742 - .attr() might return a DOMElement
  7155. if ( typeof this.originalTitle !== "string" ) {
  7156. this.originalTitle = "";
  7157. }
  7158. this.oldPosition = {
  7159. parent: this.element.parent(),
  7160. index: this.element.parent().children().index( this.element )
  7161. };
  7162. this.options.title = this.options.title || this.originalTitle;
  7163. var that = this,
  7164. options = this.options,
  7165. title = options.title || "&#160;",
  7166. uiDialog,
  7167. uiDialogTitlebar,
  7168. uiDialogTitlebarClose,
  7169. uiDialogTitle,
  7170. uiDialogButtonPane;
  7171. uiDialog = ( this.uiDialog = $( "<div>" ) )
  7172. .addClass( uiDialogClasses + options.dialogClass )
  7173. .css({
  7174. display: "none",
  7175. outline: 0, // TODO: move to stylesheet
  7176. zIndex: options.zIndex
  7177. })
  7178. // setting tabIndex makes the div focusable
  7179. .attr( "tabIndex", -1)
  7180. .keydown(function( event ) {
  7181. if ( options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
  7182. event.keyCode === $.ui.keyCode.ESCAPE ) {
  7183. that.close( event );
  7184. event.preventDefault();
  7185. }
  7186. })
  7187. .mousedown(function( event ) {
  7188. that.moveToTop( false, event );
  7189. })
  7190. .appendTo( "body" );
  7191. this.element
  7192. .show()
  7193. .removeAttr( "title" )
  7194. .addClass( "ui-dialog-content ui-widget-content" )
  7195. .appendTo( uiDialog );
  7196. uiDialogTitlebar = ( this.uiDialogTitlebar = $( "<div>" ) )
  7197. .addClass( "ui-dialog-titlebar ui-widget-header " +
  7198. "ui-corner-all ui-helper-clearfix" )
  7199. .bind( "mousedown", function() {
  7200. // Dialog isn't getting focus when dragging (#8063)
  7201. uiDialog.focus();
  7202. })
  7203. .prependTo( uiDialog );
  7204. uiDialogTitlebarClose = $( "<a href='#'></a>" )
  7205. .addClass( "ui-dialog-titlebar-close ui-corner-all" )
  7206. .attr( "role", "button" )
  7207. .click(function( event ) {
  7208. event.preventDefault();
  7209. that.close( event );
  7210. })
  7211. .appendTo( uiDialogTitlebar );
  7212. ( this.uiDialogTitlebarCloseText = $( "<span>" ) )
  7213. .addClass( "ui-icon ui-icon-closethick" )
  7214. .text( options.closeText )
  7215. .appendTo( uiDialogTitlebarClose );
  7216. uiDialogTitle = $( "<span>" )
  7217. .uniqueId()
  7218. .addClass( "ui-dialog-title" )
  7219. .html( title )
  7220. .prependTo( uiDialogTitlebar );
  7221. uiDialogButtonPane = ( this.uiDialogButtonPane = $( "<div>" ) )
  7222. .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );
  7223. ( this.uiButtonSet = $( "<div>" ) )
  7224. .addClass( "ui-dialog-buttonset" )
  7225. .appendTo( uiDialogButtonPane );
  7226. uiDialog.attr({
  7227. role: "dialog",
  7228. "aria-labelledby": uiDialogTitle.attr( "id" )
  7229. });
  7230. uiDialogTitlebar.find( "*" ).add( uiDialogTitlebar ).disableSelection();
  7231. this._hoverable( uiDialogTitlebarClose );
  7232. this._focusable( uiDialogTitlebarClose );
  7233. if ( options.draggable && $.fn.draggable ) {
  7234. this._makeDraggable();
  7235. }
  7236. if ( options.resizable && $.fn.resizable ) {
  7237. this._makeResizable();
  7238. }
  7239. this._createButtons( options.buttons );
  7240. this._isOpen = false;
  7241. if ( $.fn.bgiframe ) {
  7242. uiDialog.bgiframe();
  7243. }
  7244. // prevent tabbing out of modal dialogs
  7245. this._on( uiDialog, { keydown: function( event ) {
  7246. if ( !options.modal || event.keyCode !== $.ui.keyCode.TAB ) {
  7247. return;
  7248. }
  7249. var tabbables = $( ":tabbable", uiDialog ),
  7250. first = tabbables.filter( ":first" ),
  7251. last = tabbables.filter( ":last" );
  7252. if ( event.target === last[0] && !event.shiftKey ) {
  7253. first.focus( 1 );
  7254. return false;
  7255. } else if ( event.target === first[0] && event.shiftKey ) {
  7256. last.focus( 1 );
  7257. return false;
  7258. }
  7259. }});
  7260. },
  7261. _init: function() {
  7262. if ( this.options.autoOpen ) {
  7263. this.open();
  7264. }
  7265. },
  7266. _destroy: function() {
  7267. var next,
  7268. oldPosition = this.oldPosition;
  7269. if ( this.overlay ) {
  7270. this.overlay.destroy();
  7271. }
  7272. this.uiDialog.hide();
  7273. this.element
  7274. .removeClass( "ui-dialog-content ui-widget-content" )
  7275. .hide()
  7276. .appendTo( "body" );
  7277. this.uiDialog.remove();
  7278. if ( this.originalTitle ) {
  7279. this.element.attr( "title", this.originalTitle );
  7280. }
  7281. next = oldPosition.parent.children().eq( oldPosition.index );
  7282. // Don't try to place the dialog next to itself (#8613)
  7283. if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
  7284. next.before( this.element );
  7285. } else {
  7286. oldPosition.parent.append( this.element );
  7287. }
  7288. },
  7289. widget: function() {
  7290. return this.uiDialog;
  7291. },
  7292. close: function( event ) {
  7293. var that = this,
  7294. maxZ, thisZ;
  7295. if ( !this._isOpen ) {
  7296. return;
  7297. }
  7298. if ( false === this._trigger( "beforeClose", event ) ) {
  7299. return;
  7300. }
  7301. this._isOpen = false;
  7302. if ( this.overlay ) {
  7303. this.overlay.destroy();
  7304. }
  7305. if ( this.options.hide ) {
  7306. this._hide( this.uiDialog, this.options.hide, function() {
  7307. that._trigger( "close", event );
  7308. });
  7309. } else {
  7310. this.uiDialog.hide();
  7311. this._trigger( "close", event );
  7312. }
  7313. $.ui.dialog.overlay.resize();
  7314. // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
  7315. if ( this.options.modal ) {
  7316. maxZ = 0;
  7317. $( ".ui-dialog" ).each(function() {
  7318. if ( this !== that.uiDialog[0] ) {
  7319. thisZ = $( this ).css( "z-index" );
  7320. if ( !isNaN( thisZ ) ) {
  7321. maxZ = Math.max( maxZ, thisZ );
  7322. }
  7323. }
  7324. });
  7325. $.ui.dialog.maxZ = maxZ;
  7326. }
  7327. return this;
  7328. },
  7329. isOpen: function() {
  7330. return this._isOpen;
  7331. },
  7332. // the force parameter allows us to move modal dialogs to their correct
  7333. // position on open
  7334. moveToTop: function( force, event ) {
  7335. var options = this.options,
  7336. saveScroll;
  7337. if ( ( options.modal && !force ) ||
  7338. ( !options.stack && !options.modal ) ) {
  7339. return this._trigger( "focus", event );
  7340. }
  7341. if ( options.zIndex > $.ui.dialog.maxZ ) {
  7342. $.ui.dialog.maxZ = options.zIndex;
  7343. }
  7344. if ( this.overlay ) {
  7345. $.ui.dialog.maxZ += 1;
  7346. $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ;
  7347. this.overlay.$el.css( "z-index", $.ui.dialog.overlay.maxZ );
  7348. }
  7349. // Save and then restore scroll
  7350. // Opera 9.5+ resets when parent z-index is changed.
  7351. // http://bugs.jqueryui.com/ticket/3193
  7352. saveScroll = {
  7353. scrollTop: this.element.scrollTop(),
  7354. scrollLeft: this.element.scrollLeft()
  7355. };
  7356. $.ui.dialog.maxZ += 1;
  7357. this.uiDialog.css( "z-index", $.ui.dialog.maxZ );
  7358. this.element.attr( saveScroll );
  7359. this._trigger( "focus", event );
  7360. return this;
  7361. },
  7362. open: function() {
  7363. if ( this._isOpen ) {
  7364. return;
  7365. }
  7366. var hasFocus,
  7367. options = this.options,
  7368. uiDialog = this.uiDialog;
  7369. this._size();
  7370. this._position( options.position );
  7371. uiDialog.show( options.show );
  7372. this.overlay = options.modal ? new $.ui.dialog.overlay( this ) : null;
  7373. this.moveToTop( true );
  7374. // set focus to the first tabbable element in the content area or the first button
  7375. // if there are no tabbable elements, set focus on the dialog itself
  7376. hasFocus = this.element.find( ":tabbable" );
  7377. if ( !hasFocus.length ) {
  7378. hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
  7379. if ( !hasFocus.length ) {
  7380. hasFocus = uiDialog;
  7381. }
  7382. }
  7383. hasFocus.eq( 0 ).focus();
  7384. this._isOpen = true;
  7385. this._trigger( "open" );
  7386. return this;
  7387. },
  7388. _createButtons: function( buttons ) {
  7389. var that = this,
  7390. hasButtons = false;
  7391. // if we already have a button pane, remove it
  7392. this.uiDialogButtonPane.remove();
  7393. this.uiButtonSet.empty();
  7394. if ( typeof buttons === "object" && buttons !== null ) {
  7395. $.each( buttons, function() {
  7396. return !(hasButtons = true);
  7397. });
  7398. }
  7399. if ( hasButtons ) {
  7400. $.each( buttons, function( name, props ) {
  7401. props = $.isFunction( props ) ?
  7402. { click: props, text: name } :
  7403. props;
  7404. var button = $( "<button type='button'></button>" )
  7405. .attr( props, true )
  7406. .unbind( "click" )
  7407. .click(function() {
  7408. props.click.apply( that.element[0], arguments );
  7409. })
  7410. .appendTo( that.uiButtonSet );
  7411. if ( $.fn.button ) {
  7412. button.button();
  7413. }
  7414. });
  7415. this.uiDialog.addClass( "ui-dialog-buttons" );
  7416. this.uiDialogButtonPane.appendTo( this.uiDialog );
  7417. } else {
  7418. this.uiDialog.removeClass( "ui-dialog-buttons" );
  7419. }
  7420. },
  7421. _makeDraggable: function() {
  7422. var that = this,
  7423. options = this.options;
  7424. function filteredUi( ui ) {
  7425. return {
  7426. position: ui.position,
  7427. offset: ui.offset
  7428. };
  7429. }
  7430. this.uiDialog.draggable({
  7431. cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
  7432. handle: ".ui-dialog-titlebar",
  7433. containment: "document",
  7434. start: function( event, ui ) {
  7435. $( this )
  7436. .addClass( "ui-dialog-dragging" );
  7437. that._trigger( "dragStart", event, filteredUi( ui ) );
  7438. },
  7439. drag: function( event, ui ) {
  7440. that._trigger( "drag", event, filteredUi( ui ) );
  7441. },
  7442. stop: function( event, ui ) {
  7443. options.position = [
  7444. ui.position.left - that.document.scrollLeft(),
  7445. ui.position.top - that.document.scrollTop()
  7446. ];
  7447. $( this )
  7448. .removeClass( "ui-dialog-dragging" );
  7449. that._trigger( "dragStop", event, filteredUi( ui ) );
  7450. $.ui.dialog.overlay.resize();
  7451. }
  7452. });
  7453. },
  7454. _makeResizable: function( handles ) {
  7455. handles = (handles === undefined ? this.options.resizable : handles);
  7456. var that = this,
  7457. options = this.options,
  7458. // .ui-resizable has position: relative defined in the stylesheet
  7459. // but dialogs have to use absolute or fixed positioning
  7460. position = this.uiDialog.css( "position" ),
  7461. resizeHandles = typeof handles === 'string' ?
  7462. handles :
  7463. "n,e,s,w,se,sw,ne,nw";
  7464. function filteredUi( ui ) {
  7465. return {
  7466. originalPosition: ui.originalPosition,
  7467. originalSize: ui.originalSize,
  7468. position: ui.position,
  7469. size: ui.size
  7470. };
  7471. }
  7472. this.uiDialog.resizable({
  7473. cancel: ".ui-dialog-content",
  7474. containment: "document",
  7475. alsoResize: this.element,
  7476. maxWidth: options.maxWidth,
  7477. maxHeight: options.maxHeight,
  7478. minWidth: options.minWidth,
  7479. minHeight: this._minHeight(),
  7480. handles: resizeHandles,
  7481. start: function( event, ui ) {
  7482. $( this ).addClass( "ui-dialog-resizing" );
  7483. that._trigger( "resizeStart", event, filteredUi( ui ) );
  7484. },
  7485. resize: function( event, ui ) {
  7486. that._trigger( "resize", event, filteredUi( ui ) );
  7487. },
  7488. stop: function( event, ui ) {
  7489. $( this ).removeClass( "ui-dialog-resizing" );
  7490. options.height = $( this ).height();
  7491. options.width = $( this ).width();
  7492. that._trigger( "resizeStop", event, filteredUi( ui ) );
  7493. $.ui.dialog.overlay.resize();
  7494. }
  7495. })
  7496. .css( "position", position )
  7497. .find( ".ui-resizable-se" )
  7498. .addClass( "ui-icon ui-icon-grip-diagonal-se" );
  7499. },
  7500. _minHeight: function() {
  7501. var options = this.options;
  7502. if ( options.height === "auto" ) {
  7503. return options.minHeight;
  7504. } else {
  7505. return Math.min( options.minHeight, options.height );
  7506. }
  7507. },
  7508. _position: function( position ) {
  7509. var myAt = [],
  7510. offset = [ 0, 0 ],
  7511. isVisible;
  7512. if ( position ) {
  7513. // deep extending converts arrays to objects in jQuery <= 1.3.2 :-(
  7514. // if (typeof position == 'string' || $.isArray(position)) {
  7515. // myAt = $.isArray(position) ? position : position.split(' ');
  7516. if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) {
  7517. myAt = position.split ? position.split( " " ) : [ position[ 0 ], position[ 1 ] ];
  7518. if ( myAt.length === 1 ) {
  7519. myAt[ 1 ] = myAt[ 0 ];
  7520. }
  7521. $.each( [ "left", "top" ], function( i, offsetPosition ) {
  7522. if ( +myAt[ i ] === myAt[ i ] ) {
  7523. offset[ i ] = myAt[ i ];
  7524. myAt[ i ] = offsetPosition;
  7525. }
  7526. });
  7527. position = {
  7528. my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " +
  7529. myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]),
  7530. at: myAt.join( " " )
  7531. };
  7532. }
  7533. position = $.extend( {}, $.ui.dialog.prototype.options.position, position );
  7534. } else {
  7535. position = $.ui.dialog.prototype.options.position;
  7536. }
  7537. // need to show the dialog to get the actual offset in the position plugin
  7538. isVisible = this.uiDialog.is( ":visible" );
  7539. if ( !isVisible ) {
  7540. this.uiDialog.show();
  7541. }
  7542. this.uiDialog.position( position );
  7543. if ( !isVisible ) {
  7544. this.uiDialog.hide();
  7545. }
  7546. },
  7547. _setOptions: function( options ) {
  7548. var that = this,
  7549. resizableOptions = {},
  7550. resize = false;
  7551. $.each( options, function( key, value ) {
  7552. that._setOption( key, value );
  7553. if ( key in sizeRelatedOptions ) {
  7554. resize = true;
  7555. }
  7556. if ( key in resizableRelatedOptions ) {
  7557. resizableOptions[ key ] = value;
  7558. }
  7559. });
  7560. if ( resize ) {
  7561. this._size();
  7562. }
  7563. if ( this.uiDialog.is( ":data(resizable)" ) ) {
  7564. this.uiDialog.resizable( "option", resizableOptions );
  7565. }
  7566. },
  7567. _setOption: function( key, value ) {
  7568. var isDraggable, isResizable,
  7569. uiDialog = this.uiDialog;
  7570. switch ( key ) {
  7571. case "buttons":
  7572. this._createButtons( value );
  7573. break;
  7574. case "closeText":
  7575. // ensure that we always pass a string
  7576. this.uiDialogTitlebarCloseText.text( "" + value );
  7577. break;
  7578. case "dialogClass":
  7579. uiDialog
  7580. .removeClass( this.options.dialogClass )
  7581. .addClass( uiDialogClasses + value );
  7582. break;
  7583. case "disabled":
  7584. if ( value ) {
  7585. uiDialog.addClass( "ui-dialog-disabled" );
  7586. } else {
  7587. uiDialog.removeClass( "ui-dialog-disabled" );
  7588. }
  7589. break;
  7590. case "draggable":
  7591. isDraggable = uiDialog.is( ":data(draggable)" );
  7592. if ( isDraggable && !value ) {
  7593. uiDialog.draggable( "destroy" );
  7594. }
  7595. if ( !isDraggable && value ) {
  7596. this._makeDraggable();
  7597. }
  7598. break;
  7599. case "position":
  7600. this._position( value );
  7601. break;
  7602. case "resizable":
  7603. // currently resizable, becoming non-resizable
  7604. isResizable = uiDialog.is( ":data(resizable)" );
  7605. if ( isResizable && !value ) {
  7606. uiDialog.resizable( "destroy" );
  7607. }
  7608. // currently resizable, changing handles
  7609. if ( isResizable && typeof value === "string" ) {
  7610. uiDialog.resizable( "option", "handles", value );
  7611. }
  7612. // currently non-resizable, becoming resizable
  7613. if ( !isResizable && value !== false ) {
  7614. this._makeResizable( value );
  7615. }
  7616. break;
  7617. case "title":
  7618. // convert whatever was passed in o a string, for html() to not throw up
  7619. $( ".ui-dialog-title", this.uiDialogTitlebar )
  7620. .html( "" + ( value || "&#160;" ) );
  7621. break;
  7622. }
  7623. this._super( key, value );
  7624. },
  7625. _size: function() {
  7626. /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
  7627. * divs will both have width and height set, so we need to reset them
  7628. */
  7629. var nonContentHeight, minContentHeight, autoHeight,
  7630. options = this.options,
  7631. isVisible = this.uiDialog.is( ":visible" );
  7632. // reset content sizing
  7633. this.element.show().css({
  7634. width: "auto",
  7635. minHeight: 0,
  7636. height: 0
  7637. });
  7638. if ( options.minWidth > options.width ) {
  7639. options.width = options.minWidth;
  7640. }
  7641. // reset wrapper sizing
  7642. // determine the height of all the non-content elements
  7643. nonContentHeight = this.uiDialog.css({
  7644. height: "auto",
  7645. width: options.width
  7646. })
  7647. .outerHeight();
  7648. minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
  7649. if ( options.height === "auto" ) {
  7650. // only needed for IE6 support
  7651. if ( $.support.minHeight ) {
  7652. this.element.css({
  7653. minHeight: minContentHeight,
  7654. height: "auto"
  7655. });
  7656. } else {
  7657. this.uiDialog.show();
  7658. autoHeight = this.element.css( "height", "auto" ).height();
  7659. if ( !isVisible ) {
  7660. this.uiDialog.hide();
  7661. }
  7662. this.element.height( Math.max( autoHeight, minContentHeight ) );
  7663. }
  7664. } else {
  7665. this.element.height( Math.max( options.height - nonContentHeight, 0 ) );
  7666. }
  7667. if (this.uiDialog.is( ":data(resizable)" ) ) {
  7668. this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
  7669. }
  7670. }
  7671. });
  7672. $.extend($.ui.dialog, {
  7673. uuid: 0,
  7674. maxZ: 0,
  7675. getTitleId: function($el) {
  7676. var id = $el.attr( "id" );
  7677. if ( !id ) {
  7678. this.uuid += 1;
  7679. id = this.uuid;
  7680. }
  7681. return "ui-dialog-title-" + id;
  7682. },
  7683. overlay: function( dialog ) {
  7684. this.$el = $.ui.dialog.overlay.create( dialog );
  7685. }
  7686. });
  7687. $.extend( $.ui.dialog.overlay, {
  7688. instances: [],
  7689. // reuse old instances due to IE memory leak with alpha transparency (see #5185)
  7690. oldInstances: [],
  7691. maxZ: 0,
  7692. events: $.map(
  7693. "focus,mousedown,mouseup,keydown,keypress,click".split( "," ),
  7694. function( event ) {
  7695. return event + ".dialog-overlay";
  7696. }
  7697. ).join( " " ),
  7698. create: function( dialog ) {
  7699. if ( this.instances.length === 0 ) {
  7700. // prevent use of anchors and inputs
  7701. // we use a setTimeout in case the overlay is created from an
  7702. // event that we're going to be cancelling (see #2804)
  7703. setTimeout(function() {
  7704. // handle $(el).dialog().dialog('close') (see #4065)
  7705. if ( $.ui.dialog.overlay.instances.length ) {
  7706. $( document ).bind( $.ui.dialog.overlay.events, function( event ) {
  7707. // stop events if the z-index of the target is < the z-index of the overlay
  7708. // we cannot return true when we don't want to cancel the event (#3523)
  7709. if ( $( event.target ).zIndex() < $.ui.dialog.overlay.maxZ ) {
  7710. return false;
  7711. }
  7712. });
  7713. }
  7714. }, 1 );
  7715. // handle window resize
  7716. $( window ).bind( "resize.dialog-overlay", $.ui.dialog.overlay.resize );
  7717. }
  7718. var $el = ( this.oldInstances.pop() || $( "<div>" ).addClass( "ui-widget-overlay" ) );
  7719. // allow closing by pressing the escape key
  7720. $( document ).bind( "keydown.dialog-overlay", function( event ) {
  7721. var instances = $.ui.dialog.overlay.instances;
  7722. // only react to the event if we're the top overlay
  7723. if ( instances.length !== 0 && instances[ instances.length - 1 ] === $el &&
  7724. dialog.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
  7725. event.keyCode === $.ui.keyCode.ESCAPE ) {
  7726. dialog.close( event );
  7727. event.preventDefault();
  7728. }
  7729. });
  7730. $el.appendTo( document.body ).css({
  7731. width: this.width(),
  7732. height: this.height()
  7733. });
  7734. if ( $.fn.bgiframe ) {
  7735. $el.bgiframe();
  7736. }
  7737. this.instances.push( $el );
  7738. return $el;
  7739. },
  7740. destroy: function( $el ) {
  7741. var indexOf = $.inArray( $el, this.instances ),
  7742. maxZ = 0;
  7743. if ( indexOf !== -1 ) {
  7744. this.oldInstances.push( this.instances.splice( indexOf, 1 )[ 0 ] );
  7745. }
  7746. if ( this.instances.length === 0 ) {
  7747. $( [ document, window ] ).unbind( ".dialog-overlay" );
  7748. }
  7749. $el.height( 0 ).width( 0 ).remove();
  7750. // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
  7751. $.each( this.instances, function() {
  7752. maxZ = Math.max( maxZ, this.css( "z-index" ) );
  7753. });
  7754. this.maxZ = maxZ;
  7755. },
  7756. height: function() {
  7757. var scrollHeight,
  7758. offsetHeight;
  7759. // handle IE
  7760. if ( $.ui.ie ) {
  7761. scrollHeight = Math.max(
  7762. document.documentElement.scrollHeight,
  7763. document.body.scrollHeight
  7764. );
  7765. offsetHeight = Math.max(
  7766. document.documentElement.offsetHeight,
  7767. document.body.offsetHeight
  7768. );
  7769. if ( scrollHeight < offsetHeight ) {
  7770. return $( window ).height() + "px";
  7771. } else {
  7772. return scrollHeight + "px";
  7773. }
  7774. // handle "good" browsers
  7775. } else {
  7776. return $( document ).height() + "px";
  7777. }
  7778. },
  7779. width: function() {
  7780. var scrollWidth,
  7781. offsetWidth;
  7782. // handle IE
  7783. if ( $.ui.ie ) {
  7784. scrollWidth = Math.max(
  7785. document.documentElement.scrollWidth,
  7786. document.body.scrollWidth
  7787. );
  7788. offsetWidth = Math.max(
  7789. document.documentElement.offsetWidth,
  7790. document.body.offsetWidth
  7791. );
  7792. if ( scrollWidth < offsetWidth ) {
  7793. return $( window ).width() + "px";
  7794. } else {
  7795. return scrollWidth + "px";
  7796. }
  7797. // handle "good" browsers
  7798. } else {
  7799. return $( document ).width() + "px";
  7800. }
  7801. },
  7802. resize: function() {
  7803. /* If the dialog is draggable and the user drags it past the
  7804. * right edge of the window, the document becomes wider so we
  7805. * need to stretch the overlay. If the user then drags the
  7806. * dialog back to the left, the document will become narrower,
  7807. * so we need to shrink the overlay to the appropriate size.
  7808. * This is handled by shrinking the overlay before setting it
  7809. * to the full document size.
  7810. */
  7811. var $overlays = $( [] );
  7812. $.each( $.ui.dialog.overlay.instances, function() {
  7813. $overlays = $overlays.add( this );
  7814. });
  7815. $overlays.css({
  7816. width: 0,
  7817. height: 0
  7818. }).css({
  7819. width: $.ui.dialog.overlay.width(),
  7820. height: $.ui.dialog.overlay.height()
  7821. });
  7822. }
  7823. });
  7824. $.extend( $.ui.dialog.overlay.prototype, {
  7825. destroy: function() {
  7826. $.ui.dialog.overlay.destroy( this.$el );
  7827. }
  7828. });
  7829. }( jQuery ) );
  7830. (function( $, undefined ) {
  7831. var mouseHandled = false;
  7832. $.widget( "ui.menu", {
  7833. version: "1.9.1",
  7834. defaultElement: "<ul>",
  7835. delay: 300,
  7836. options: {
  7837. icons: {
  7838. submenu: "ui-icon-carat-1-e"
  7839. },
  7840. menus: "ul",
  7841. position: {
  7842. my: "left top",
  7843. at: "right top"
  7844. },
  7845. role: "menu",
  7846. // callbacks
  7847. blur: null,
  7848. focus: null,
  7849. select: null
  7850. },
  7851. _create: function() {
  7852. this.activeMenu = this.element;
  7853. this.element
  7854. .uniqueId()
  7855. .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
  7856. .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
  7857. .attr({
  7858. role: this.options.role,
  7859. tabIndex: 0
  7860. })
  7861. // need to catch all clicks on disabled menu
  7862. // not possible through _on
  7863. .bind( "click" + this.eventNamespace, $.proxy(function( event ) {
  7864. if ( this.options.disabled ) {
  7865. event.preventDefault();
  7866. }
  7867. }, this ));
  7868. if ( this.options.disabled ) {
  7869. this.element
  7870. .addClass( "ui-state-disabled" )
  7871. .attr( "aria-disabled", "true" );
  7872. }
  7873. this._on({
  7874. // Prevent focus from sticking to links inside menu after clicking
  7875. // them (focus should always stay on UL during navigation).
  7876. "mousedown .ui-menu-item > a": function( event ) {
  7877. event.preventDefault();
  7878. },
  7879. "click .ui-state-disabled > a": function( event ) {
  7880. event.preventDefault();
  7881. },
  7882. "click .ui-menu-item:has(a)": function( event ) {
  7883. var target = $( event.target ).closest( ".ui-menu-item" );
  7884. if ( !mouseHandled && target.not( ".ui-state-disabled" ).length ) {
  7885. mouseHandled = true;
  7886. this.select( event );
  7887. // Open submenu on click
  7888. if ( target.has( ".ui-menu" ).length ) {
  7889. this.expand( event );
  7890. } else if ( !this.element.is( ":focus" ) ) {
  7891. // Redirect focus to the menu
  7892. this.element.trigger( "focus", [ true ] );
  7893. // If the active item is on the top level, let it stay active.
  7894. // Otherwise, blur the active item since it is no longer visible.
  7895. if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
  7896. clearTimeout( this.timer );
  7897. }
  7898. }
  7899. }
  7900. },
  7901. "mouseenter .ui-menu-item": function( event ) {
  7902. var target = $( event.currentTarget );
  7903. // Remove ui-state-active class from siblings of the newly focused menu item
  7904. // to avoid a jump caused by adjacent elements both having a class with a border
  7905. target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" );
  7906. this.focus( event, target );
  7907. },
  7908. mouseleave: "collapseAll",
  7909. "mouseleave .ui-menu": "collapseAll",
  7910. focus: function( event, keepActiveItem ) {
  7911. // If there's already an active item, keep it active
  7912. // If not, activate the first item
  7913. var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 );
  7914. if ( !keepActiveItem ) {
  7915. this.focus( event, item );
  7916. }
  7917. },
  7918. blur: function( event ) {
  7919. this._delay(function() {
  7920. if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
  7921. this.collapseAll( event );
  7922. }
  7923. });
  7924. },
  7925. keydown: "_keydown"
  7926. });
  7927. this.refresh();
  7928. // Clicks outside of a menu collapse any open menus
  7929. this._on( this.document, {
  7930. click: function( event ) {
  7931. if ( !$( event.target ).closest( ".ui-menu" ).length ) {
  7932. this.collapseAll( event );
  7933. }
  7934. // Reset the mouseHandled flag
  7935. mouseHandled = false;
  7936. }
  7937. });
  7938. },
  7939. _destroy: function() {
  7940. // Destroy (sub)menus
  7941. this.element
  7942. .removeAttr( "aria-activedescendant" )
  7943. .find( ".ui-menu" ).andSelf()
  7944. .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" )
  7945. .removeAttr( "role" )
  7946. .removeAttr( "tabIndex" )
  7947. .removeAttr( "aria-labelledby" )
  7948. .removeAttr( "aria-expanded" )
  7949. .removeAttr( "aria-hidden" )
  7950. .removeAttr( "aria-disabled" )
  7951. .removeUniqueId()
  7952. .show();
  7953. // Destroy menu items
  7954. this.element.find( ".ui-menu-item" )
  7955. .removeClass( "ui-menu-item" )
  7956. .removeAttr( "role" )
  7957. .removeAttr( "aria-disabled" )
  7958. .children( "a" )
  7959. .removeUniqueId()
  7960. .removeClass( "ui-corner-all ui-state-hover" )
  7961. .removeAttr( "tabIndex" )
  7962. .removeAttr( "role" )
  7963. .removeAttr( "aria-haspopup" )
  7964. .children().each( function() {
  7965. var elem = $( this );
  7966. if ( elem.data( "ui-menu-submenu-carat" ) ) {
  7967. elem.remove();
  7968. }
  7969. });
  7970. // Destroy menu dividers
  7971. this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
  7972. },
  7973. _keydown: function( event ) {
  7974. var match, prev, character, skip, regex,
  7975. preventDefault = true;
  7976. function escape( value ) {
  7977. return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
  7978. }
  7979. switch ( event.keyCode ) {
  7980. case $.ui.keyCode.PAGE_UP:
  7981. this.previousPage( event );
  7982. break;
  7983. case $.ui.keyCode.PAGE_DOWN:
  7984. this.nextPage( event );
  7985. break;
  7986. case $.ui.keyCode.HOME:
  7987. this._move( "first", "first", event );
  7988. break;
  7989. case $.ui.keyCode.END:
  7990. this._move( "last", "last", event );
  7991. break;
  7992. case $.ui.keyCode.UP:
  7993. this.previous( event );
  7994. break;
  7995. case $.ui.keyCode.DOWN:
  7996. this.next( event );
  7997. break;
  7998. case $.ui.keyCode.LEFT:
  7999. this.collapse( event );
  8000. break;
  8001. case $.ui.keyCode.RIGHT:
  8002. if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
  8003. this.expand( event );
  8004. }
  8005. break;
  8006. case $.ui.keyCode.ENTER:
  8007. case $.ui.keyCode.SPACE:
  8008. this._activate( event );
  8009. break;
  8010. case $.ui.keyCode.ESCAPE:
  8011. this.collapse( event );
  8012. break;
  8013. default:
  8014. preventDefault = false;
  8015. prev = this.previousFilter || "";
  8016. character = String.fromCharCode( event.keyCode );
  8017. skip = false;
  8018. clearTimeout( this.filterTimer );
  8019. if ( character === prev ) {
  8020. skip = true;
  8021. } else {
  8022. character = prev + character;
  8023. }
  8024. regex = new RegExp( "^" + escape( character ), "i" );
  8025. match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
  8026. return regex.test( $( this ).children( "a" ).text() );
  8027. });
  8028. match = skip && match.index( this.active.next() ) !== -1 ?
  8029. this.active.nextAll( ".ui-menu-item" ) :
  8030. match;
  8031. // If no matches on the current filter, reset to the last character pressed
  8032. // to move down the menu to the first item that starts with that character
  8033. if ( !match.length ) {
  8034. character = String.fromCharCode( event.keyCode );
  8035. regex = new RegExp( "^" + escape( character ), "i" );
  8036. match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
  8037. return regex.test( $( this ).children( "a" ).text() );
  8038. });
  8039. }
  8040. if ( match.length ) {
  8041. this.focus( event, match );
  8042. if ( match.length > 1 ) {
  8043. this.previousFilter = character;
  8044. this.filterTimer = this._delay(function() {
  8045. delete this.previousFilter;
  8046. }, 1000 );
  8047. } else {
  8048. delete this.previousFilter;
  8049. }
  8050. } else {
  8051. delete this.previousFilter;
  8052. }
  8053. }
  8054. if ( preventDefault ) {
  8055. event.preventDefault();
  8056. }
  8057. },
  8058. _activate: function( event ) {
  8059. if ( !this.active.is( ".ui-state-disabled" ) ) {
  8060. if ( this.active.children( "a[aria-haspopup='true']" ).length ) {
  8061. this.expand( event );
  8062. } else {
  8063. this.select( event );
  8064. }
  8065. }
  8066. },
  8067. refresh: function() {
  8068. // Initialize nested menus
  8069. var menus,
  8070. icon = this.options.icons.submenu,
  8071. submenus = this.element.find( this.options.menus + ":not(.ui-menu)" )
  8072. .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
  8073. .hide()
  8074. .attr({
  8075. role: this.options.role,
  8076. "aria-hidden": "true",
  8077. "aria-expanded": "false"
  8078. });
  8079. // Don't refresh list items that are already adapted
  8080. menus = submenus.add( this.element );
  8081. menus.children( ":not(.ui-menu-item):has(a)" )
  8082. .addClass( "ui-menu-item" )
  8083. .attr( "role", "presentation" )
  8084. .children( "a" )
  8085. .uniqueId()
  8086. .addClass( "ui-corner-all" )
  8087. .attr({
  8088. tabIndex: -1,
  8089. role: this._itemRole()
  8090. });
  8091. // Initialize unlinked menu-items containing spaces and/or dashes only as dividers
  8092. menus.children( ":not(.ui-menu-item)" ).each(function() {
  8093. var item = $( this );
  8094. // hyphen, em dash, en dash
  8095. if ( !/[^\-—–\s]/.test( item.text() ) ) {
  8096. item.addClass( "ui-widget-content ui-menu-divider" );
  8097. }
  8098. });
  8099. // Add aria-disabled attribute to any disabled menu item
  8100. menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
  8101. submenus.each(function() {
  8102. var menu = $( this ),
  8103. item = menu.prev( "a" ),
  8104. submenuCarat = $( "<span>" )
  8105. .addClass( "ui-menu-icon ui-icon " + icon )
  8106. .data( "ui-menu-submenu-carat", true );
  8107. item
  8108. .attr( "aria-haspopup", "true" )
  8109. .prepend( submenuCarat );
  8110. menu.attr( "aria-labelledby", item.attr( "id" ) );
  8111. });
  8112. // If the active item has been removed, blur the menu
  8113. if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
  8114. this.blur();
  8115. }
  8116. },
  8117. _itemRole: function() {
  8118. return {
  8119. menu: "menuitem",
  8120. listbox: "option"
  8121. }[ this.options.role ];
  8122. },
  8123. focus: function( event, item ) {
  8124. var nested, focused;
  8125. this.blur( event, event && event.type === "focus" );
  8126. this._scrollIntoView( item );
  8127. this.active = item.first();
  8128. focused = this.active.children( "a" ).addClass( "ui-state-focus" );
  8129. // Only update aria-activedescendant if there's a role
  8130. // otherwise we assume focus is managed elsewhere
  8131. if ( this.options.role ) {
  8132. this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
  8133. }
  8134. // Highlight active parent menu item, if any
  8135. this.active
  8136. .parent()
  8137. .closest( ".ui-menu-item" )
  8138. .children( "a:first" )
  8139. .addClass( "ui-state-active" );
  8140. if ( event && event.type === "keydown" ) {
  8141. this._close();
  8142. } else {
  8143. this.timer = this._delay(function() {
  8144. this._close();
  8145. }, this.delay );
  8146. }
  8147. nested = item.children( ".ui-menu" );
  8148. if ( nested.length && ( /^mouse/.test( event.type ) ) ) {
  8149. this._startOpening(nested);
  8150. }
  8151. this.activeMenu = item.parent();
  8152. this._trigger( "focus", event, { item: item } );
  8153. },
  8154. _scrollIntoView: function( item ) {
  8155. var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
  8156. if ( this._hasScroll() ) {
  8157. borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
  8158. paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
  8159. offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
  8160. scroll = this.activeMenu.scrollTop();
  8161. elementHeight = this.activeMenu.height();
  8162. itemHeight = item.height();
  8163. if ( offset < 0 ) {
  8164. this.activeMenu.scrollTop( scroll + offset );
  8165. } else if ( offset + itemHeight > elementHeight ) {
  8166. this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
  8167. }
  8168. }
  8169. },
  8170. blur: function( event, fromFocus ) {
  8171. if ( !fromFocus ) {
  8172. clearTimeout( this.timer );
  8173. }
  8174. if ( !this.active ) {
  8175. return;
  8176. }
  8177. this.active.children( "a" ).removeClass( "ui-state-focus" );
  8178. this.active = null;
  8179. this._trigger( "blur", event, { item: this.active } );
  8180. },
  8181. _startOpening: function( submenu ) {
  8182. clearTimeout( this.timer );
  8183. // Don't open if already open fixes a Firefox bug that caused a .5 pixel
  8184. // shift in the submenu position when mousing over the carat icon
  8185. if ( submenu.attr( "aria-hidden" ) !== "true" ) {
  8186. return;
  8187. }
  8188. this.timer = this._delay(function() {
  8189. this._close();
  8190. this._open( submenu );
  8191. }, this.delay );
  8192. },
  8193. _open: function( submenu ) {
  8194. var position = $.extend({
  8195. of: this.active
  8196. }, this.options.position );
  8197. clearTimeout( this.timer );
  8198. this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
  8199. .hide()
  8200. .attr( "aria-hidden", "true" );
  8201. submenu
  8202. .show()
  8203. .removeAttr( "aria-hidden" )
  8204. .attr( "aria-expanded", "true" )
  8205. .position( position );
  8206. },
  8207. collapseAll: function( event, all ) {
  8208. clearTimeout( this.timer );
  8209. this.timer = this._delay(function() {
  8210. // If we were passed an event, look for the submenu that contains the event
  8211. var currentMenu = all ? this.element :
  8212. $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
  8213. // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
  8214. if ( !currentMenu.length ) {
  8215. currentMenu = this.element;
  8216. }
  8217. this._close( currentMenu );
  8218. this.blur( event );
  8219. this.activeMenu = currentMenu;
  8220. }, this.delay );
  8221. },
  8222. // With no arguments, closes the currently active menu - if nothing is active
  8223. // it closes all menus. If passed an argument, it will search for menus BELOW
  8224. _close: function( startMenu ) {
  8225. if ( !startMenu ) {
  8226. startMenu = this.active ? this.active.parent() : this.element;
  8227. }
  8228. startMenu
  8229. .find( ".ui-menu" )
  8230. .hide()
  8231. .attr( "aria-hidden", "true" )
  8232. .attr( "aria-expanded", "false" )
  8233. .end()
  8234. .find( "a.ui-state-active" )
  8235. .removeClass( "ui-state-active" );
  8236. },
  8237. collapse: function( event ) {
  8238. var newItem = this.active &&
  8239. this.active.parent().closest( ".ui-menu-item", this.element );
  8240. if ( newItem && newItem.length ) {
  8241. this._close();
  8242. this.focus( event, newItem );
  8243. }
  8244. },
  8245. expand: function( event ) {
  8246. var newItem = this.active &&
  8247. this.active
  8248. .children( ".ui-menu " )
  8249. .children( ".ui-menu-item" )
  8250. .first();
  8251. if ( newItem && newItem.length ) {
  8252. this._open( newItem.parent() );
  8253. // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
  8254. this._delay(function() {
  8255. this.focus( event, newItem );
  8256. });
  8257. }
  8258. },
  8259. next: function( event ) {
  8260. this._move( "next", "first", event );
  8261. },
  8262. previous: function( event ) {
  8263. this._move( "prev", "last", event );
  8264. },
  8265. isFirstItem: function() {
  8266. return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
  8267. },
  8268. isLastItem: function() {
  8269. return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
  8270. },
  8271. _move: function( direction, filter, event ) {
  8272. var next;
  8273. if ( this.active ) {
  8274. if ( direction === "first" || direction === "last" ) {
  8275. next = this.active
  8276. [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
  8277. .eq( -1 );
  8278. } else {
  8279. next = this.active
  8280. [ direction + "All" ]( ".ui-menu-item" )
  8281. .eq( 0 );
  8282. }
  8283. }
  8284. if ( !next || !next.length || !this.active ) {
  8285. next = this.activeMenu.children( ".ui-menu-item" )[ filter ]();
  8286. }
  8287. this.focus( event, next );
  8288. },
  8289. nextPage: function( event ) {
  8290. var item, base, height;
  8291. if ( !this.active ) {
  8292. this.next( event );
  8293. return;
  8294. }
  8295. if ( this.isLastItem() ) {
  8296. return;
  8297. }
  8298. if ( this._hasScroll() ) {
  8299. base = this.active.offset().top;
  8300. height = this.element.height();
  8301. this.active.nextAll( ".ui-menu-item" ).each(function() {
  8302. item = $( this );
  8303. return item.offset().top - base - height < 0;
  8304. });
  8305. this.focus( event, item );
  8306. } else {
  8307. this.focus( event, this.activeMenu.children( ".ui-menu-item" )
  8308. [ !this.active ? "first" : "last" ]() );
  8309. }
  8310. },
  8311. previousPage: function( event ) {
  8312. var item, base, height;
  8313. if ( !this.active ) {
  8314. this.next( event );
  8315. return;
  8316. }
  8317. if ( this.isFirstItem() ) {
  8318. return;
  8319. }
  8320. if ( this._hasScroll() ) {
  8321. base = this.active.offset().top;
  8322. height = this.element.height();
  8323. this.active.prevAll( ".ui-menu-item" ).each(function() {
  8324. item = $( this );
  8325. return item.offset().top - base + height > 0;
  8326. });
  8327. this.focus( event, item );
  8328. } else {
  8329. this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
  8330. }
  8331. },
  8332. _hasScroll: function() {
  8333. return this.element.outerHeight() < this.element.prop( "scrollHeight" );
  8334. },
  8335. select: function( event ) {
  8336. // TODO: It should never be possible to not have an active item at this
  8337. // point, but the tests don't trigger mouseenter before click.
  8338. this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
  8339. var ui = { item: this.active };
  8340. if ( !this.active.has( ".ui-menu" ).length ) {
  8341. this.collapseAll( event, true );
  8342. }
  8343. this._trigger( "select", event, ui );
  8344. }
  8345. });
  8346. }( jQuery ));
  8347. (function( $, undefined ) {
  8348. $.widget( "ui.progressbar", {
  8349. version: "1.9.1",
  8350. options: {
  8351. value: 0,
  8352. max: 100
  8353. },
  8354. min: 0,
  8355. _create: function() {
  8356. this.element
  8357. .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
  8358. .attr({
  8359. role: "progressbar",
  8360. "aria-valuemin": this.min,
  8361. "aria-valuemax": this.options.max,
  8362. "aria-valuenow": this._value()
  8363. });
  8364. this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
  8365. .appendTo( this.element );
  8366. this.oldValue = this._value();
  8367. this._refreshValue();
  8368. },
  8369. _destroy: function() {
  8370. this.element
  8371. .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
  8372. .removeAttr( "role" )
  8373. .removeAttr( "aria-valuemin" )
  8374. .removeAttr( "aria-valuemax" )
  8375. .removeAttr( "aria-valuenow" );
  8376. this.valueDiv.remove();
  8377. },
  8378. value: function( newValue ) {
  8379. if ( newValue === undefined ) {
  8380. return this._value();
  8381. }
  8382. this._setOption( "value", newValue );
  8383. return this;
  8384. },
  8385. _setOption: function( key, value ) {
  8386. if ( key === "value" ) {
  8387. this.options.value = value;
  8388. this._refreshValue();
  8389. if ( this._value() === this.options.max ) {
  8390. this._trigger( "complete" );
  8391. }
  8392. }
  8393. this._super( key, value );
  8394. },
  8395. _value: function() {
  8396. var val = this.options.value;
  8397. // normalize invalid value
  8398. if ( typeof val !== "number" ) {
  8399. val = 0;
  8400. }
  8401. return Math.min( this.options.max, Math.max( this.min, val ) );
  8402. },
  8403. _percentage: function() {
  8404. return 100 * this._value() / this.options.max;
  8405. },
  8406. _refreshValue: function() {
  8407. var value = this.value(),
  8408. percentage = this._percentage();
  8409. if ( this.oldValue !== value ) {
  8410. this.oldValue = value;
  8411. this._trigger( "change" );
  8412. }
  8413. this.valueDiv
  8414. .toggle( value > this.min )
  8415. .toggleClass( "ui-corner-right", value === this.options.max )
  8416. .width( percentage.toFixed(0) + "%" );
  8417. this.element.attr( "aria-valuenow", value );
  8418. }
  8419. });
  8420. })( jQuery );
  8421. (function( $, undefined ) {
  8422. // number of pages in a slider
  8423. // (how many times can you page up/down to go through the whole range)
  8424. var numPages = 5;
  8425. $.widget( "ui.slider", $.ui.mouse, {
  8426. version: "1.9.1",
  8427. widgetEventPrefix: "slide",
  8428. options: {
  8429. animate: false,
  8430. distance: 0,
  8431. max: 100,
  8432. min: 0,
  8433. orientation: "horizontal",
  8434. range: false,
  8435. step: 1,
  8436. value: 0,
  8437. values: null
  8438. },
  8439. _create: function() {
  8440. var i, handleCount,
  8441. o = this.options,
  8442. existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
  8443. handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
  8444. handles = [];
  8445. this._keySliding = false;
  8446. this._mouseSliding = false;
  8447. this._animateOff = true;
  8448. this._handleIndex = null;
  8449. this._detectOrientation();
  8450. this._mouseInit();
  8451. this.element
  8452. .addClass( "ui-slider" +
  8453. " ui-slider-" + this.orientation +
  8454. " ui-widget" +
  8455. " ui-widget-content" +
  8456. " ui-corner-all" +
  8457. ( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) );
  8458. this.range = $([]);
  8459. if ( o.range ) {
  8460. if ( o.range === true ) {
  8461. if ( !o.values ) {
  8462. o.values = [ this._valueMin(), this._valueMin() ];
  8463. }
  8464. if ( o.values.length && o.values.length !== 2 ) {
  8465. o.values = [ o.values[0], o.values[0] ];
  8466. }
  8467. }
  8468. this.range = $( "<div></div>" )
  8469. .appendTo( this.element )
  8470. .addClass( "ui-slider-range" +
  8471. // note: this isn't the most fittingly semantic framework class for this element,
  8472. // but worked best visually with a variety of themes
  8473. " ui-widget-header" +
  8474. ( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) );
  8475. }
  8476. handleCount = ( o.values && o.values.length ) || 1;
  8477. for ( i = existingHandles.length; i < handleCount; i++ ) {
  8478. handles.push( handle );
  8479. }
  8480. this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
  8481. this.handle = this.handles.eq( 0 );
  8482. this.handles.add( this.range ).filter( "a" )
  8483. .click(function( event ) {
  8484. event.preventDefault();
  8485. })
  8486. .mouseenter(function() {
  8487. if ( !o.disabled ) {
  8488. $( this ).addClass( "ui-state-hover" );
  8489. }
  8490. })
  8491. .mouseleave(function() {
  8492. $( this ).removeClass( "ui-state-hover" );
  8493. })
  8494. .focus(function() {
  8495. if ( !o.disabled ) {
  8496. $( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" );
  8497. $( this ).addClass( "ui-state-focus" );
  8498. } else {
  8499. $( this ).blur();
  8500. }
  8501. })
  8502. .blur(function() {
  8503. $( this ).removeClass( "ui-state-focus" );
  8504. });
  8505. this.handles.each(function( i ) {
  8506. $( this ).data( "ui-slider-handle-index", i );
  8507. });
  8508. this._on( this.handles, {
  8509. keydown: function( event ) {
  8510. var allowed, curVal, newVal, step,
  8511. index = $( event.target ).data( "ui-slider-handle-index" );
  8512. switch ( event.keyCode ) {
  8513. case $.ui.keyCode.HOME:
  8514. case $.ui.keyCode.END:
  8515. case $.ui.keyCode.PAGE_UP:
  8516. case $.ui.keyCode.PAGE_DOWN:
  8517. case $.ui.keyCode.UP:
  8518. case $.ui.keyCode.RIGHT:
  8519. case $.ui.keyCode.DOWN:
  8520. case $.ui.keyCode.LEFT:
  8521. event.preventDefault();
  8522. if ( !this._keySliding ) {
  8523. this._keySliding = true;
  8524. $( event.target ).addClass( "ui-state-active" );
  8525. allowed = this._start( event, index );
  8526. if ( allowed === false ) {
  8527. return;
  8528. }
  8529. }
  8530. break;
  8531. }
  8532. step = this.options.step;
  8533. if ( this.options.values && this.options.values.length ) {
  8534. curVal = newVal = this.values( index );
  8535. } else {
  8536. curVal = newVal = this.value();
  8537. }
  8538. switch ( event.keyCode ) {
  8539. case $.ui.keyCode.HOME:
  8540. newVal = this._valueMin();
  8541. break;
  8542. case $.ui.keyCode.END:
  8543. newVal = this._valueMax();
  8544. break;
  8545. case $.ui.keyCode.PAGE_UP:
  8546. newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );
  8547. break;
  8548. case $.ui.keyCode.PAGE_DOWN:
  8549. newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );
  8550. break;
  8551. case $.ui.keyCode.UP:
  8552. case $.ui.keyCode.RIGHT:
  8553. if ( curVal === this._valueMax() ) {
  8554. return;
  8555. }
  8556. newVal = this._trimAlignValue( curVal + step );
  8557. break;
  8558. case $.ui.keyCode.DOWN:
  8559. case $.ui.keyCode.LEFT:
  8560. if ( curVal === this._valueMin() ) {
  8561. return;
  8562. }
  8563. newVal = this._trimAlignValue( curVal - step );
  8564. break;
  8565. }
  8566. this._slide( event, index, newVal );
  8567. },
  8568. keyup: function( event ) {
  8569. var index = $( event.target ).data( "ui-slider-handle-index" );
  8570. if ( this._keySliding ) {
  8571. this._keySliding = false;
  8572. this._stop( event, index );
  8573. this._change( event, index );
  8574. $( event.target ).removeClass( "ui-state-active" );
  8575. }
  8576. }
  8577. });
  8578. this._refreshValue();
  8579. this._animateOff = false;
  8580. },
  8581. _destroy: function() {
  8582. this.handles.remove();
  8583. this.range.remove();
  8584. this.element
  8585. .removeClass( "ui-slider" +
  8586. " ui-slider-horizontal" +
  8587. " ui-slider-vertical" +
  8588. " ui-slider-disabled" +
  8589. " ui-widget" +
  8590. " ui-widget-content" +
  8591. " ui-corner-all" );
  8592. this._mouseDestroy();
  8593. },
  8594. _mouseCapture: function( event ) {
  8595. var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
  8596. that = this,
  8597. o = this.options;
  8598. if ( o.disabled ) {
  8599. return false;
  8600. }
  8601. this.elementSize = {
  8602. width: this.element.outerWidth(),
  8603. height: this.element.outerHeight()
  8604. };
  8605. this.elementOffset = this.element.offset();
  8606. position = { x: event.pageX, y: event.pageY };
  8607. normValue = this._normValueFromMouse( position );
  8608. distance = this._valueMax() - this._valueMin() + 1;
  8609. this.handles.each(function( i ) {
  8610. var thisDistance = Math.abs( normValue - that.values(i) );
  8611. if ( distance > thisDistance ) {
  8612. distance = thisDistance;
  8613. closestHandle = $( this );
  8614. index = i;
  8615. }
  8616. });
  8617. // workaround for bug #3736 (if both handles of a range are at 0,
  8618. // the first is always used as the one with least distance,
  8619. // and moving it is obviously prevented by preventing negative ranges)
  8620. if( o.range === true && this.values(1) === o.min ) {
  8621. index += 1;
  8622. closestHandle = $( this.handles[index] );
  8623. }
  8624. allowed = this._start( event, index );
  8625. if ( allowed === false ) {
  8626. return false;
  8627. }
  8628. this._mouseSliding = true;
  8629. this._handleIndex = index;
  8630. closestHandle
  8631. .addClass( "ui-state-active" )
  8632. .focus();
  8633. offset = closestHandle.offset();
  8634. mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" );
  8635. this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
  8636. left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
  8637. top: event.pageY - offset.top -
  8638. ( closestHandle.height() / 2 ) -
  8639. ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
  8640. ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
  8641. ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
  8642. };
  8643. if ( !this.handles.hasClass( "ui-state-hover" ) ) {
  8644. this._slide( event, index, normValue );
  8645. }
  8646. this._animateOff = true;
  8647. return true;
  8648. },
  8649. _mouseStart: function() {
  8650. return true;
  8651. },
  8652. _mouseDrag: function( event ) {
  8653. var position = { x: event.pageX, y: event.pageY },
  8654. normValue = this._normValueFromMouse( position );
  8655. this._slide( event, this._handleIndex, normValue );
  8656. return false;
  8657. },
  8658. _mouseStop: function( event ) {
  8659. this.handles.removeClass( "ui-state-active" );
  8660. this._mouseSliding = false;
  8661. this._stop( event, this._handleIndex );
  8662. this._change( event, this._handleIndex );
  8663. this._handleIndex = null;
  8664. this._clickOffset = null;
  8665. this._animateOff = false;
  8666. return false;
  8667. },
  8668. _detectOrientation: function() {
  8669. this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
  8670. },
  8671. _normValueFromMouse: function( position ) {
  8672. var pixelTotal,
  8673. pixelMouse,
  8674. percentMouse,
  8675. valueTotal,
  8676. valueMouse;
  8677. if ( this.orientation === "horizontal" ) {
  8678. pixelTotal = this.elementSize.width;
  8679. pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
  8680. } else {
  8681. pixelTotal = this.elementSize.height;
  8682. pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
  8683. }
  8684. percentMouse = ( pixelMouse / pixelTotal );
  8685. if ( percentMouse > 1 ) {
  8686. percentMouse = 1;
  8687. }
  8688. if ( percentMouse < 0 ) {
  8689. percentMouse = 0;
  8690. }
  8691. if ( this.orientation === "vertical" ) {
  8692. percentMouse = 1 - percentMouse;
  8693. }
  8694. valueTotal = this._valueMax() - this._valueMin();
  8695. valueMouse = this._valueMin() + percentMouse * valueTotal;
  8696. return this._trimAlignValue( valueMouse );
  8697. },
  8698. _start: function( event, index ) {
  8699. var uiHash = {
  8700. handle: this.handles[ index ],
  8701. value: this.value()
  8702. };
  8703. if ( this.options.values && this.options.values.length ) {
  8704. uiHash.value = this.values( index );
  8705. uiHash.values = this.values();
  8706. }
  8707. return this._trigger( "start", event, uiHash );
  8708. },
  8709. _slide: function( event, index, newVal ) {
  8710. var otherVal,
  8711. newValues,
  8712. allowed;
  8713. if ( this.options.values && this.options.values.length ) {
  8714. otherVal = this.values( index ? 0 : 1 );
  8715. if ( ( this.options.values.length === 2 && this.options.range === true ) &&
  8716. ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
  8717. ) {
  8718. newVal = otherVal;
  8719. }
  8720. if ( newVal !== this.values( index ) ) {
  8721. newValues = this.values();
  8722. newValues[ index ] = newVal;
  8723. // A slide can be canceled by returning false from the slide callback
  8724. allowed = this._trigger( "slide", event, {
  8725. handle: this.handles[ index ],
  8726. value: newVal,
  8727. values: newValues
  8728. } );
  8729. otherVal = this.values( index ? 0 : 1 );
  8730. if ( allowed !== false ) {
  8731. this.values( index, newVal, true );
  8732. }
  8733. }
  8734. } else {
  8735. if ( newVal !== this.value() ) {
  8736. // A slide can be canceled by returning false from the slide callback
  8737. allowed = this._trigger( "slide", event, {
  8738. handle: this.handles[ index ],
  8739. value: newVal
  8740. } );
  8741. if ( allowed !== false ) {
  8742. this.value( newVal );
  8743. }
  8744. }
  8745. }
  8746. },
  8747. _stop: function( event, index ) {
  8748. var uiHash = {
  8749. handle: this.handles[ index ],
  8750. value: this.value()
  8751. };
  8752. if ( this.options.values && this.options.values.length ) {
  8753. uiHash.value = this.values( index );
  8754. uiHash.values = this.values();
  8755. }
  8756. this._trigger( "stop", event, uiHash );
  8757. },
  8758. _change: function( event, index ) {
  8759. if ( !this._keySliding && !this._mouseSliding ) {
  8760. var uiHash = {
  8761. handle: this.handles[ index ],
  8762. value: this.value()
  8763. };
  8764. if ( this.options.values && this.options.values.length ) {
  8765. uiHash.value = this.values( index );
  8766. uiHash.values = this.values();
  8767. }
  8768. this._trigger( "change", event, uiHash );
  8769. }
  8770. },
  8771. value: function( newValue ) {
  8772. if ( arguments.length ) {
  8773. this.options.value = this._trimAlignValue( newValue );
  8774. this._refreshValue();
  8775. this._change( null, 0 );
  8776. return;
  8777. }
  8778. return this._value();
  8779. },
  8780. values: function( index, newValue ) {
  8781. var vals,
  8782. newValues,
  8783. i;
  8784. if ( arguments.length > 1 ) {
  8785. this.options.values[ index ] = this._trimAlignValue( newValue );
  8786. this._refreshValue();
  8787. this._change( null, index );
  8788. return;
  8789. }
  8790. if ( arguments.length ) {
  8791. if ( $.isArray( arguments[ 0 ] ) ) {
  8792. vals = this.options.values;
  8793. newValues = arguments[ 0 ];
  8794. for ( i = 0; i < vals.length; i += 1 ) {
  8795. vals[ i ] = this._trimAlignValue( newValues[ i ] );
  8796. this._change( null, i );
  8797. }
  8798. this._refreshValue();
  8799. } else {
  8800. if ( this.options.values && this.options.values.length ) {
  8801. return this._values( index );
  8802. } else {
  8803. return this.value();
  8804. }
  8805. }
  8806. } else {
  8807. return this._values();
  8808. }
  8809. },
  8810. _setOption: function( key, value ) {
  8811. var i,
  8812. valsLength = 0;
  8813. if ( $.isArray( this.options.values ) ) {
  8814. valsLength = this.options.values.length;
  8815. }
  8816. $.Widget.prototype._setOption.apply( this, arguments );
  8817. switch ( key ) {
  8818. case "disabled":
  8819. if ( value ) {
  8820. this.handles.filter( ".ui-state-focus" ).blur();
  8821. this.handles.removeClass( "ui-state-hover" );
  8822. this.handles.prop( "disabled", true );
  8823. this.element.addClass( "ui-disabled" );
  8824. } else {
  8825. this.handles.prop( "disabled", false );
  8826. this.element.removeClass( "ui-disabled" );
  8827. }
  8828. break;
  8829. case "orientation":
  8830. this._detectOrientation();
  8831. this.element
  8832. .removeClass( "ui-slider-horizontal ui-slider-vertical" )
  8833. .addClass( "ui-slider-" + this.orientation );
  8834. this._refreshValue();
  8835. break;
  8836. case "value":
  8837. this._animateOff = true;
  8838. this._refreshValue();
  8839. this._change( null, 0 );
  8840. this._animateOff = false;
  8841. break;
  8842. case "values":
  8843. this._animateOff = true;
  8844. this._refreshValue();
  8845. for ( i = 0; i < valsLength; i += 1 ) {
  8846. this._change( null, i );
  8847. }
  8848. this._animateOff = false;
  8849. break;
  8850. case "min":
  8851. case "max":
  8852. this._animateOff = true;
  8853. this._refreshValue();
  8854. this._animateOff = false;
  8855. break;
  8856. }
  8857. },
  8858. //internal value getter
  8859. // _value() returns value trimmed by min and max, aligned by step
  8860. _value: function() {
  8861. var val = this.options.value;
  8862. val = this._trimAlignValue( val );
  8863. return val;
  8864. },
  8865. //internal values getter
  8866. // _values() returns array of values trimmed by min and max, aligned by step
  8867. // _values( index ) returns single value trimmed by min and max, aligned by step
  8868. _values: function( index ) {
  8869. var val,
  8870. vals,
  8871. i;
  8872. if ( arguments.length ) {
  8873. val = this.options.values[ index ];
  8874. val = this._trimAlignValue( val );
  8875. return val;
  8876. } else {
  8877. // .slice() creates a copy of the array
  8878. // this copy gets trimmed by min and max and then returned
  8879. vals = this.options.values.slice();
  8880. for ( i = 0; i < vals.length; i+= 1) {
  8881. vals[ i ] = this._trimAlignValue( vals[ i ] );
  8882. }
  8883. return vals;
  8884. }
  8885. },
  8886. // returns the step-aligned value that val is closest to, between (inclusive) min and max
  8887. _trimAlignValue: function( val ) {
  8888. if ( val <= this._valueMin() ) {
  8889. return this._valueMin();
  8890. }
  8891. if ( val >= this._valueMax() ) {
  8892. return this._valueMax();
  8893. }
  8894. var step = ( this.options.step > 0 ) ? this.options.step : 1,
  8895. valModStep = (val - this._valueMin()) % step,
  8896. alignValue = val - valModStep;
  8897. if ( Math.abs(valModStep) * 2 >= step ) {
  8898. alignValue += ( valModStep > 0 ) ? step : ( -step );
  8899. }
  8900. // Since JavaScript has problems with large floats, round
  8901. // the final value to 5 digits after the decimal point (see #4124)
  8902. return parseFloat( alignValue.toFixed(5) );
  8903. },
  8904. _valueMin: function() {
  8905. return this.options.min;
  8906. },
  8907. _valueMax: function() {
  8908. return this.options.max;
  8909. },
  8910. _refreshValue: function() {
  8911. var lastValPercent, valPercent, value, valueMin, valueMax,
  8912. oRange = this.options.range,
  8913. o = this.options,
  8914. that = this,
  8915. animate = ( !this._animateOff ) ? o.animate : false,
  8916. _set = {};
  8917. if ( this.options.values && this.options.values.length ) {
  8918. this.handles.each(function( i ) {
  8919. valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
  8920. _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
  8921. $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
  8922. if ( that.options.range === true ) {
  8923. if ( that.orientation === "horizontal" ) {
  8924. if ( i === 0 ) {
  8925. that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
  8926. }
  8927. if ( i === 1 ) {
  8928. that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
  8929. }
  8930. } else {
  8931. if ( i === 0 ) {
  8932. that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
  8933. }
  8934. if ( i === 1 ) {
  8935. that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
  8936. }
  8937. }
  8938. }
  8939. lastValPercent = valPercent;
  8940. });
  8941. } else {
  8942. value = this.value();
  8943. valueMin = this._valueMin();
  8944. valueMax = this._valueMax();
  8945. valPercent = ( valueMax !== valueMin ) ?
  8946. ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
  8947. 0;
  8948. _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
  8949. this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
  8950. if ( oRange === "min" && this.orientation === "horizontal" ) {
  8951. this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
  8952. }
  8953. if ( oRange === "max" && this.orientation === "horizontal" ) {
  8954. this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
  8955. }
  8956. if ( oRange === "min" && this.orientation === "vertical" ) {
  8957. this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
  8958. }
  8959. if ( oRange === "max" && this.orientation === "vertical" ) {
  8960. this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
  8961. }
  8962. }
  8963. }
  8964. });
  8965. }(jQuery));
  8966. (function( $ ) {
  8967. function modifier( fn ) {
  8968. return function() {
  8969. var previous = this.element.val();
  8970. fn.apply( this, arguments );
  8971. this._refresh();
  8972. if ( previous !== this.element.val() ) {
  8973. this._trigger( "change" );
  8974. }
  8975. };
  8976. }
  8977. $.widget( "ui.spinner", {
  8978. version: "1.9.1",
  8979. defaultElement: "<input>",
  8980. widgetEventPrefix: "spin",
  8981. options: {
  8982. culture: null,
  8983. icons: {
  8984. down: "ui-icon-triangle-1-s",
  8985. up: "ui-icon-triangle-1-n"
  8986. },
  8987. incremental: true,
  8988. max: null,
  8989. min: null,
  8990. numberFormat: null,
  8991. page: 10,
  8992. step: 1,
  8993. change: null,
  8994. spin: null,
  8995. start: null,
  8996. stop: null
  8997. },
  8998. _create: function() {
  8999. // handle string values that need to be parsed
  9000. this._setOption( "max", this.options.max );
  9001. this._setOption( "min", this.options.min );
  9002. this._setOption( "step", this.options.step );
  9003. // format the value, but don't constrain
  9004. this._value( this.element.val(), true );
  9005. this._draw();
  9006. this._on( this._events );
  9007. this._refresh();
  9008. // turning off autocomplete prevents the browser from remembering the
  9009. // value when navigating through history, so we re-enable autocomplete
  9010. // if the page is unloaded before the widget is destroyed. #7790
  9011. this._on( this.window, {
  9012. beforeunload: function() {
  9013. this.element.removeAttr( "autocomplete" );
  9014. }
  9015. });
  9016. },
  9017. _getCreateOptions: function() {
  9018. var options = {},
  9019. element = this.element;
  9020. $.each( [ "min", "max", "step" ], function( i, option ) {
  9021. var value = element.attr( option );
  9022. if ( value !== undefined && value.length ) {
  9023. options[ option ] = value;
  9024. }
  9025. });
  9026. return options;
  9027. },
  9028. _events: {
  9029. keydown: function( event ) {
  9030. if ( this._start( event ) && this._keydown( event ) ) {
  9031. event.preventDefault();
  9032. }
  9033. },
  9034. keyup: "_stop",
  9035. focus: function() {
  9036. this.previous = this.element.val();
  9037. },
  9038. blur: function( event ) {
  9039. if ( this.cancelBlur ) {
  9040. delete this.cancelBlur;
  9041. return;
  9042. }
  9043. this._refresh();
  9044. if ( this.previous !== this.element.val() ) {
  9045. this._trigger( "change", event );
  9046. }
  9047. },
  9048. mousewheel: function( event, delta ) {
  9049. if ( !delta ) {
  9050. return;
  9051. }
  9052. if ( !this.spinning && !this._start( event ) ) {
  9053. return false;
  9054. }
  9055. this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
  9056. clearTimeout( this.mousewheelTimer );
  9057. this.mousewheelTimer = this._delay(function() {
  9058. if ( this.spinning ) {
  9059. this._stop( event );
  9060. }
  9061. }, 100 );
  9062. event.preventDefault();
  9063. },
  9064. "mousedown .ui-spinner-button": function( event ) {
  9065. var previous;
  9066. // We never want the buttons to have focus; whenever the user is
  9067. // interacting with the spinner, the focus should be on the input.
  9068. // If the input is focused then this.previous is properly set from
  9069. // when the input first received focus. If the input is not focused
  9070. // then we need to set this.previous based on the value before spinning.
  9071. previous = this.element[0] === this.document[0].activeElement ?
  9072. this.previous : this.element.val();
  9073. function checkFocus() {
  9074. var isActive = this.element[0] === this.document[0].activeElement;
  9075. if ( !isActive ) {
  9076. this.element.focus();
  9077. this.previous = previous;
  9078. // support: IE
  9079. // IE sets focus asynchronously, so we need to check if focus
  9080. // moved off of the input because the user clicked on the button.
  9081. this._delay(function() {
  9082. this.previous = previous;
  9083. });
  9084. }
  9085. }
  9086. // ensure focus is on (or stays on) the text field
  9087. event.preventDefault();
  9088. checkFocus.call( this );
  9089. // support: IE
  9090. // IE doesn't prevent moving focus even with event.preventDefault()
  9091. // so we set a flag to know when we should ignore the blur event
  9092. // and check (again) if focus moved off of the input.
  9093. this.cancelBlur = true;
  9094. this._delay(function() {
  9095. delete this.cancelBlur;
  9096. checkFocus.call( this );
  9097. });
  9098. if ( this._start( event ) === false ) {
  9099. return;
  9100. }
  9101. this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
  9102. },
  9103. "mouseup .ui-spinner-button": "_stop",
  9104. "mouseenter .ui-spinner-button": function( event ) {
  9105. // button will add ui-state-active if mouse was down while mouseleave and kept down
  9106. if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
  9107. return;
  9108. }
  9109. if ( this._start( event ) === false ) {
  9110. return false;
  9111. }
  9112. this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
  9113. },
  9114. // TODO: do we really want to consider this a stop?
  9115. // shouldn't we just stop the repeater and wait until mouseup before
  9116. // we trigger the stop event?
  9117. "mouseleave .ui-spinner-button": "_stop"
  9118. },
  9119. _draw: function() {
  9120. var uiSpinner = this.uiSpinner = this.element
  9121. .addClass( "ui-spinner-input" )
  9122. .attr( "autocomplete", "off" )
  9123. .wrap( this._uiSpinnerHtml() )
  9124. .parent()
  9125. // add buttons
  9126. .append( this._buttonHtml() );
  9127. this.element.attr( "role", "spinbutton" );
  9128. // button bindings
  9129. this.buttons = uiSpinner.find( ".ui-spinner-button" )
  9130. .attr( "tabIndex", -1 )
  9131. .button()
  9132. .removeClass( "ui-corner-all" );
  9133. // IE 6 doesn't understand height: 50% for the buttons
  9134. // unless the wrapper has an explicit height
  9135. if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
  9136. uiSpinner.height() > 0 ) {
  9137. uiSpinner.height( uiSpinner.height() );
  9138. }
  9139. // disable spinner if element was already disabled
  9140. if ( this.options.disabled ) {
  9141. this.disable();
  9142. }
  9143. },
  9144. _keydown: function( event ) {
  9145. var options = this.options,
  9146. keyCode = $.ui.keyCode;
  9147. switch ( event.keyCode ) {
  9148. case keyCode.UP:
  9149. this._repeat( null, 1, event );
  9150. return true;
  9151. case keyCode.DOWN:
  9152. this._repeat( null, -1, event );
  9153. return true;
  9154. case keyCode.PAGE_UP:
  9155. this._repeat( null, options.page, event );
  9156. return true;
  9157. case keyCode.PAGE_DOWN:
  9158. this._repeat( null, -options.page, event );
  9159. return true;
  9160. }
  9161. return false;
  9162. },
  9163. _uiSpinnerHtml: function() {
  9164. return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
  9165. },
  9166. _buttonHtml: function() {
  9167. return "" +
  9168. "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
  9169. "<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
  9170. "</a>" +
  9171. "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
  9172. "<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
  9173. "</a>";
  9174. },
  9175. _start: function( event ) {
  9176. if ( !this.spinning && this._trigger( "start", event ) === false ) {
  9177. return false;
  9178. }
  9179. if ( !this.counter ) {
  9180. this.counter = 1;
  9181. }
  9182. this.spinning = true;
  9183. return true;
  9184. },
  9185. _repeat: function( i, steps, event ) {
  9186. i = i || 500;
  9187. clearTimeout( this.timer );
  9188. this.timer = this._delay(function() {
  9189. this._repeat( 40, steps, event );
  9190. }, i );
  9191. this._spin( steps * this.options.step, event );
  9192. },
  9193. _spin: function( step, event ) {
  9194. var value = this.value() || 0;
  9195. if ( !this.counter ) {
  9196. this.counter = 1;
  9197. }
  9198. value = this._adjustValue( value + step * this._increment( this.counter ) );
  9199. if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
  9200. this._value( value );
  9201. this.counter++;
  9202. }
  9203. },
  9204. _increment: function( i ) {
  9205. var incremental = this.options.incremental;
  9206. if ( incremental ) {
  9207. return $.isFunction( incremental ) ?
  9208. incremental( i ) :
  9209. Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );
  9210. }
  9211. return 1;
  9212. },
  9213. _precision: function() {
  9214. var precision = this._precisionOf( this.options.step );
  9215. if ( this.options.min !== null ) {
  9216. precision = Math.max( precision, this._precisionOf( this.options.min ) );
  9217. }
  9218. return precision;
  9219. },
  9220. _precisionOf: function( num ) {
  9221. var str = num.toString(),
  9222. decimal = str.indexOf( "." );
  9223. return decimal === -1 ? 0 : str.length - decimal - 1;
  9224. },
  9225. _adjustValue: function( value ) {
  9226. var base, aboveMin,
  9227. options = this.options;
  9228. // make sure we're at a valid step
  9229. // - find out where we are relative to the base (min or 0)
  9230. base = options.min !== null ? options.min : 0;
  9231. aboveMin = value - base;
  9232. // - round to the nearest step
  9233. aboveMin = Math.round(aboveMin / options.step) * options.step;
  9234. // - rounding is based on 0, so adjust back to our base
  9235. value = base + aboveMin;
  9236. // fix precision from bad JS floating point math
  9237. value = parseFloat( value.toFixed( this._precision() ) );
  9238. // clamp the value
  9239. if ( options.max !== null && value > options.max) {
  9240. return options.max;
  9241. }
  9242. if ( options.min !== null && value < options.min ) {
  9243. return options.min;
  9244. }
  9245. return value;
  9246. },
  9247. _stop: function( event ) {
  9248. if ( !this.spinning ) {
  9249. return;
  9250. }
  9251. clearTimeout( this.timer );
  9252. clearTimeout( this.mousewheelTimer );
  9253. this.counter = 0;
  9254. this.spinning = false;
  9255. this._trigger( "stop", event );
  9256. },
  9257. _setOption: function( key, value ) {
  9258. if ( key === "culture" || key === "numberFormat" ) {
  9259. var prevValue = this._parse( this.element.val() );
  9260. this.options[ key ] = value;
  9261. this.element.val( this._format( prevValue ) );
  9262. return;
  9263. }
  9264. if ( key === "max" || key === "min" || key === "step" ) {
  9265. if ( typeof value === "string" ) {
  9266. value = this._parse( value );
  9267. }
  9268. }
  9269. this._super( key, value );
  9270. if ( key === "disabled" ) {
  9271. if ( value ) {
  9272. this.element.prop( "disabled", true );
  9273. this.buttons.button( "disable" );
  9274. } else {
  9275. this.element.prop( "disabled", false );
  9276. this.buttons.button( "enable" );
  9277. }
  9278. }
  9279. },
  9280. _setOptions: modifier(function( options ) {
  9281. this._super( options );
  9282. this._value( this.element.val() );
  9283. }),
  9284. _parse: function( val ) {
  9285. if ( typeof val === "string" && val !== "" ) {
  9286. val = window.Globalize && this.options.numberFormat ?
  9287. Globalize.parseFloat( val, 10, this.options.culture ) : +val;
  9288. }
  9289. return val === "" || isNaN( val ) ? null : val;
  9290. },
  9291. _format: function( value ) {
  9292. if ( value === "" ) {
  9293. return "";
  9294. }
  9295. return window.Globalize && this.options.numberFormat ?
  9296. Globalize.format( value, this.options.numberFormat, this.options.culture ) :
  9297. value;
  9298. },
  9299. _refresh: function() {
  9300. this.element.attr({
  9301. "aria-valuemin": this.options.min,
  9302. "aria-valuemax": this.options.max,
  9303. // TODO: what should we do with values that can't be parsed?
  9304. "aria-valuenow": this._parse( this.element.val() )
  9305. });
  9306. },
  9307. // update the value without triggering change
  9308. _value: function( value, allowAny ) {
  9309. var parsed;
  9310. if ( value !== "" ) {
  9311. parsed = this._parse( value );
  9312. if ( parsed !== null ) {
  9313. if ( !allowAny ) {
  9314. parsed = this._adjustValue( parsed );
  9315. }
  9316. value = this._format( parsed );
  9317. }
  9318. }
  9319. this.element.val( value );
  9320. this._refresh();
  9321. },
  9322. _destroy: function() {
  9323. this.element
  9324. .removeClass( "ui-spinner-input" )
  9325. .prop( "disabled", false )
  9326. .removeAttr( "autocomplete" )
  9327. .removeAttr( "role" )
  9328. .removeAttr( "aria-valuemin" )
  9329. .removeAttr( "aria-valuemax" )
  9330. .removeAttr( "aria-valuenow" );
  9331. this.uiSpinner.replaceWith( this.element );
  9332. },
  9333. stepUp: modifier(function( steps ) {
  9334. this._stepUp( steps );
  9335. }),
  9336. _stepUp: function( steps ) {
  9337. this._spin( (steps || 1) * this.options.step );
  9338. },
  9339. stepDown: modifier(function( steps ) {
  9340. this._stepDown( steps );
  9341. }),
  9342. _stepDown: function( steps ) {
  9343. this._spin( (steps || 1) * -this.options.step );
  9344. },
  9345. pageUp: modifier(function( pages ) {
  9346. this._stepUp( (pages || 1) * this.options.page );
  9347. }),
  9348. pageDown: modifier(function( pages ) {
  9349. this._stepDown( (pages || 1) * this.options.page );
  9350. }),
  9351. value: function( newVal ) {
  9352. if ( !arguments.length ) {
  9353. return this._parse( this.element.val() );
  9354. }
  9355. modifier( this._value ).call( this, newVal );
  9356. },
  9357. widget: function() {
  9358. return this.uiSpinner;
  9359. }
  9360. });
  9361. }( jQuery ) );
  9362. (function( $, undefined ) {
  9363. var tabId = 0,
  9364. rhash = /#.*$/;
  9365. function getNextTabId() {
  9366. return ++tabId;
  9367. }
  9368. function isLocal( anchor ) {
  9369. return anchor.hash.length > 1 &&
  9370. anchor.href.replace( rhash, "" ) === location.href.replace( rhash, "" );
  9371. }
  9372. $.widget( "ui.tabs", {
  9373. version: "1.9.1",
  9374. delay: 300,
  9375. options: {
  9376. active: null,
  9377. collapsible: false,
  9378. event: "click",
  9379. heightStyle: "content",
  9380. hide: null,
  9381. show: null,
  9382. // callbacks
  9383. activate: null,
  9384. beforeActivate: null,
  9385. beforeLoad: null,
  9386. load: null
  9387. },
  9388. _create: function() {
  9389. var that = this,
  9390. options = this.options,
  9391. active = options.active,
  9392. locationHash = location.hash.substring( 1 );
  9393. this.running = false;
  9394. this.element
  9395. .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
  9396. .toggleClass( "ui-tabs-collapsible", options.collapsible )
  9397. // Prevent users from focusing disabled tabs via click
  9398. .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) {
  9399. if ( $( this ).is( ".ui-state-disabled" ) ) {
  9400. event.preventDefault();
  9401. }
  9402. })
  9403. // support: IE <9
  9404. // Preventing the default action in mousedown doesn't prevent IE
  9405. // from focusing the element, so if the anchor gets focused, blur.
  9406. // We don't have to worry about focusing the previously focused
  9407. // element since clicking on a non-focusable element should focus
  9408. // the body anyway.
  9409. .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
  9410. if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
  9411. this.blur();
  9412. }
  9413. });
  9414. this._processTabs();
  9415. if ( active === null ) {
  9416. // check the fragment identifier in the URL
  9417. if ( locationHash ) {
  9418. this.tabs.each(function( i, tab ) {
  9419. if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
  9420. active = i;
  9421. return false;
  9422. }
  9423. });
  9424. }
  9425. // check for a tab marked active via a class
  9426. if ( active === null ) {
  9427. active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
  9428. }
  9429. // no active tab, set to false
  9430. if ( active === null || active === -1 ) {
  9431. active = this.tabs.length ? 0 : false;
  9432. }
  9433. }
  9434. // handle numbers: negative, out of range
  9435. if ( active !== false ) {
  9436. active = this.tabs.index( this.tabs.eq( active ) );
  9437. if ( active === -1 ) {
  9438. active = options.collapsible ? false : 0;
  9439. }
  9440. }
  9441. options.active = active;
  9442. // don't allow collapsible: false and active: false
  9443. if ( !options.collapsible && options.active === false && this.anchors.length ) {
  9444. options.active = 0;
  9445. }
  9446. // Take disabling tabs via class attribute from HTML
  9447. // into account and update option properly.
  9448. if ( $.isArray( options.disabled ) ) {
  9449. options.disabled = $.unique( options.disabled.concat(
  9450. $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
  9451. return that.tabs.index( li );
  9452. })
  9453. ) ).sort();
  9454. }
  9455. // check for length avoids error when initializing empty list
  9456. if ( this.options.active !== false && this.anchors.length ) {
  9457. this.active = this._findActive( this.options.active );
  9458. } else {
  9459. this.active = $();
  9460. }
  9461. this._refresh();
  9462. if ( this.active.length ) {
  9463. this.load( options.active );
  9464. }
  9465. },
  9466. _getCreateEventData: function() {
  9467. return {
  9468. tab: this.active,
  9469. panel: !this.active.length ? $() : this._getPanelForTab( this.active )
  9470. };
  9471. },
  9472. _tabKeydown: function( event ) {
  9473. var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
  9474. selectedIndex = this.tabs.index( focusedTab ),
  9475. goingForward = true;
  9476. if ( this._handlePageNav( event ) ) {
  9477. return;
  9478. }
  9479. switch ( event.keyCode ) {
  9480. case $.ui.keyCode.RIGHT:
  9481. case $.ui.keyCode.DOWN:
  9482. selectedIndex++;
  9483. break;
  9484. case $.ui.keyCode.UP:
  9485. case $.ui.keyCode.LEFT:
  9486. goingForward = false;
  9487. selectedIndex--;
  9488. break;
  9489. case $.ui.keyCode.END:
  9490. selectedIndex = this.anchors.length - 1;
  9491. break;
  9492. case $.ui.keyCode.HOME:
  9493. selectedIndex = 0;
  9494. break;
  9495. case $.ui.keyCode.SPACE:
  9496. // Activate only, no collapsing
  9497. event.preventDefault();
  9498. clearTimeout( this.activating );
  9499. this._activate( selectedIndex );
  9500. return;
  9501. case $.ui.keyCode.ENTER:
  9502. // Toggle (cancel delayed activation, allow collapsing)
  9503. event.preventDefault();
  9504. clearTimeout( this.activating );
  9505. // Determine if we should collapse or activate
  9506. this._activate( selectedIndex === this.options.active ? false : selectedIndex );
  9507. return;
  9508. default:
  9509. return;
  9510. }
  9511. // Focus the appropriate tab, based on which key was pressed
  9512. event.preventDefault();
  9513. clearTimeout( this.activating );
  9514. selectedIndex = this._focusNextTab( selectedIndex, goingForward );
  9515. // Navigating with control key will prevent automatic activation
  9516. if ( !event.ctrlKey ) {
  9517. // Update aria-selected immediately so that AT think the tab is already selected.
  9518. // Otherwise AT may confuse the user by stating that they need to activate the tab,
  9519. // but the tab will already be activated by the time the announcement finishes.
  9520. focusedTab.attr( "aria-selected", "false" );
  9521. this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
  9522. this.activating = this._delay(function() {
  9523. this.option( "active", selectedIndex );
  9524. }, this.delay );
  9525. }
  9526. },
  9527. _panelKeydown: function( event ) {
  9528. if ( this._handlePageNav( event ) ) {
  9529. return;
  9530. }
  9531. // Ctrl+up moves focus to the current tab
  9532. if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
  9533. event.preventDefault();
  9534. this.active.focus();
  9535. }
  9536. },
  9537. // Alt+page up/down moves focus to the previous/next tab (and activates)
  9538. _handlePageNav: function( event ) {
  9539. if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
  9540. this._activate( this._focusNextTab( this.options.active - 1, false ) );
  9541. return true;
  9542. }
  9543. if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
  9544. this._activate( this._focusNextTab( this.options.active + 1, true ) );
  9545. return true;
  9546. }
  9547. },
  9548. _findNextTab: function( index, goingForward ) {
  9549. var lastTabIndex = this.tabs.length - 1;
  9550. function constrain() {
  9551. if ( index > lastTabIndex ) {
  9552. index = 0;
  9553. }
  9554. if ( index < 0 ) {
  9555. index = lastTabIndex;
  9556. }
  9557. return index;
  9558. }
  9559. while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
  9560. index = goingForward ? index + 1 : index - 1;
  9561. }
  9562. return index;
  9563. },
  9564. _focusNextTab: function( index, goingForward ) {
  9565. index = this._findNextTab( index, goingForward );
  9566. this.tabs.eq( index ).focus();
  9567. return index;
  9568. },
  9569. _setOption: function( key, value ) {
  9570. if ( key === "active" ) {
  9571. // _activate() will handle invalid values and update this.options
  9572. this._activate( value );
  9573. return;
  9574. }
  9575. if ( key === "disabled" ) {
  9576. // don't use the widget factory's disabled handling
  9577. this._setupDisabled( value );
  9578. return;
  9579. }
  9580. this._super( key, value);
  9581. if ( key === "collapsible" ) {
  9582. this.element.toggleClass( "ui-tabs-collapsible", value );
  9583. // Setting collapsible: false while collapsed; open first panel
  9584. if ( !value && this.options.active === false ) {
  9585. this._activate( 0 );
  9586. }
  9587. }
  9588. if ( key === "event" ) {
  9589. this._setupEvents( value );
  9590. }
  9591. if ( key === "heightStyle" ) {
  9592. this._setupHeightStyle( value );
  9593. }
  9594. },
  9595. _tabId: function( tab ) {
  9596. return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId();
  9597. },
  9598. _sanitizeSelector: function( hash ) {
  9599. return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
  9600. },
  9601. refresh: function() {
  9602. var options = this.options,
  9603. lis = this.tablist.children( ":has(a[href])" );
  9604. // get disabled tabs from class attribute from HTML
  9605. // this will get converted to a boolean if needed in _refresh()
  9606. options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
  9607. return lis.index( tab );
  9608. });
  9609. this._processTabs();
  9610. // was collapsed or no tabs
  9611. if ( options.active === false || !this.anchors.length ) {
  9612. options.active = false;
  9613. this.active = $();
  9614. // was active, but active tab is gone
  9615. } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
  9616. // all remaining tabs are disabled
  9617. if ( this.tabs.length === options.disabled.length ) {
  9618. options.active = false;
  9619. this.active = $();
  9620. // activate previous tab
  9621. } else {
  9622. this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
  9623. }
  9624. // was active, active tab still exists
  9625. } else {
  9626. // make sure active index is correct
  9627. options.active = this.tabs.index( this.active );
  9628. }
  9629. this._refresh();
  9630. },
  9631. _refresh: function() {
  9632. this._setupDisabled( this.options.disabled );
  9633. this._setupEvents( this.options.event );
  9634. this._setupHeightStyle( this.options.heightStyle );
  9635. this.tabs.not( this.active ).attr({
  9636. "aria-selected": "false",
  9637. tabIndex: -1
  9638. });
  9639. this.panels.not( this._getPanelForTab( this.active ) )
  9640. .hide()
  9641. .attr({
  9642. "aria-expanded": "false",
  9643. "aria-hidden": "true"
  9644. });
  9645. // Make sure one tab is in the tab order
  9646. if ( !this.active.length ) {
  9647. this.tabs.eq( 0 ).attr( "tabIndex", 0 );
  9648. } else {
  9649. this.active
  9650. .addClass( "ui-tabs-active ui-state-active" )
  9651. .attr({
  9652. "aria-selected": "true",
  9653. tabIndex: 0
  9654. });
  9655. this._getPanelForTab( this.active )
  9656. .show()
  9657. .attr({
  9658. "aria-expanded": "true",
  9659. "aria-hidden": "false"
  9660. });
  9661. }
  9662. },
  9663. _processTabs: function() {
  9664. var that = this;
  9665. this.tablist = this._getList()
  9666. .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
  9667. .attr( "role", "tablist" );
  9668. this.tabs = this.tablist.find( "> li:has(a[href])" )
  9669. .addClass( "ui-state-default ui-corner-top" )
  9670. .attr({
  9671. role: "tab",
  9672. tabIndex: -1
  9673. });
  9674. this.anchors = this.tabs.map(function() {
  9675. return $( "a", this )[ 0 ];
  9676. })
  9677. .addClass( "ui-tabs-anchor" )
  9678. .attr({
  9679. role: "presentation",
  9680. tabIndex: -1
  9681. });
  9682. this.panels = $();
  9683. this.anchors.each(function( i, anchor ) {
  9684. var selector, panel, panelId,
  9685. anchorId = $( anchor ).uniqueId().attr( "id" ),
  9686. tab = $( anchor ).closest( "li" ),
  9687. originalAriaControls = tab.attr( "aria-controls" );
  9688. // inline tab
  9689. if ( isLocal( anchor ) ) {
  9690. selector = anchor.hash;
  9691. panel = that.element.find( that._sanitizeSelector( selector ) );
  9692. // remote tab
  9693. } else {
  9694. panelId = that._tabId( tab );
  9695. selector = "#" + panelId;
  9696. panel = that.element.find( selector );
  9697. if ( !panel.length ) {
  9698. panel = that._createPanel( panelId );
  9699. panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
  9700. }
  9701. panel.attr( "aria-live", "polite" );
  9702. }
  9703. if ( panel.length) {
  9704. that.panels = that.panels.add( panel );
  9705. }
  9706. if ( originalAriaControls ) {
  9707. tab.data( "ui-tabs-aria-controls", originalAriaControls );
  9708. }
  9709. tab.attr({
  9710. "aria-controls": selector.substring( 1 ),
  9711. "aria-labelledby": anchorId
  9712. });
  9713. panel.attr( "aria-labelledby", anchorId );
  9714. });
  9715. this.panels
  9716. .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
  9717. .attr( "role", "tabpanel" );
  9718. },
  9719. // allow overriding how to find the list for rare usage scenarios (#7715)
  9720. _getList: function() {
  9721. return this.element.find( "ol,ul" ).eq( 0 );
  9722. },
  9723. _createPanel: function( id ) {
  9724. return $( "<div>" )
  9725. .attr( "id", id )
  9726. .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
  9727. .data( "ui-tabs-destroy", true );
  9728. },
  9729. _setupDisabled: function( disabled ) {
  9730. if ( $.isArray( disabled ) ) {
  9731. if ( !disabled.length ) {
  9732. disabled = false;
  9733. } else if ( disabled.length === this.anchors.length ) {
  9734. disabled = true;
  9735. }
  9736. }
  9737. // disable tabs
  9738. for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
  9739. if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
  9740. $( li )
  9741. .addClass( "ui-state-disabled" )
  9742. .attr( "aria-disabled", "true" );
  9743. } else {
  9744. $( li )
  9745. .removeClass( "ui-state-disabled" )
  9746. .removeAttr( "aria-disabled" );
  9747. }
  9748. }
  9749. this.options.disabled = disabled;
  9750. },
  9751. _setupEvents: function( event ) {
  9752. var events = {
  9753. click: function( event ) {
  9754. event.preventDefault();
  9755. }
  9756. };
  9757. if ( event ) {
  9758. $.each( event.split(" "), function( index, eventName ) {
  9759. events[ eventName ] = "_eventHandler";
  9760. });
  9761. }
  9762. this._off( this.anchors.add( this.tabs ).add( this.panels ) );
  9763. this._on( this.anchors, events );
  9764. this._on( this.tabs, { keydown: "_tabKeydown" } );
  9765. this._on( this.panels, { keydown: "_panelKeydown" } );
  9766. this._focusable( this.tabs );
  9767. this._hoverable( this.tabs );
  9768. },
  9769. _setupHeightStyle: function( heightStyle ) {
  9770. var maxHeight, overflow,
  9771. parent = this.element.parent();
  9772. if ( heightStyle === "fill" ) {
  9773. // IE 6 treats height like minHeight, so we need to turn off overflow
  9774. // in order to get a reliable height
  9775. // we use the minHeight support test because we assume that only
  9776. // browsers that don't support minHeight will treat height as minHeight
  9777. if ( !$.support.minHeight ) {
  9778. overflow = parent.css( "overflow" );
  9779. parent.css( "overflow", "hidden");
  9780. }
  9781. maxHeight = parent.height();
  9782. this.element.siblings( ":visible" ).each(function() {
  9783. var elem = $( this ),
  9784. position = elem.css( "position" );
  9785. if ( position === "absolute" || position === "fixed" ) {
  9786. return;
  9787. }
  9788. maxHeight -= elem.outerHeight( true );
  9789. });
  9790. if ( overflow ) {
  9791. parent.css( "overflow", overflow );
  9792. }
  9793. this.element.children().not( this.panels ).each(function() {
  9794. maxHeight -= $( this ).outerHeight( true );
  9795. });
  9796. this.panels.each(function() {
  9797. $( this ).height( Math.max( 0, maxHeight -
  9798. $( this ).innerHeight() + $( this ).height() ) );
  9799. })
  9800. .css( "overflow", "auto" );
  9801. } else if ( heightStyle === "auto" ) {
  9802. maxHeight = 0;
  9803. this.panels.each(function() {
  9804. maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
  9805. }).height( maxHeight );
  9806. }
  9807. },
  9808. _eventHandler: function( event ) {
  9809. var options = this.options,
  9810. active = this.active,
  9811. anchor = $( event.currentTarget ),
  9812. tab = anchor.closest( "li" ),
  9813. clickedIsActive = tab[ 0 ] === active[ 0 ],
  9814. collapsing = clickedIsActive && options.collapsible,
  9815. toShow = collapsing ? $() : this._getPanelForTab( tab ),
  9816. toHide = !active.length ? $() : this._getPanelForTab( active ),
  9817. eventData = {
  9818. oldTab: active,
  9819. oldPanel: toHide,
  9820. newTab: collapsing ? $() : tab,
  9821. newPanel: toShow
  9822. };
  9823. event.preventDefault();
  9824. if ( tab.hasClass( "ui-state-disabled" ) ||
  9825. // tab is already loading
  9826. tab.hasClass( "ui-tabs-loading" ) ||
  9827. // can't switch durning an animation
  9828. this.running ||
  9829. // click on active header, but not collapsible
  9830. ( clickedIsActive && !options.collapsible ) ||
  9831. // allow canceling activation
  9832. ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
  9833. return;
  9834. }
  9835. options.active = collapsing ? false : this.tabs.index( tab );
  9836. this.active = clickedIsActive ? $() : tab;
  9837. if ( this.xhr ) {
  9838. this.xhr.abort();
  9839. }
  9840. if ( !toHide.length && !toShow.length ) {
  9841. $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
  9842. }
  9843. if ( toShow.length ) {
  9844. this.load( this.tabs.index( tab ), event );
  9845. }
  9846. this._toggle( event, eventData );
  9847. },
  9848. // handles show/hide for selecting tabs
  9849. _toggle: function( event, eventData ) {
  9850. var that = this,
  9851. toShow = eventData.newPanel,
  9852. toHide = eventData.oldPanel;
  9853. this.running = true;
  9854. function complete() {
  9855. that.running = false;
  9856. that._trigger( "activate", event, eventData );
  9857. }
  9858. function show() {
  9859. eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
  9860. if ( toShow.length && that.options.show ) {
  9861. that._show( toShow, that.options.show, complete );
  9862. } else {
  9863. toShow.show();
  9864. complete();
  9865. }
  9866. }
  9867. // start out by hiding, then showing, then completing
  9868. if ( toHide.length && this.options.hide ) {
  9869. this._hide( toHide, this.options.hide, function() {
  9870. eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
  9871. show();
  9872. });
  9873. } else {
  9874. eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
  9875. toHide.hide();
  9876. show();
  9877. }
  9878. toHide.attr({
  9879. "aria-expanded": "false",
  9880. "aria-hidden": "true"
  9881. });
  9882. eventData.oldTab.attr( "aria-selected", "false" );
  9883. // If we're switching tabs, remove the old tab from the tab order.
  9884. // If we're opening from collapsed state, remove the previous tab from the tab order.
  9885. // If we're collapsing, then keep the collapsing tab in the tab order.
  9886. if ( toShow.length && toHide.length ) {
  9887. eventData.oldTab.attr( "tabIndex", -1 );
  9888. } else if ( toShow.length ) {
  9889. this.tabs.filter(function() {
  9890. return $( this ).attr( "tabIndex" ) === 0;
  9891. })
  9892. .attr( "tabIndex", -1 );
  9893. }
  9894. toShow.attr({
  9895. "aria-expanded": "true",
  9896. "aria-hidden": "false"
  9897. });
  9898. eventData.newTab.attr({
  9899. "aria-selected": "true",
  9900. tabIndex: 0
  9901. });
  9902. },
  9903. _activate: function( index ) {
  9904. var anchor,
  9905. active = this._findActive( index );
  9906. // trying to activate the already active panel
  9907. if ( active[ 0 ] === this.active[ 0 ] ) {
  9908. return;
  9909. }
  9910. // trying to collapse, simulate a click on the current active header
  9911. if ( !active.length ) {
  9912. active = this.active;
  9913. }
  9914. anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
  9915. this._eventHandler({
  9916. target: anchor,
  9917. currentTarget: anchor,
  9918. preventDefault: $.noop
  9919. });
  9920. },
  9921. _findActive: function( index ) {
  9922. return index === false ? $() : this.tabs.eq( index );
  9923. },
  9924. _getIndex: function( index ) {
  9925. // meta-function to give users option to provide a href string instead of a numerical index.
  9926. if ( typeof index === "string" ) {
  9927. index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
  9928. }
  9929. return index;
  9930. },
  9931. _destroy: function() {
  9932. if ( this.xhr ) {
  9933. this.xhr.abort();
  9934. }
  9935. this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
  9936. this.tablist
  9937. .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
  9938. .removeAttr( "role" );
  9939. this.anchors
  9940. .removeClass( "ui-tabs-anchor" )
  9941. .removeAttr( "role" )
  9942. .removeAttr( "tabIndex" )
  9943. .removeData( "href.tabs" )
  9944. .removeData( "load.tabs" )
  9945. .removeUniqueId();
  9946. this.tabs.add( this.panels ).each(function() {
  9947. if ( $.data( this, "ui-tabs-destroy" ) ) {
  9948. $( this ).remove();
  9949. } else {
  9950. $( this )
  9951. .removeClass( "ui-state-default ui-state-active ui-state-disabled " +
  9952. "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
  9953. .removeAttr( "tabIndex" )
  9954. .removeAttr( "aria-live" )
  9955. .removeAttr( "aria-busy" )
  9956. .removeAttr( "aria-selected" )
  9957. .removeAttr( "aria-labelledby" )
  9958. .removeAttr( "aria-hidden" )
  9959. .removeAttr( "aria-expanded" )
  9960. .removeAttr( "role" );
  9961. }
  9962. });
  9963. this.tabs.each(function() {
  9964. var li = $( this ),
  9965. prev = li.data( "ui-tabs-aria-controls" );
  9966. if ( prev ) {
  9967. li.attr( "aria-controls", prev );
  9968. } else {
  9969. li.removeAttr( "aria-controls" );
  9970. }
  9971. });
  9972. if ( this.options.heightStyle !== "content" ) {
  9973. this.panels.css( "height", "" );
  9974. }
  9975. },
  9976. enable: function( index ) {
  9977. var disabled = this.options.disabled;
  9978. if ( disabled === false ) {
  9979. return;
  9980. }
  9981. if ( index === undefined ) {
  9982. disabled = false;
  9983. } else {
  9984. index = this._getIndex( index );
  9985. if ( $.isArray( disabled ) ) {
  9986. disabled = $.map( disabled, function( num ) {
  9987. return num !== index ? num : null;
  9988. });
  9989. } else {
  9990. disabled = $.map( this.tabs, function( li, num ) {
  9991. return num !== index ? num : null;
  9992. });
  9993. }
  9994. }
  9995. this._setupDisabled( disabled );
  9996. },
  9997. disable: function( index ) {
  9998. var disabled = this.options.disabled;
  9999. if ( disabled === true ) {
  10000. return;
  10001. }
  10002. if ( index === undefined ) {
  10003. disabled = true;
  10004. } else {
  10005. index = this._getIndex( index );
  10006. if ( $.inArray( index, disabled ) !== -1 ) {
  10007. return;
  10008. }
  10009. if ( $.isArray( disabled ) ) {
  10010. disabled = $.merge( [ index ], disabled ).sort();
  10011. } else {
  10012. disabled = [ index ];
  10013. }
  10014. }
  10015. this._setupDisabled( disabled );
  10016. },
  10017. load: function( index, event ) {
  10018. index = this._getIndex( index );
  10019. var that = this,
  10020. tab = this.tabs.eq( index ),
  10021. anchor = tab.find( ".ui-tabs-anchor" ),
  10022. panel = this._getPanelForTab( tab ),
  10023. eventData = {
  10024. tab: tab,
  10025. panel: panel
  10026. };
  10027. // not remote
  10028. if ( isLocal( anchor[ 0 ] ) ) {
  10029. return;
  10030. }
  10031. this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
  10032. // support: jQuery <1.8
  10033. // jQuery <1.8 returns false if the request is canceled in beforeSend,
  10034. // but as of 1.8, $.ajax() always returns a jqXHR object.
  10035. if ( this.xhr && this.xhr.statusText !== "canceled" ) {
  10036. tab.addClass( "ui-tabs-loading" );
  10037. panel.attr( "aria-busy", "true" );
  10038. this.xhr
  10039. .success(function( response ) {
  10040. // support: jQuery <1.8
  10041. // http://bugs.jquery.com/ticket/11778
  10042. setTimeout(function() {
  10043. panel.html( response );
  10044. that._trigger( "load", event, eventData );
  10045. }, 1 );
  10046. })
  10047. .complete(function( jqXHR, status ) {
  10048. // support: jQuery <1.8
  10049. // http://bugs.jquery.com/ticket/11778
  10050. setTimeout(function() {
  10051. if ( status === "abort" ) {
  10052. that.panels.stop( false, true );
  10053. }
  10054. tab.removeClass( "ui-tabs-loading" );
  10055. panel.removeAttr( "aria-busy" );
  10056. if ( jqXHR === that.xhr ) {
  10057. delete that.xhr;
  10058. }
  10059. }, 1 );
  10060. });
  10061. }
  10062. },
  10063. // TODO: Remove this function in 1.10 when ajaxOptions is removed
  10064. _ajaxSettings: function( anchor, event, eventData ) {
  10065. var that = this;
  10066. return {
  10067. url: anchor.attr( "href" ),
  10068. beforeSend: function( jqXHR, settings ) {
  10069. return that._trigger( "beforeLoad", event,
  10070. $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) );
  10071. }
  10072. };
  10073. },
  10074. _getPanelForTab: function( tab ) {
  10075. var id = $( tab ).attr( "aria-controls" );
  10076. return this.element.find( this._sanitizeSelector( "#" + id ) );
  10077. }
  10078. });
  10079. // DEPRECATED
  10080. if ( $.uiBackCompat !== false ) {
  10081. // helper method for a lot of the back compat extensions
  10082. $.ui.tabs.prototype._ui = function( tab, panel ) {
  10083. return {
  10084. tab: tab,
  10085. panel: panel,
  10086. index: this.anchors.index( tab )
  10087. };
  10088. };
  10089. // url method
  10090. $.widget( "ui.tabs", $.ui.tabs, {
  10091. url: function( index, url ) {
  10092. this.anchors.eq( index ).attr( "href", url );
  10093. }
  10094. });
  10095. // TODO: Remove _ajaxSettings() method when removing this extension
  10096. // ajaxOptions and cache options
  10097. $.widget( "ui.tabs", $.ui.tabs, {
  10098. options: {
  10099. ajaxOptions: null,
  10100. cache: false
  10101. },
  10102. _create: function() {
  10103. this._super();
  10104. var that = this;
  10105. this._on({ tabsbeforeload: function( event, ui ) {
  10106. // tab is already cached
  10107. if ( $.data( ui.tab[ 0 ], "cache.tabs" ) ) {
  10108. event.preventDefault();
  10109. return;
  10110. }
  10111. ui.jqXHR.success(function() {
  10112. if ( that.options.cache ) {
  10113. $.data( ui.tab[ 0 ], "cache.tabs", true );
  10114. }
  10115. });
  10116. }});
  10117. },
  10118. _ajaxSettings: function( anchor, event, ui ) {
  10119. var ajaxOptions = this.options.ajaxOptions;
  10120. return $.extend( {}, ajaxOptions, {
  10121. error: function( xhr, status ) {
  10122. try {
  10123. // Passing index avoid a race condition when this method is
  10124. // called after the user has selected another tab.
  10125. // Pass the anchor that initiated this request allows
  10126. // loadError to manipulate the tab content panel via $(a.hash)
  10127. ajaxOptions.error(
  10128. xhr, status, ui.tab.closest( "li" ).index(), ui.tab[ 0 ] );
  10129. }
  10130. catch ( error ) {}
  10131. }
  10132. }, this._superApply( arguments ) );
  10133. },
  10134. _setOption: function( key, value ) {
  10135. // reset cache if switching from cached to not cached
  10136. if ( key === "cache" && value === false ) {
  10137. this.anchors.removeData( "cache.tabs" );
  10138. }
  10139. this._super( key, value );
  10140. },
  10141. _destroy: function() {
  10142. this.anchors.removeData( "cache.tabs" );
  10143. this._super();
  10144. },
  10145. url: function( index ){
  10146. this.anchors.eq( index ).removeData( "cache.tabs" );
  10147. this._superApply( arguments );
  10148. }
  10149. });
  10150. // abort method
  10151. $.widget( "ui.tabs", $.ui.tabs, {
  10152. abort: function() {
  10153. if ( this.xhr ) {
  10154. this.xhr.abort();
  10155. }
  10156. }
  10157. });
  10158. // spinner
  10159. $.widget( "ui.tabs", $.ui.tabs, {
  10160. options: {
  10161. spinner: "<em>Loading&#8230;</em>"
  10162. },
  10163. _create: function() {
  10164. this._super();
  10165. this._on({
  10166. tabsbeforeload: function( event, ui ) {
  10167. // Don't react to nested tabs or tabs that don't use a spinner
  10168. if ( event.target !== this.element[ 0 ] ||
  10169. !this.options.spinner ) {
  10170. return;
  10171. }
  10172. var span = ui.tab.find( "span" ),
  10173. html = span.html();
  10174. span.html( this.options.spinner );
  10175. ui.jqXHR.complete(function() {
  10176. span.html( html );
  10177. });
  10178. }
  10179. });
  10180. }
  10181. });
  10182. // enable/disable events
  10183. $.widget( "ui.tabs", $.ui.tabs, {
  10184. options: {
  10185. enable: null,
  10186. disable: null
  10187. },
  10188. enable: function( index ) {
  10189. var options = this.options,
  10190. trigger;
  10191. if ( index && options.disabled === true ||
  10192. ( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) !== -1 ) ) {
  10193. trigger = true;
  10194. }
  10195. this._superApply( arguments );
  10196. if ( trigger ) {
  10197. this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
  10198. }
  10199. },
  10200. disable: function( index ) {
  10201. var options = this.options,
  10202. trigger;
  10203. if ( index && options.disabled === false ||
  10204. ( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) === -1 ) ) {
  10205. trigger = true;
  10206. }
  10207. this._superApply( arguments );
  10208. if ( trigger ) {
  10209. this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
  10210. }
  10211. }
  10212. });
  10213. // add/remove methods and events
  10214. $.widget( "ui.tabs", $.ui.tabs, {
  10215. options: {
  10216. add: null,
  10217. remove: null,
  10218. tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>"
  10219. },
  10220. add: function( url, label, index ) {
  10221. if ( index === undefined ) {
  10222. index = this.anchors.length;
  10223. }
  10224. var doInsertAfter, panel,
  10225. options = this.options,
  10226. li = $( options.tabTemplate
  10227. .replace( /#\{href\}/g, url )
  10228. .replace( /#\{label\}/g, label ) ),
  10229. id = !url.indexOf( "#" ) ?
  10230. url.replace( "#", "" ) :
  10231. this._tabId( li );
  10232. li.addClass( "ui-state-default ui-corner-top" ).data( "ui-tabs-destroy", true );
  10233. li.attr( "aria-controls", id );
  10234. doInsertAfter = index >= this.tabs.length;
  10235. // try to find an existing element before creating a new one
  10236. panel = this.element.find( "#" + id );
  10237. if ( !panel.length ) {
  10238. panel = this._createPanel( id );
  10239. if ( doInsertAfter ) {
  10240. if ( index > 0 ) {
  10241. panel.insertAfter( this.panels.eq( -1 ) );
  10242. } else {
  10243. panel.appendTo( this.element );
  10244. }
  10245. } else {
  10246. panel.insertBefore( this.panels[ index ] );
  10247. }
  10248. }
  10249. panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ).hide();
  10250. if ( doInsertAfter ) {
  10251. li.appendTo( this.tablist );
  10252. } else {
  10253. li.insertBefore( this.tabs[ index ] );
  10254. }
  10255. options.disabled = $.map( options.disabled, function( n ) {
  10256. return n >= index ? ++n : n;
  10257. });
  10258. this.refresh();
  10259. if ( this.tabs.length === 1 && options.active === false ) {
  10260. this.option( "active", 0 );
  10261. }
  10262. this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
  10263. return this;
  10264. },
  10265. remove: function( index ) {
  10266. index = this._getIndex( index );
  10267. var options = this.options,
  10268. tab = this.tabs.eq( index ).remove(),
  10269. panel = this._getPanelForTab( tab ).remove();
  10270. // If selected tab was removed focus tab to the right or
  10271. // in case the last tab was removed the tab to the left.
  10272. // We check for more than 2 tabs, because if there are only 2,
  10273. // then when we remove this tab, there will only be one tab left
  10274. // so we don't need to detect which tab to activate.
  10275. if ( tab.hasClass( "ui-tabs-active" ) && this.anchors.length > 2 ) {
  10276. this._activate( index + ( index + 1 < this.anchors.length ? 1 : -1 ) );
  10277. }
  10278. options.disabled = $.map(
  10279. $.grep( options.disabled, function( n ) {
  10280. return n !== index;
  10281. }),
  10282. function( n ) {
  10283. return n >= index ? --n : n;
  10284. });
  10285. this.refresh();
  10286. this._trigger( "remove", null, this._ui( tab.find( "a" )[ 0 ], panel[ 0 ] ) );
  10287. return this;
  10288. }
  10289. });
  10290. // length method
  10291. $.widget( "ui.tabs", $.ui.tabs, {
  10292. length: function() {
  10293. return this.anchors.length;
  10294. }
  10295. });
  10296. // panel ids (idPrefix option + title attribute)
  10297. $.widget( "ui.tabs", $.ui.tabs, {
  10298. options: {
  10299. idPrefix: "ui-tabs-"
  10300. },
  10301. _tabId: function( tab ) {
  10302. var a = tab.is( "li" ) ? tab.find( "a[href]" ) : tab;
  10303. a = a[0];
  10304. return $( a ).closest( "li" ).attr( "aria-controls" ) ||
  10305. a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF\-]/g, "" ) ||
  10306. this.options.idPrefix + getNextTabId();
  10307. }
  10308. });
  10309. // _createPanel method
  10310. $.widget( "ui.tabs", $.ui.tabs, {
  10311. options: {
  10312. panelTemplate: "<div></div>"
  10313. },
  10314. _createPanel: function( id ) {
  10315. return $( this.options.panelTemplate )
  10316. .attr( "id", id )
  10317. .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
  10318. .data( "ui-tabs-destroy", true );
  10319. }
  10320. });
  10321. // selected option
  10322. $.widget( "ui.tabs", $.ui.tabs, {
  10323. _create: function() {
  10324. var options = this.options;
  10325. if ( options.active === null && options.selected !== undefined ) {
  10326. options.active = options.selected === -1 ? false : options.selected;
  10327. }
  10328. this._super();
  10329. options.selected = options.active;
  10330. if ( options.selected === false ) {
  10331. options.selected = -1;
  10332. }
  10333. },
  10334. _setOption: function( key, value ) {
  10335. if ( key !== "selected" ) {
  10336. return this._super( key, value );
  10337. }
  10338. var options = this.options;
  10339. this._super( "active", value === -1 ? false : value );
  10340. options.selected = options.active;
  10341. if ( options.selected === false ) {
  10342. options.selected = -1;
  10343. }
  10344. },
  10345. _eventHandler: function() {
  10346. this._superApply( arguments );
  10347. this.options.selected = this.options.active;
  10348. if ( this.options.selected === false ) {
  10349. this.options.selected = -1;
  10350. }
  10351. }
  10352. });
  10353. // show and select event
  10354. $.widget( "ui.tabs", $.ui.tabs, {
  10355. options: {
  10356. show: null,
  10357. select: null
  10358. },
  10359. _create: function() {
  10360. this._super();
  10361. if ( this.options.active !== false ) {
  10362. this._trigger( "show", null, this._ui(
  10363. this.active.find( ".ui-tabs-anchor" )[ 0 ],
  10364. this._getPanelForTab( this.active )[ 0 ] ) );
  10365. }
  10366. },
  10367. _trigger: function( type, event, data ) {
  10368. var ret = this._superApply( arguments );
  10369. if ( !ret ) {
  10370. return false;
  10371. }
  10372. if ( type === "beforeActivate" && data.newTab.length ) {
  10373. ret = this._super( "select", event, {
  10374. tab: data.newTab.find( ".ui-tabs-anchor" )[ 0],
  10375. panel: data.newPanel[ 0 ],
  10376. index: data.newTab.closest( "li" ).index()
  10377. });
  10378. } else if ( type === "activate" && data.newTab.length ) {
  10379. ret = this._super( "show", event, {
  10380. tab: data.newTab.find( ".ui-tabs-anchor" )[ 0 ],
  10381. panel: data.newPanel[ 0 ],
  10382. index: data.newTab.closest( "li" ).index()
  10383. });
  10384. }
  10385. return ret;
  10386. }
  10387. });
  10388. // select method
  10389. $.widget( "ui.tabs", $.ui.tabs, {
  10390. select: function( index ) {
  10391. index = this._getIndex( index );
  10392. if ( index === -1 ) {
  10393. if ( this.options.collapsible && this.options.selected !== -1 ) {
  10394. index = this.options.selected;
  10395. } else {
  10396. return;
  10397. }
  10398. }
  10399. this.anchors.eq( index ).trigger( this.options.event + this.eventNamespace );
  10400. }
  10401. });
  10402. // cookie option
  10403. (function() {
  10404. var listId = 0;
  10405. $.widget( "ui.tabs", $.ui.tabs, {
  10406. options: {
  10407. cookie: null // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
  10408. },
  10409. _create: function() {
  10410. var options = this.options,
  10411. active;
  10412. if ( options.active == null && options.cookie ) {
  10413. active = parseInt( this._cookie(), 10 );
  10414. if ( active === -1 ) {
  10415. active = false;
  10416. }
  10417. options.active = active;
  10418. }
  10419. this._super();
  10420. },
  10421. _cookie: function( active ) {
  10422. var cookie = [ this.cookie ||
  10423. ( this.cookie = this.options.cookie.name || "ui-tabs-" + (++listId) ) ];
  10424. if ( arguments.length ) {
  10425. cookie.push( active === false ? -1 : active );
  10426. cookie.push( this.options.cookie );
  10427. }
  10428. return $.cookie.apply( null, cookie );
  10429. },
  10430. _refresh: function() {
  10431. this._super();
  10432. if ( this.options.cookie ) {
  10433. this._cookie( this.options.active, this.options.cookie );
  10434. }
  10435. },
  10436. _eventHandler: function() {
  10437. this._superApply( arguments );
  10438. if ( this.options.cookie ) {
  10439. this._cookie( this.options.active, this.options.cookie );
  10440. }
  10441. },
  10442. _destroy: function() {
  10443. this._super();
  10444. if ( this.options.cookie ) {
  10445. this._cookie( null, this.options.cookie );
  10446. }
  10447. }
  10448. });
  10449. })();
  10450. // load event
  10451. $.widget( "ui.tabs", $.ui.tabs, {
  10452. _trigger: function( type, event, data ) {
  10453. var _data = $.extend( {}, data );
  10454. if ( type === "load" ) {
  10455. _data.panel = _data.panel[ 0 ];
  10456. _data.tab = _data.tab.find( ".ui-tabs-anchor" )[ 0 ];
  10457. }
  10458. return this._super( type, event, _data );
  10459. }
  10460. });
  10461. // fx option
  10462. // The new animation options (show, hide) conflict with the old show callback.
  10463. // The old fx option wins over show/hide anyway (always favor back-compat).
  10464. // If a user wants to use the new animation API, they must give up the old API.
  10465. $.widget( "ui.tabs", $.ui.tabs, {
  10466. options: {
  10467. fx: null // e.g. { height: "toggle", opacity: "toggle", duration: 200 }
  10468. },
  10469. _getFx: function() {
  10470. var hide, show,
  10471. fx = this.options.fx;
  10472. if ( fx ) {
  10473. if ( $.isArray( fx ) ) {
  10474. hide = fx[ 0 ];
  10475. show = fx[ 1 ];
  10476. } else {
  10477. hide = show = fx;
  10478. }
  10479. }
  10480. return fx ? { show: show, hide: hide } : null;
  10481. },
  10482. _toggle: function( event, eventData ) {
  10483. var that = this,
  10484. toShow = eventData.newPanel,
  10485. toHide = eventData.oldPanel,
  10486. fx = this._getFx();
  10487. if ( !fx ) {
  10488. return this._super( event, eventData );
  10489. }
  10490. that.running = true;
  10491. function complete() {
  10492. that.running = false;
  10493. that._trigger( "activate", event, eventData );
  10494. }
  10495. function show() {
  10496. eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
  10497. if ( toShow.length && fx.show ) {
  10498. toShow
  10499. .animate( fx.show, fx.show.duration, function() {
  10500. complete();
  10501. });
  10502. } else {
  10503. toShow.show();
  10504. complete();
  10505. }
  10506. }
  10507. // start out by hiding, then showing, then completing
  10508. if ( toHide.length && fx.hide ) {
  10509. toHide.animate( fx.hide, fx.hide.duration, function() {
  10510. eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
  10511. show();
  10512. });
  10513. } else {
  10514. eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
  10515. toHide.hide();
  10516. show();
  10517. }
  10518. }
  10519. });
  10520. }
  10521. })( jQuery );
  10522. (function( $ ) {
  10523. var increments = 0;
  10524. function addDescribedBy( elem, id ) {
  10525. var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
  10526. describedby.push( id );
  10527. elem
  10528. .data( "ui-tooltip-id", id )
  10529. .attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
  10530. }
  10531. function removeDescribedBy( elem ) {
  10532. var id = elem.data( "ui-tooltip-id" ),
  10533. describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
  10534. index = $.inArray( id, describedby );
  10535. if ( index !== -1 ) {
  10536. describedby.splice( index, 1 );
  10537. }
  10538. elem.removeData( "ui-tooltip-id" );
  10539. describedby = $.trim( describedby.join( " " ) );
  10540. if ( describedby ) {
  10541. elem.attr( "aria-describedby", describedby );
  10542. } else {
  10543. elem.removeAttr( "aria-describedby" );
  10544. }
  10545. }
  10546. $.widget( "ui.tooltip", {
  10547. version: "1.9.1",
  10548. options: {
  10549. content: function() {
  10550. return $( this ).attr( "title" );
  10551. },
  10552. hide: true,
  10553. // Disabled elements have inconsistent behavior across browsers (#8661)
  10554. items: "[title]:not([disabled])",
  10555. position: {
  10556. my: "left top+15",
  10557. at: "left bottom",
  10558. collision: "flipfit flipfit"
  10559. },
  10560. show: true,
  10561. tooltipClass: null,
  10562. track: false,
  10563. // callbacks
  10564. close: null,
  10565. open: null
  10566. },
  10567. _create: function() {
  10568. this._on({
  10569. mouseover: "open",
  10570. focusin: "open"
  10571. });
  10572. // IDs of generated tooltips, needed for destroy
  10573. this.tooltips = {};
  10574. // IDs of parent tooltips where we removed the title attribute
  10575. this.parents = {};
  10576. if ( this.options.disabled ) {
  10577. this._disable();
  10578. }
  10579. },
  10580. _setOption: function( key, value ) {
  10581. var that = this;
  10582. if ( key === "disabled" ) {
  10583. this[ value ? "_disable" : "_enable" ]();
  10584. this.options[ key ] = value;
  10585. // disable element style changes
  10586. return;
  10587. }
  10588. this._super( key, value );
  10589. if ( key === "content" ) {
  10590. $.each( this.tooltips, function( id, element ) {
  10591. that._updateContent( element );
  10592. });
  10593. }
  10594. },
  10595. _disable: function() {
  10596. var that = this;
  10597. // close open tooltips
  10598. $.each( this.tooltips, function( id, element ) {
  10599. var event = $.Event( "blur" );
  10600. event.target = event.currentTarget = element[0];
  10601. that.close( event, true );
  10602. });
  10603. // remove title attributes to prevent native tooltips
  10604. this.element.find( this.options.items ).andSelf().each(function() {
  10605. var element = $( this );
  10606. if ( element.is( "[title]" ) ) {
  10607. element
  10608. .data( "ui-tooltip-title", element.attr( "title" ) )
  10609. .attr( "title", "" );
  10610. }
  10611. });
  10612. },
  10613. _enable: function() {
  10614. // restore title attributes
  10615. this.element.find( this.options.items ).andSelf().each(function() {
  10616. var element = $( this );
  10617. if ( element.data( "ui-tooltip-title" ) ) {
  10618. element.attr( "title", element.data( "ui-tooltip-title" ) );
  10619. }
  10620. });
  10621. },
  10622. open: function( event ) {
  10623. var that = this,
  10624. target = $( event ? event.target : this.element )
  10625. // we need closest here due to mouseover bubbling,
  10626. // but always pointing at the same event target
  10627. .closest( this.options.items );
  10628. // No element to show a tooltip for
  10629. if ( !target.length ) {
  10630. return;
  10631. }
  10632. // If the tooltip is open and we're tracking then reposition the tooltip.
  10633. // This makes sure that a tracking tooltip doesn't obscure a focused element
  10634. // if the user was hovering when the element gained focused.
  10635. if ( this.options.track && target.data( "ui-tooltip-id" ) ) {
  10636. this._find( target ).position( $.extend({
  10637. of: target
  10638. }, this.options.position ) );
  10639. // Stop tracking (#8622)
  10640. this._off( this.document, "mousemove" );
  10641. return;
  10642. }
  10643. if ( target.attr( "title" ) ) {
  10644. target.data( "ui-tooltip-title", target.attr( "title" ) );
  10645. }
  10646. target.data( "tooltip-open", true );
  10647. // kill parent tooltips, custom or native, for hover
  10648. if ( event && event.type === "mouseover" ) {
  10649. target.parents().each(function() {
  10650. var blurEvent;
  10651. if ( $( this ).data( "tooltip-open" ) ) {
  10652. blurEvent = $.Event( "blur" );
  10653. blurEvent.target = blurEvent.currentTarget = this;
  10654. that.close( blurEvent, true );
  10655. }
  10656. if ( this.title ) {
  10657. $( this ).uniqueId();
  10658. that.parents[ this.id ] = {
  10659. element: this,
  10660. title: this.title
  10661. };
  10662. this.title = "";
  10663. }
  10664. });
  10665. }
  10666. this._updateContent( target, event );
  10667. },
  10668. _updateContent: function( target, event ) {
  10669. var content,
  10670. contentOption = this.options.content,
  10671. that = this;
  10672. if ( typeof contentOption === "string" ) {
  10673. return this._open( event, target, contentOption );
  10674. }
  10675. content = contentOption.call( target[0], function( response ) {
  10676. // ignore async response if tooltip was closed already
  10677. if ( !target.data( "tooltip-open" ) ) {
  10678. return;
  10679. }
  10680. // IE may instantly serve a cached response for ajax requests
  10681. // delay this call to _open so the other call to _open runs first
  10682. that._delay(function() {
  10683. this._open( event, target, response );
  10684. });
  10685. });
  10686. if ( content ) {
  10687. this._open( event, target, content );
  10688. }
  10689. },
  10690. _open: function( event, target, content ) {
  10691. var tooltip, events, delayedShow,
  10692. positionOption = $.extend( {}, this.options.position );
  10693. if ( !content ) {
  10694. return;
  10695. }
  10696. // Content can be updated multiple times. If the tooltip already
  10697. // exists, then just update the content and bail.
  10698. tooltip = this._find( target );
  10699. if ( tooltip.length ) {
  10700. tooltip.find( ".ui-tooltip-content" ).html( content );
  10701. return;
  10702. }
  10703. // if we have a title, clear it to prevent the native tooltip
  10704. // we have to check first to avoid defining a title if none exists
  10705. // (we don't want to cause an element to start matching [title])
  10706. //
  10707. // We use removeAttr only for key events, to allow IE to export the correct
  10708. // accessible attributes. For mouse events, set to empty string to avoid
  10709. // native tooltip showing up (happens only when removing inside mouseover).
  10710. if ( target.is( "[title]" ) ) {
  10711. if ( event && event.type === "mouseover" ) {
  10712. target.attr( "title", "" );
  10713. } else {
  10714. target.removeAttr( "title" );
  10715. }
  10716. }
  10717. tooltip = this._tooltip( target );
  10718. addDescribedBy( target, tooltip.attr( "id" ) );
  10719. tooltip.find( ".ui-tooltip-content" ).html( content );
  10720. function position( event ) {
  10721. positionOption.of = event;
  10722. if ( tooltip.is( ":hidden" ) ) {
  10723. return;
  10724. }
  10725. tooltip.position( positionOption );
  10726. }
  10727. if ( this.options.track && event && /^mouse/.test( event.originalEvent.type ) ) {
  10728. this._on( this.document, {
  10729. mousemove: position
  10730. });
  10731. // trigger once to override element-relative positioning
  10732. position( event );
  10733. } else {
  10734. tooltip.position( $.extend({
  10735. of: target
  10736. }, this.options.position ) );
  10737. }
  10738. tooltip.hide();
  10739. this._show( tooltip, this.options.show );
  10740. // Handle tracking tooltips that are shown with a delay (#8644). As soon
  10741. // as the tooltip is visible, position the tooltip using the most recent
  10742. // event.
  10743. if ( this.options.show && this.options.show.delay ) {
  10744. delayedShow = setInterval(function() {
  10745. if ( tooltip.is( ":visible" ) ) {
  10746. position( positionOption.of );
  10747. clearInterval( delayedShow );
  10748. }
  10749. }, $.fx.interval );
  10750. }
  10751. this._trigger( "open", event, { tooltip: tooltip } );
  10752. events = {
  10753. keyup: function( event ) {
  10754. if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
  10755. var fakeEvent = $.Event(event);
  10756. fakeEvent.currentTarget = target[0];
  10757. this.close( fakeEvent, true );
  10758. }
  10759. },
  10760. remove: function() {
  10761. this._removeTooltip( tooltip );
  10762. }
  10763. };
  10764. if ( !event || event.type === "mouseover" ) {
  10765. events.mouseleave = "close";
  10766. }
  10767. if ( !event || event.type === "focusin" ) {
  10768. events.focusout = "close";
  10769. }
  10770. this._on( target, events );
  10771. },
  10772. close: function( event ) {
  10773. var that = this,
  10774. target = $( event ? event.currentTarget : this.element ),
  10775. tooltip = this._find( target );
  10776. // disabling closes the tooltip, so we need to track when we're closing
  10777. // to avoid an infinite loop in case the tooltip becomes disabled on close
  10778. if ( this.closing ) {
  10779. return;
  10780. }
  10781. // only set title if we had one before (see comment in _open())
  10782. if ( target.data( "ui-tooltip-title" ) ) {
  10783. target.attr( "title", target.data( "ui-tooltip-title" ) );
  10784. }
  10785. removeDescribedBy( target );
  10786. tooltip.stop( true );
  10787. this._hide( tooltip, this.options.hide, function() {
  10788. that._removeTooltip( $( this ) );
  10789. });
  10790. target.removeData( "tooltip-open" );
  10791. this._off( target, "mouseleave focusout keyup" );
  10792. // Remove 'remove' binding only on delegated targets
  10793. if ( target[0] !== this.element[0] ) {
  10794. this._off( target, "remove" );
  10795. }
  10796. this._off( this.document, "mousemove" );
  10797. if ( event && event.type === "mouseleave" ) {
  10798. $.each( this.parents, function( id, parent ) {
  10799. parent.element.title = parent.title;
  10800. delete that.parents[ id ];
  10801. });
  10802. }
  10803. this.closing = true;
  10804. this._trigger( "close", event, { tooltip: tooltip } );
  10805. this.closing = false;
  10806. },
  10807. _tooltip: function( element ) {
  10808. var id = "ui-tooltip-" + increments++,
  10809. tooltip = $( "<div>" )
  10810. .attr({
  10811. id: id,
  10812. role: "tooltip"
  10813. })
  10814. .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
  10815. ( this.options.tooltipClass || "" ) );
  10816. $( "<div>" )
  10817. .addClass( "ui-tooltip-content" )
  10818. .appendTo( tooltip );
  10819. tooltip.appendTo( this.document[0].body );
  10820. if ( $.fn.bgiframe ) {
  10821. tooltip.bgiframe();
  10822. }
  10823. this.tooltips[ id ] = element;
  10824. return tooltip;
  10825. },
  10826. _find: function( target ) {
  10827. var id = target.data( "ui-tooltip-id" );
  10828. return id ? $( "#" + id ) : $();
  10829. },
  10830. _removeTooltip: function( tooltip ) {
  10831. tooltip.remove();
  10832. delete this.tooltips[ tooltip.attr( "id" ) ];
  10833. },
  10834. _destroy: function() {
  10835. var that = this;
  10836. // close open tooltips
  10837. $.each( this.tooltips, function( id, element ) {
  10838. // Delegate to close method to handle common cleanup
  10839. var event = $.Event( "blur" );
  10840. event.target = event.currentTarget = element[0];
  10841. that.close( event, true );
  10842. // Remove immediately; destroying an open tooltip doesn't use the
  10843. // hide animation
  10844. $( "#" + id ).remove();
  10845. // Restore the title
  10846. if ( element.data( "ui-tooltip-title" ) ) {
  10847. element.attr( "title", element.data( "ui-tooltip-title" ) );
  10848. element.removeData( "ui-tooltip-title" );
  10849. }
  10850. });
  10851. }
  10852. });
  10853. }( jQuery ) );
  10854. ;(jQuery.effects || (function($, undefined) {
  10855. var backCompat = $.uiBackCompat !== false,
  10856. // prefix used for storing data on .data()
  10857. dataSpace = "ui-effects-";
  10858. $.effects = {
  10859. effect: {}
  10860. };
  10861. /*!
  10862. * jQuery Color Animations v2.0.0
  10863. * http://jquery.com/
  10864. *
  10865. * Copyright 2012 jQuery Foundation and other contributors
  10866. * Released under the MIT license.
  10867. * http://jquery.org/license
  10868. *
  10869. * Date: Mon Aug 13 13:41:02 2012 -0500
  10870. */
  10871. (function( jQuery, undefined ) {
  10872. var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor".split(" "),
  10873. // plusequals test for += 100 -= 100
  10874. rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
  10875. // a set of RE's that can match strings and generate color tuples.
  10876. stringParsers = [{
  10877. re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
  10878. parse: function( execResult ) {
  10879. return [
  10880. execResult[ 1 ],
  10881. execResult[ 2 ],
  10882. execResult[ 3 ],
  10883. execResult[ 4 ]
  10884. ];
  10885. }
  10886. }, {
  10887. re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
  10888. parse: function( execResult ) {
  10889. return [
  10890. execResult[ 1 ] * 2.55,
  10891. execResult[ 2 ] * 2.55,
  10892. execResult[ 3 ] * 2.55,
  10893. execResult[ 4 ]
  10894. ];
  10895. }
  10896. }, {
  10897. // this regex ignores A-F because it's compared against an already lowercased string
  10898. re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
  10899. parse: function( execResult ) {
  10900. return [
  10901. parseInt( execResult[ 1 ], 16 ),
  10902. parseInt( execResult[ 2 ], 16 ),
  10903. parseInt( execResult[ 3 ], 16 )
  10904. ];
  10905. }
  10906. }, {
  10907. // this regex ignores A-F because it's compared against an already lowercased string
  10908. re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
  10909. parse: function( execResult ) {
  10910. return [
  10911. parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
  10912. parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
  10913. parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
  10914. ];
  10915. }
  10916. }, {
  10917. re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
  10918. space: "hsla",
  10919. parse: function( execResult ) {
  10920. return [
  10921. execResult[ 1 ],
  10922. execResult[ 2 ] / 100,
  10923. execResult[ 3 ] / 100,
  10924. execResult[ 4 ]
  10925. ];
  10926. }
  10927. }],
  10928. // jQuery.Color( )
  10929. color = jQuery.Color = function( color, green, blue, alpha ) {
  10930. return new jQuery.Color.fn.parse( color, green, blue, alpha );
  10931. },
  10932. spaces = {
  10933. rgba: {
  10934. props: {
  10935. red: {
  10936. idx: 0,
  10937. type: "byte"
  10938. },
  10939. green: {
  10940. idx: 1,
  10941. type: "byte"
  10942. },
  10943. blue: {
  10944. idx: 2,
  10945. type: "byte"
  10946. }
  10947. }
  10948. },
  10949. hsla: {
  10950. props: {
  10951. hue: {
  10952. idx: 0,
  10953. type: "degrees"
  10954. },
  10955. saturation: {
  10956. idx: 1,
  10957. type: "percent"
  10958. },
  10959. lightness: {
  10960. idx: 2,
  10961. type: "percent"
  10962. }
  10963. }
  10964. }
  10965. },
  10966. propTypes = {
  10967. "byte": {
  10968. floor: true,
  10969. max: 255
  10970. },
  10971. "percent": {
  10972. max: 1
  10973. },
  10974. "degrees": {
  10975. mod: 360,
  10976. floor: true
  10977. }
  10978. },
  10979. support = color.support = {},
  10980. // element for support tests
  10981. supportElem = jQuery( "<p>" )[ 0 ],
  10982. // colors = jQuery.Color.names
  10983. colors,
  10984. // local aliases of functions called often
  10985. each = jQuery.each;
  10986. // determine rgba support immediately
  10987. supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
  10988. support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
  10989. // define cache name and alpha properties
  10990. // for rgba and hsla spaces
  10991. each( spaces, function( spaceName, space ) {
  10992. space.cache = "_" + spaceName;
  10993. space.props.alpha = {
  10994. idx: 3,
  10995. type: "percent",
  10996. def: 1
  10997. };
  10998. });
  10999. function clamp( value, prop, allowEmpty ) {
  11000. var type = propTypes[ prop.type ] || {};
  11001. if ( value == null ) {
  11002. return (allowEmpty || !prop.def) ? null : prop.def;
  11003. }
  11004. // ~~ is an short way of doing floor for positive numbers
  11005. value = type.floor ? ~~value : parseFloat( value );
  11006. // IE will pass in empty strings as value for alpha,
  11007. // which will hit this case
  11008. if ( isNaN( value ) ) {
  11009. return prop.def;
  11010. }
  11011. if ( type.mod ) {
  11012. // we add mod before modding to make sure that negatives values
  11013. // get converted properly: -10 -> 350
  11014. return (value + type.mod) % type.mod;
  11015. }
  11016. // for now all property types without mod have min and max
  11017. return 0 > value ? 0 : type.max < value ? type.max : value;
  11018. }
  11019. function stringParse( string ) {
  11020. var inst = color(),
  11021. rgba = inst._rgba = [];
  11022. string = string.toLowerCase();
  11023. each( stringParsers, function( i, parser ) {
  11024. var parsed,
  11025. match = parser.re.exec( string ),
  11026. values = match && parser.parse( match ),
  11027. spaceName = parser.space || "rgba";
  11028. if ( values ) {
  11029. parsed = inst[ spaceName ]( values );
  11030. // if this was an rgba parse the assignment might happen twice
  11031. // oh well....
  11032. inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
  11033. rgba = inst._rgba = parsed._rgba;
  11034. // exit each( stringParsers ) here because we matched
  11035. return false;
  11036. }
  11037. });
  11038. // Found a stringParser that handled it
  11039. if ( rgba.length ) {
  11040. // if this came from a parsed string, force "transparent" when alpha is 0
  11041. // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
  11042. if ( rgba.join() === "0,0,0,0" ) {
  11043. jQuery.extend( rgba, colors.transparent );
  11044. }
  11045. return inst;
  11046. }
  11047. // named colors
  11048. return colors[ string ];
  11049. }
  11050. color.fn = jQuery.extend( color.prototype, {
  11051. parse: function( red, green, blue, alpha ) {
  11052. if ( red === undefined ) {
  11053. this._rgba = [ null, null, null, null ];
  11054. return this;
  11055. }
  11056. if ( red.jquery || red.nodeType ) {
  11057. red = jQuery( red ).css( green );
  11058. green = undefined;
  11059. }
  11060. var inst = this,
  11061. type = jQuery.type( red ),
  11062. rgba = this._rgba = [];
  11063. // more than 1 argument specified - assume ( red, green, blue, alpha )
  11064. if ( green !== undefined ) {
  11065. red = [ red, green, blue, alpha ];
  11066. type = "array";
  11067. }
  11068. if ( type === "string" ) {
  11069. return this.parse( stringParse( red ) || colors._default );
  11070. }
  11071. if ( type === "array" ) {
  11072. each( spaces.rgba.props, function( key, prop ) {
  11073. rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
  11074. });
  11075. return this;
  11076. }
  11077. if ( type === "object" ) {
  11078. if ( red instanceof color ) {
  11079. each( spaces, function( spaceName, space ) {
  11080. if ( red[ space.cache ] ) {
  11081. inst[ space.cache ] = red[ space.cache ].slice();
  11082. }
  11083. });
  11084. } else {
  11085. each( spaces, function( spaceName, space ) {
  11086. var cache = space.cache;
  11087. each( space.props, function( key, prop ) {
  11088. // if the cache doesn't exist, and we know how to convert
  11089. if ( !inst[ cache ] && space.to ) {
  11090. // if the value was null, we don't need to copy it
  11091. // if the key was alpha, we don't need to copy it either
  11092. if ( key === "alpha" || red[ key ] == null ) {
  11093. return;
  11094. }
  11095. inst[ cache ] = space.to( inst._rgba );
  11096. }
  11097. // this is the only case where we allow nulls for ALL properties.
  11098. // call clamp with alwaysAllowEmpty
  11099. inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
  11100. });
  11101. // everything defined but alpha?
  11102. if ( inst[ cache ] && $.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
  11103. // use the default of 1
  11104. inst[ cache ][ 3 ] = 1;
  11105. if ( space.from ) {
  11106. inst._rgba = space.from( inst[ cache ] );
  11107. }
  11108. }
  11109. });
  11110. }
  11111. return this;
  11112. }
  11113. },
  11114. is: function( compare ) {
  11115. var is = color( compare ),
  11116. same = true,
  11117. inst = this;
  11118. each( spaces, function( _, space ) {
  11119. var localCache,
  11120. isCache = is[ space.cache ];
  11121. if (isCache) {
  11122. localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
  11123. each( space.props, function( _, prop ) {
  11124. if ( isCache[ prop.idx ] != null ) {
  11125. same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
  11126. return same;
  11127. }
  11128. });
  11129. }
  11130. return same;
  11131. });
  11132. return same;
  11133. },
  11134. _space: function() {
  11135. var used = [],
  11136. inst = this;
  11137. each( spaces, function( spaceName, space ) {
  11138. if ( inst[ space.cache ] ) {
  11139. used.push( spaceName );
  11140. }
  11141. });
  11142. return used.pop();
  11143. },
  11144. transition: function( other, distance ) {
  11145. var end = color( other ),
  11146. spaceName = end._space(),
  11147. space = spaces[ spaceName ],
  11148. startColor = this.alpha() === 0 ? color( "transparent" ) : this,
  11149. start = startColor[ space.cache ] || space.to( startColor._rgba ),
  11150. result = start.slice();
  11151. end = end[ space.cache ];
  11152. each( space.props, function( key, prop ) {
  11153. var index = prop.idx,
  11154. startValue = start[ index ],
  11155. endValue = end[ index ],
  11156. type = propTypes[ prop.type ] || {};
  11157. // if null, don't override start value
  11158. if ( endValue === null ) {
  11159. return;
  11160. }
  11161. // if null - use end
  11162. if ( startValue === null ) {
  11163. result[ index ] = endValue;
  11164. } else {
  11165. if ( type.mod ) {
  11166. if ( endValue - startValue > type.mod / 2 ) {
  11167. startValue += type.mod;
  11168. } else if ( startValue - endValue > type.mod / 2 ) {
  11169. startValue -= type.mod;
  11170. }
  11171. }
  11172. result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
  11173. }
  11174. });
  11175. return this[ spaceName ]( result );
  11176. },
  11177. blend: function( opaque ) {
  11178. // if we are already opaque - return ourself
  11179. if ( this._rgba[ 3 ] === 1 ) {
  11180. return this;
  11181. }
  11182. var rgb = this._rgba.slice(),
  11183. a = rgb.pop(),
  11184. blend = color( opaque )._rgba;
  11185. return color( jQuery.map( rgb, function( v, i ) {
  11186. return ( 1 - a ) * blend[ i ] + a * v;
  11187. }));
  11188. },
  11189. toRgbaString: function() {
  11190. var prefix = "rgba(",
  11191. rgba = jQuery.map( this._rgba, function( v, i ) {
  11192. return v == null ? ( i > 2 ? 1 : 0 ) : v;
  11193. });
  11194. if ( rgba[ 3 ] === 1 ) {
  11195. rgba.pop();
  11196. prefix = "rgb(";
  11197. }
  11198. return prefix + rgba.join() + ")";
  11199. },
  11200. toHslaString: function() {
  11201. var prefix = "hsla(",
  11202. hsla = jQuery.map( this.hsla(), function( v, i ) {
  11203. if ( v == null ) {
  11204. v = i > 2 ? 1 : 0;
  11205. }
  11206. // catch 1 and 2
  11207. if ( i && i < 3 ) {
  11208. v = Math.round( v * 100 ) + "%";
  11209. }
  11210. return v;
  11211. });
  11212. if ( hsla[ 3 ] === 1 ) {
  11213. hsla.pop();
  11214. prefix = "hsl(";
  11215. }
  11216. return prefix + hsla.join() + ")";
  11217. },
  11218. toHexString: function( includeAlpha ) {
  11219. var rgba = this._rgba.slice(),
  11220. alpha = rgba.pop();
  11221. if ( includeAlpha ) {
  11222. rgba.push( ~~( alpha * 255 ) );
  11223. }
  11224. return "#" + jQuery.map( rgba, function( v ) {
  11225. // default to 0 when nulls exist
  11226. v = ( v || 0 ).toString( 16 );
  11227. return v.length === 1 ? "0" + v : v;
  11228. }).join("");
  11229. },
  11230. toString: function() {
  11231. return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
  11232. }
  11233. });
  11234. color.fn.parse.prototype = color.fn;
  11235. // hsla conversions adapted from:
  11236. // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
  11237. function hue2rgb( p, q, h ) {
  11238. h = ( h + 1 ) % 1;
  11239. if ( h * 6 < 1 ) {
  11240. return p + (q - p) * h * 6;
  11241. }
  11242. if ( h * 2 < 1) {
  11243. return q;
  11244. }
  11245. if ( h * 3 < 2 ) {
  11246. return p + (q - p) * ((2/3) - h) * 6;
  11247. }
  11248. return p;
  11249. }
  11250. spaces.hsla.to = function ( rgba ) {
  11251. if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
  11252. return [ null, null, null, rgba[ 3 ] ];
  11253. }
  11254. var r = rgba[ 0 ] / 255,
  11255. g = rgba[ 1 ] / 255,
  11256. b = rgba[ 2 ] / 255,
  11257. a = rgba[ 3 ],
  11258. max = Math.max( r, g, b ),
  11259. min = Math.min( r, g, b ),
  11260. diff = max - min,
  11261. add = max + min,
  11262. l = add * 0.5,
  11263. h, s;
  11264. if ( min === max ) {
  11265. h = 0;
  11266. } else if ( r === max ) {
  11267. h = ( 60 * ( g - b ) / diff ) + 360;
  11268. } else if ( g === max ) {
  11269. h = ( 60 * ( b - r ) / diff ) + 120;
  11270. } else {
  11271. h = ( 60 * ( r - g ) / diff ) + 240;
  11272. }
  11273. if ( l === 0 || l === 1 ) {
  11274. s = l;
  11275. } else if ( l <= 0.5 ) {
  11276. s = diff / add;
  11277. } else {
  11278. s = diff / ( 2 - add );
  11279. }
  11280. return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
  11281. };
  11282. spaces.hsla.from = function ( hsla ) {
  11283. if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
  11284. return [ null, null, null, hsla[ 3 ] ];
  11285. }
  11286. var h = hsla[ 0 ] / 360,
  11287. s = hsla[ 1 ],
  11288. l = hsla[ 2 ],
  11289. a = hsla[ 3 ],
  11290. q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
  11291. p = 2 * l - q;
  11292. return [
  11293. Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
  11294. Math.round( hue2rgb( p, q, h ) * 255 ),
  11295. Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
  11296. a
  11297. ];
  11298. };
  11299. each( spaces, function( spaceName, space ) {
  11300. var props = space.props,
  11301. cache = space.cache,
  11302. to = space.to,
  11303. from = space.from;
  11304. // makes rgba() and hsla()
  11305. color.fn[ spaceName ] = function( value ) {
  11306. // generate a cache for this space if it doesn't exist
  11307. if ( to && !this[ cache ] ) {
  11308. this[ cache ] = to( this._rgba );
  11309. }
  11310. if ( value === undefined ) {
  11311. return this[ cache ].slice();
  11312. }
  11313. var ret,
  11314. type = jQuery.type( value ),
  11315. arr = ( type === "array" || type === "object" ) ? value : arguments,
  11316. local = this[ cache ].slice();
  11317. each( props, function( key, prop ) {
  11318. var val = arr[ type === "object" ? key : prop.idx ];
  11319. if ( val == null ) {
  11320. val = local[ prop.idx ];
  11321. }
  11322. local[ prop.idx ] = clamp( val, prop );
  11323. });
  11324. if ( from ) {
  11325. ret = color( from( local ) );
  11326. ret[ cache ] = local;
  11327. return ret;
  11328. } else {
  11329. return color( local );
  11330. }
  11331. };
  11332. // makes red() green() blue() alpha() hue() saturation() lightness()
  11333. each( props, function( key, prop ) {
  11334. // alpha is included in more than one space
  11335. if ( color.fn[ key ] ) {
  11336. return;
  11337. }
  11338. color.fn[ key ] = function( value ) {
  11339. var vtype = jQuery.type( value ),
  11340. fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
  11341. local = this[ fn ](),
  11342. cur = local[ prop.idx ],
  11343. match;
  11344. if ( vtype === "undefined" ) {
  11345. return cur;
  11346. }
  11347. if ( vtype === "function" ) {
  11348. value = value.call( this, cur );
  11349. vtype = jQuery.type( value );
  11350. }
  11351. if ( value == null && prop.empty ) {
  11352. return this;
  11353. }
  11354. if ( vtype === "string" ) {
  11355. match = rplusequals.exec( value );
  11356. if ( match ) {
  11357. value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
  11358. }
  11359. }
  11360. local[ prop.idx ] = value;
  11361. return this[ fn ]( local );
  11362. };
  11363. });
  11364. });
  11365. // add .fx.step functions
  11366. each( stepHooks, function( i, hook ) {
  11367. jQuery.cssHooks[ hook ] = {
  11368. set: function( elem, value ) {
  11369. var parsed, curElem,
  11370. backgroundColor = "";
  11371. if ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) {
  11372. value = color( parsed || value );
  11373. if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
  11374. curElem = hook === "backgroundColor" ? elem.parentNode : elem;
  11375. while (
  11376. (backgroundColor === "" || backgroundColor === "transparent") &&
  11377. curElem && curElem.style
  11378. ) {
  11379. try {
  11380. backgroundColor = jQuery.css( curElem, "backgroundColor" );
  11381. curElem = curElem.parentNode;
  11382. } catch ( e ) {
  11383. }
  11384. }
  11385. value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
  11386. backgroundColor :
  11387. "_default" );
  11388. }
  11389. value = value.toRgbaString();
  11390. }
  11391. try {
  11392. elem.style[ hook ] = value;
  11393. } catch( error ) {
  11394. // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
  11395. }
  11396. }
  11397. };
  11398. jQuery.fx.step[ hook ] = function( fx ) {
  11399. if ( !fx.colorInit ) {
  11400. fx.start = color( fx.elem, hook );
  11401. fx.end = color( fx.end );
  11402. fx.colorInit = true;
  11403. }
  11404. jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
  11405. };
  11406. });
  11407. jQuery.cssHooks.borderColor = {
  11408. expand: function( value ) {
  11409. var expanded = {};
  11410. each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
  11411. expanded[ "border" + part + "Color" ] = value;
  11412. });
  11413. return expanded;
  11414. }
  11415. };
  11416. // Basic color names only.
  11417. // Usage of any of the other color names requires adding yourself or including
  11418. // jquery.color.svg-names.js.
  11419. colors = jQuery.Color.names = {
  11420. // 4.1. Basic color keywords
  11421. aqua: "#00ffff",
  11422. black: "#000000",
  11423. blue: "#0000ff",
  11424. fuchsia: "#ff00ff",
  11425. gray: "#808080",
  11426. green: "#008000",
  11427. lime: "#00ff00",
  11428. maroon: "#800000",
  11429. navy: "#000080",
  11430. olive: "#808000",
  11431. purple: "#800080",
  11432. red: "#ff0000",
  11433. silver: "#c0c0c0",
  11434. teal: "#008080",
  11435. white: "#ffffff",
  11436. yellow: "#ffff00",
  11437. // 4.2.3. "transparent" color keyword
  11438. transparent: [ null, null, null, 0 ],
  11439. _default: "#ffffff"
  11440. };
  11441. })( jQuery );
  11442. /******************************************************************************/
  11443. /****************************** CLASS ANIMATIONS ******************************/
  11444. /******************************************************************************/
  11445. (function() {
  11446. var classAnimationActions = [ "add", "remove", "toggle" ],
  11447. shorthandStyles = {
  11448. border: 1,
  11449. borderBottom: 1,
  11450. borderColor: 1,
  11451. borderLeft: 1,
  11452. borderRight: 1,
  11453. borderTop: 1,
  11454. borderWidth: 1,
  11455. margin: 1,
  11456. padding: 1
  11457. };
  11458. $.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
  11459. $.fx.step[ prop ] = function( fx ) {
  11460. if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
  11461. jQuery.style( fx.elem, prop, fx.end );
  11462. fx.setAttr = true;
  11463. }
  11464. };
  11465. });
  11466. function getElementStyles() {
  11467. var style = this.ownerDocument.defaultView ?
  11468. this.ownerDocument.defaultView.getComputedStyle( this, null ) :
  11469. this.currentStyle,
  11470. newStyle = {},
  11471. key,
  11472. len;
  11473. // webkit enumerates style porperties
  11474. if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
  11475. len = style.length;
  11476. while ( len-- ) {
  11477. key = style[ len ];
  11478. if ( typeof style[ key ] === "string" ) {
  11479. newStyle[ $.camelCase( key ) ] = style[ key ];
  11480. }
  11481. }
  11482. } else {
  11483. for ( key in style ) {
  11484. if ( typeof style[ key ] === "string" ) {
  11485. newStyle[ key ] = style[ key ];
  11486. }
  11487. }
  11488. }
  11489. return newStyle;
  11490. }
  11491. function styleDifference( oldStyle, newStyle ) {
  11492. var diff = {},
  11493. name, value;
  11494. for ( name in newStyle ) {
  11495. value = newStyle[ name ];
  11496. if ( oldStyle[ name ] !== value ) {
  11497. if ( !shorthandStyles[ name ] ) {
  11498. if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
  11499. diff[ name ] = value;
  11500. }
  11501. }
  11502. }
  11503. }
  11504. return diff;
  11505. }
  11506. $.effects.animateClass = function( value, duration, easing, callback ) {
  11507. var o = $.speed( duration, easing, callback );
  11508. return this.queue( function() {
  11509. var animated = $( this ),
  11510. baseClass = animated.attr( "class" ) || "",
  11511. applyClassChange,
  11512. allAnimations = o.children ? animated.find( "*" ).andSelf() : animated;
  11513. // map the animated objects to store the original styles.
  11514. allAnimations = allAnimations.map(function() {
  11515. var el = $( this );
  11516. return {
  11517. el: el,
  11518. start: getElementStyles.call( this )
  11519. };
  11520. });
  11521. // apply class change
  11522. applyClassChange = function() {
  11523. $.each( classAnimationActions, function(i, action) {
  11524. if ( value[ action ] ) {
  11525. animated[ action + "Class" ]( value[ action ] );
  11526. }
  11527. });
  11528. };
  11529. applyClassChange();
  11530. // map all animated objects again - calculate new styles and diff
  11531. allAnimations = allAnimations.map(function() {
  11532. this.end = getElementStyles.call( this.el[ 0 ] );
  11533. this.diff = styleDifference( this.start, this.end );
  11534. return this;
  11535. });
  11536. // apply original class
  11537. animated.attr( "class", baseClass );
  11538. // map all animated objects again - this time collecting a promise
  11539. allAnimations = allAnimations.map(function() {
  11540. var styleInfo = this,
  11541. dfd = $.Deferred(),
  11542. opts = jQuery.extend({}, o, {
  11543. queue: false,
  11544. complete: function() {
  11545. dfd.resolve( styleInfo );
  11546. }
  11547. });
  11548. this.el.animate( this.diff, opts );
  11549. return dfd.promise();
  11550. });
  11551. // once all animations have completed:
  11552. $.when.apply( $, allAnimations.get() ).done(function() {
  11553. // set the final class
  11554. applyClassChange();
  11555. // for each animated element,
  11556. // clear all css properties that were animated
  11557. $.each( arguments, function() {
  11558. var el = this.el;
  11559. $.each( this.diff, function(key) {
  11560. el.css( key, '' );
  11561. });
  11562. });
  11563. // this is guarnteed to be there if you use jQuery.speed()
  11564. // it also handles dequeuing the next anim...
  11565. o.complete.call( animated[ 0 ] );
  11566. });
  11567. });
  11568. };
  11569. $.fn.extend({
  11570. _addClass: $.fn.addClass,
  11571. addClass: function( classNames, speed, easing, callback ) {
  11572. return speed ?
  11573. $.effects.animateClass.call( this,
  11574. { add: classNames }, speed, easing, callback ) :
  11575. this._addClass( classNames );
  11576. },
  11577. _removeClass: $.fn.removeClass,
  11578. removeClass: function( classNames, speed, easing, callback ) {
  11579. return speed ?
  11580. $.effects.animateClass.call( this,
  11581. { remove: classNames }, speed, easing, callback ) :
  11582. this._removeClass( classNames );
  11583. },
  11584. _toggleClass: $.fn.toggleClass,
  11585. toggleClass: function( classNames, force, speed, easing, callback ) {
  11586. if ( typeof force === "boolean" || force === undefined ) {
  11587. if ( !speed ) {
  11588. // without speed parameter
  11589. return this._toggleClass( classNames, force );
  11590. } else {
  11591. return $.effects.animateClass.call( this,
  11592. (force ? { add: classNames } : { remove: classNames }),
  11593. speed, easing, callback );
  11594. }
  11595. } else {
  11596. // without force parameter
  11597. return $.effects.animateClass.call( this,
  11598. { toggle: classNames }, force, speed, easing );
  11599. }
  11600. },
  11601. switchClass: function( remove, add, speed, easing, callback) {
  11602. return $.effects.animateClass.call( this, {
  11603. add: add,
  11604. remove: remove
  11605. }, speed, easing, callback );
  11606. }
  11607. });
  11608. })();
  11609. /******************************************************************************/
  11610. /*********************************** EFFECTS **********************************/
  11611. /******************************************************************************/
  11612. (function() {
  11613. $.extend( $.effects, {
  11614. version: "1.9.1",
  11615. // Saves a set of properties in a data storage
  11616. save: function( element, set ) {
  11617. for( var i=0; i < set.length; i++ ) {
  11618. if ( set[ i ] !== null ) {
  11619. element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
  11620. }
  11621. }
  11622. },
  11623. // Restores a set of previously saved properties from a data storage
  11624. restore: function( element, set ) {
  11625. var val, i;
  11626. for( i=0; i < set.length; i++ ) {
  11627. if ( set[ i ] !== null ) {
  11628. val = element.data( dataSpace + set[ i ] );
  11629. // support: jQuery 1.6.2
  11630. // http://bugs.jquery.com/ticket/9917
  11631. // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
  11632. // We can't differentiate between "" and 0 here, so we just assume
  11633. // empty string since it's likely to be a more common value...
  11634. if ( val === undefined ) {
  11635. val = "";
  11636. }
  11637. element.css( set[ i ], val );
  11638. }
  11639. }
  11640. },
  11641. setMode: function( el, mode ) {
  11642. if (mode === "toggle") {
  11643. mode = el.is( ":hidden" ) ? "show" : "hide";
  11644. }
  11645. return mode;
  11646. },
  11647. // Translates a [top,left] array into a baseline value
  11648. // this should be a little more flexible in the future to handle a string & hash
  11649. getBaseline: function( origin, original ) {
  11650. var y, x;
  11651. switch ( origin[ 0 ] ) {
  11652. case "top": y = 0; break;
  11653. case "middle": y = 0.5; break;
  11654. case "bottom": y = 1; break;
  11655. default: y = origin[ 0 ] / original.height;
  11656. }
  11657. switch ( origin[ 1 ] ) {
  11658. case "left": x = 0; break;
  11659. case "center": x = 0.5; break;
  11660. case "right": x = 1; break;
  11661. default: x = origin[ 1 ] / original.width;
  11662. }
  11663. return {
  11664. x: x,
  11665. y: y
  11666. };
  11667. },
  11668. // Wraps the element around a wrapper that copies position properties
  11669. createWrapper: function( element ) {
  11670. // if the element is already wrapped, return it
  11671. if ( element.parent().is( ".ui-effects-wrapper" )) {
  11672. return element.parent();
  11673. }
  11674. // wrap the element
  11675. var props = {
  11676. width: element.outerWidth(true),
  11677. height: element.outerHeight(true),
  11678. "float": element.css( "float" )
  11679. },
  11680. wrapper = $( "<div></div>" )
  11681. .addClass( "ui-effects-wrapper" )
  11682. .css({
  11683. fontSize: "100%",
  11684. background: "transparent",
  11685. border: "none",
  11686. margin: 0,
  11687. padding: 0
  11688. }),
  11689. // Store the size in case width/height are defined in % - Fixes #5245
  11690. size = {
  11691. width: element.width(),
  11692. height: element.height()
  11693. },
  11694. active = document.activeElement;
  11695. // support: Firefox
  11696. // Firefox incorrectly exposes anonymous content
  11697. // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
  11698. try {
  11699. active.id;
  11700. } catch( e ) {
  11701. active = document.body;
  11702. }
  11703. element.wrap( wrapper );
  11704. // Fixes #7595 - Elements lose focus when wrapped.
  11705. if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
  11706. $( active ).focus();
  11707. }
  11708. wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
  11709. // transfer positioning properties to the wrapper
  11710. if ( element.css( "position" ) === "static" ) {
  11711. wrapper.css({ position: "relative" });
  11712. element.css({ position: "relative" });
  11713. } else {
  11714. $.extend( props, {
  11715. position: element.css( "position" ),
  11716. zIndex: element.css( "z-index" )
  11717. });
  11718. $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
  11719. props[ pos ] = element.css( pos );
  11720. if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
  11721. props[ pos ] = "auto";
  11722. }
  11723. });
  11724. element.css({
  11725. position: "relative",
  11726. top: 0,
  11727. left: 0,
  11728. right: "auto",
  11729. bottom: "auto"
  11730. });
  11731. }
  11732. element.css(size);
  11733. return wrapper.css( props ).show();
  11734. },
  11735. removeWrapper: function( element ) {
  11736. var active = document.activeElement;
  11737. if ( element.parent().is( ".ui-effects-wrapper" ) ) {
  11738. element.parent().replaceWith( element );
  11739. // Fixes #7595 - Elements lose focus when wrapped.
  11740. if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
  11741. $( active ).focus();
  11742. }
  11743. }
  11744. return element;
  11745. },
  11746. setTransition: function( element, list, factor, value ) {
  11747. value = value || {};
  11748. $.each( list, function( i, x ) {
  11749. var unit = element.cssUnit( x );
  11750. if ( unit[ 0 ] > 0 ) {
  11751. value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
  11752. }
  11753. });
  11754. return value;
  11755. }
  11756. });
  11757. // return an effect options object for the given parameters:
  11758. function _normalizeArguments( effect, options, speed, callback ) {
  11759. // allow passing all options as the first parameter
  11760. if ( $.isPlainObject( effect ) ) {
  11761. options = effect;
  11762. effect = effect.effect;
  11763. }
  11764. // convert to an object
  11765. effect = { effect: effect };
  11766. // catch (effect, null, ...)
  11767. if ( options == null ) {
  11768. options = {};
  11769. }
  11770. // catch (effect, callback)
  11771. if ( $.isFunction( options ) ) {
  11772. callback = options;
  11773. speed = null;
  11774. options = {};
  11775. }
  11776. // catch (effect, speed, ?)
  11777. if ( typeof options === "number" || $.fx.speeds[ options ] ) {
  11778. callback = speed;
  11779. speed = options;
  11780. options = {};
  11781. }
  11782. // catch (effect, options, callback)
  11783. if ( $.isFunction( speed ) ) {
  11784. callback = speed;
  11785. speed = null;
  11786. }
  11787. // add options to effect
  11788. if ( options ) {
  11789. $.extend( effect, options );
  11790. }
  11791. speed = speed || options.duration;
  11792. effect.duration = $.fx.off ? 0 :
  11793. typeof speed === "number" ? speed :
  11794. speed in $.fx.speeds ? $.fx.speeds[ speed ] :
  11795. $.fx.speeds._default;
  11796. effect.complete = callback || options.complete;
  11797. return effect;
  11798. }
  11799. function standardSpeed( speed ) {
  11800. // valid standard speeds
  11801. if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
  11802. return true;
  11803. }
  11804. // invalid strings - treat as "normal" speed
  11805. if ( typeof speed === "string" && !$.effects.effect[ speed ] ) {
  11806. // TODO: remove in 2.0 (#7115)
  11807. if ( backCompat && $.effects[ speed ] ) {
  11808. return false;
  11809. }
  11810. return true;
  11811. }
  11812. return false;
  11813. }
  11814. $.fn.extend({
  11815. effect: function( /* effect, options, speed, callback */ ) {
  11816. var args = _normalizeArguments.apply( this, arguments ),
  11817. mode = args.mode,
  11818. queue = args.queue,
  11819. effectMethod = $.effects.effect[ args.effect ],
  11820. // DEPRECATED: remove in 2.0 (#7115)
  11821. oldEffectMethod = !effectMethod && backCompat && $.effects[ args.effect ];
  11822. if ( $.fx.off || !( effectMethod || oldEffectMethod ) ) {
  11823. // delegate to the original method (e.g., .show()) if possible
  11824. if ( mode ) {
  11825. return this[ mode ]( args.duration, args.complete );
  11826. } else {
  11827. return this.each( function() {
  11828. if ( args.complete ) {
  11829. args.complete.call( this );
  11830. }
  11831. });
  11832. }
  11833. }
  11834. function run( next ) {
  11835. var elem = $( this ),
  11836. complete = args.complete,
  11837. mode = args.mode;
  11838. function done() {
  11839. if ( $.isFunction( complete ) ) {
  11840. complete.call( elem[0] );
  11841. }
  11842. if ( $.isFunction( next ) ) {
  11843. next();
  11844. }
  11845. }
  11846. // if the element is hiddden and mode is hide,
  11847. // or element is visible and mode is show
  11848. if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
  11849. done();
  11850. } else {
  11851. effectMethod.call( elem[0], args, done );
  11852. }
  11853. }
  11854. // TODO: remove this check in 2.0, effectMethod will always be true
  11855. if ( effectMethod ) {
  11856. return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
  11857. } else {
  11858. // DEPRECATED: remove in 2.0 (#7115)
  11859. return oldEffectMethod.call(this, {
  11860. options: args,
  11861. duration: args.duration,
  11862. callback: args.complete,
  11863. mode: args.mode
  11864. });
  11865. }
  11866. },
  11867. _show: $.fn.show,
  11868. show: function( speed ) {
  11869. if ( standardSpeed( speed ) ) {
  11870. return this._show.apply( this, arguments );
  11871. } else {
  11872. var args = _normalizeArguments.apply( this, arguments );
  11873. args.mode = "show";
  11874. return this.effect.call( this, args );
  11875. }
  11876. },
  11877. _hide: $.fn.hide,
  11878. hide: function( speed ) {
  11879. if ( standardSpeed( speed ) ) {
  11880. return this._hide.apply( this, arguments );
  11881. } else {
  11882. var args = _normalizeArguments.apply( this, arguments );
  11883. args.mode = "hide";
  11884. return this.effect.call( this, args );
  11885. }
  11886. },
  11887. // jQuery core overloads toggle and creates _toggle
  11888. __toggle: $.fn.toggle,
  11889. toggle: function( speed ) {
  11890. if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) {
  11891. return this.__toggle.apply( this, arguments );
  11892. } else {
  11893. var args = _normalizeArguments.apply( this, arguments );
  11894. args.mode = "toggle";
  11895. return this.effect.call( this, args );
  11896. }
  11897. },
  11898. // helper functions
  11899. cssUnit: function(key) {
  11900. var style = this.css( key ),
  11901. val = [];
  11902. $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
  11903. if ( style.indexOf( unit ) > 0 ) {
  11904. val = [ parseFloat( style ), unit ];
  11905. }
  11906. });
  11907. return val;
  11908. }
  11909. });
  11910. })();
  11911. /******************************************************************************/
  11912. /*********************************** EASING ***********************************/
  11913. /******************************************************************************/
  11914. (function() {
  11915. // based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
  11916. var baseEasings = {};
  11917. $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
  11918. baseEasings[ name ] = function( p ) {
  11919. return Math.pow( p, i + 2 );
  11920. };
  11921. });
  11922. $.extend( baseEasings, {
  11923. Sine: function ( p ) {
  11924. return 1 - Math.cos( p * Math.PI / 2 );
  11925. },
  11926. Circ: function ( p ) {
  11927. return 1 - Math.sqrt( 1 - p * p );
  11928. },
  11929. Elastic: function( p ) {
  11930. return p === 0 || p === 1 ? p :
  11931. -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
  11932. },
  11933. Back: function( p ) {
  11934. return p * p * ( 3 * p - 2 );
  11935. },
  11936. Bounce: function ( p ) {
  11937. var pow2,
  11938. bounce = 4;
  11939. while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
  11940. return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
  11941. }
  11942. });
  11943. $.each( baseEasings, function( name, easeIn ) {
  11944. $.easing[ "easeIn" + name ] = easeIn;
  11945. $.easing[ "easeOut" + name ] = function( p ) {
  11946. return 1 - easeIn( 1 - p );
  11947. };
  11948. $.easing[ "easeInOut" + name ] = function( p ) {
  11949. return p < 0.5 ?
  11950. easeIn( p * 2 ) / 2 :
  11951. 1 - easeIn( p * -2 + 2 ) / 2;
  11952. };
  11953. });
  11954. })();
  11955. })(jQuery));
  11956. (function( $, undefined ) {
  11957. var rvertical = /up|down|vertical/,
  11958. rpositivemotion = /up|left|vertical|horizontal/;
  11959. $.effects.effect.blind = function( o, done ) {
  11960. // Create element
  11961. var el = $( this ),
  11962. props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
  11963. mode = $.effects.setMode( el, o.mode || "hide" ),
  11964. direction = o.direction || "up",
  11965. vertical = rvertical.test( direction ),
  11966. ref = vertical ? "height" : "width",
  11967. ref2 = vertical ? "top" : "left",
  11968. motion = rpositivemotion.test( direction ),
  11969. animation = {},
  11970. show = mode === "show",
  11971. wrapper, distance, margin;
  11972. // if already wrapped, the wrapper's properties are my property. #6245
  11973. if ( el.parent().is( ".ui-effects-wrapper" ) ) {
  11974. $.effects.save( el.parent(), props );
  11975. } else {
  11976. $.effects.save( el, props );
  11977. }
  11978. el.show();
  11979. wrapper = $.effects.createWrapper( el ).css({
  11980. overflow: "hidden"
  11981. });
  11982. distance = wrapper[ ref ]();
  11983. margin = parseFloat( wrapper.css( ref2 ) ) || 0;
  11984. animation[ ref ] = show ? distance : 0;
  11985. if ( !motion ) {
  11986. el
  11987. .css( vertical ? "bottom" : "right", 0 )
  11988. .css( vertical ? "top" : "left", "auto" )
  11989. .css({ position: "absolute" });
  11990. animation[ ref2 ] = show ? margin : distance + margin;
  11991. }
  11992. // start at 0 if we are showing
  11993. if ( show ) {
  11994. wrapper.css( ref, 0 );
  11995. if ( ! motion ) {
  11996. wrapper.css( ref2, margin + distance );
  11997. }
  11998. }
  11999. // Animate
  12000. wrapper.animate( animation, {
  12001. duration: o.duration,
  12002. easing: o.easing,
  12003. queue: false,
  12004. complete: function() {
  12005. if ( mode === "hide" ) {
  12006. el.hide();
  12007. }
  12008. $.effects.restore( el, props );
  12009. $.effects.removeWrapper( el );
  12010. done();
  12011. }
  12012. });
  12013. };
  12014. })(jQuery);
  12015. (function( $, undefined ) {
  12016. $.effects.effect.bounce = function( o, done ) {
  12017. var el = $( this ),
  12018. props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
  12019. // defaults:
  12020. mode = $.effects.setMode( el, o.mode || "effect" ),
  12021. hide = mode === "hide",
  12022. show = mode === "show",
  12023. direction = o.direction || "up",
  12024. distance = o.distance,
  12025. times = o.times || 5,
  12026. // number of internal animations
  12027. anims = times * 2 + ( show || hide ? 1 : 0 ),
  12028. speed = o.duration / anims,
  12029. easing = o.easing,
  12030. // utility:
  12031. ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
  12032. motion = ( direction === "up" || direction === "left" ),
  12033. i,
  12034. upAnim,
  12035. downAnim,
  12036. // we will need to re-assemble the queue to stack our animations in place
  12037. queue = el.queue(),
  12038. queuelen = queue.length;
  12039. // Avoid touching opacity to prevent clearType and PNG issues in IE
  12040. if ( show || hide ) {
  12041. props.push( "opacity" );
  12042. }
  12043. $.effects.save( el, props );
  12044. el.show();
  12045. $.effects.createWrapper( el ); // Create Wrapper
  12046. // default distance for the BIGGEST bounce is the outer Distance / 3
  12047. if ( !distance ) {
  12048. distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
  12049. }
  12050. if ( show ) {
  12051. downAnim = { opacity: 1 };
  12052. downAnim[ ref ] = 0;
  12053. // if we are showing, force opacity 0 and set the initial position
  12054. // then do the "first" animation
  12055. el.css( "opacity", 0 )
  12056. .css( ref, motion ? -distance * 2 : distance * 2 )
  12057. .animate( downAnim, speed, easing );
  12058. }
  12059. // start at the smallest distance if we are hiding
  12060. if ( hide ) {
  12061. distance = distance / Math.pow( 2, times - 1 );
  12062. }
  12063. downAnim = {};
  12064. downAnim[ ref ] = 0;
  12065. // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
  12066. for ( i = 0; i < times; i++ ) {
  12067. upAnim = {};
  12068. upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
  12069. el.animate( upAnim, speed, easing )
  12070. .animate( downAnim, speed, easing );
  12071. distance = hide ? distance * 2 : distance / 2;
  12072. }
  12073. // Last Bounce when Hiding
  12074. if ( hide ) {
  12075. upAnim = { opacity: 0 };
  12076. upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
  12077. el.animate( upAnim, speed, easing );
  12078. }
  12079. el.queue(function() {
  12080. if ( hide ) {
  12081. el.hide();
  12082. }
  12083. $.effects.restore( el, props );
  12084. $.effects.removeWrapper( el );
  12085. done();
  12086. });
  12087. // inject all the animations we just queued to be first in line (after "inprogress")
  12088. if ( queuelen > 1) {
  12089. queue.splice.apply( queue,
  12090. [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
  12091. }
  12092. el.dequeue();
  12093. };
  12094. })(jQuery);
  12095. (function( $, undefined ) {
  12096. $.effects.effect.clip = function( o, done ) {
  12097. // Create element
  12098. var el = $( this ),
  12099. props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
  12100. mode = $.effects.setMode( el, o.mode || "hide" ),
  12101. show = mode === "show",
  12102. direction = o.direction || "vertical",
  12103. vert = direction === "vertical",
  12104. size = vert ? "height" : "width",
  12105. position = vert ? "top" : "left",
  12106. animation = {},
  12107. wrapper, animate, distance;
  12108. // Save & Show
  12109. $.effects.save( el, props );
  12110. el.show();
  12111. // Create Wrapper
  12112. wrapper = $.effects.createWrapper( el ).css({
  12113. overflow: "hidden"
  12114. });
  12115. animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
  12116. distance = animate[ size ]();
  12117. // Shift
  12118. if ( show ) {
  12119. animate.css( size, 0 );
  12120. animate.css( position, distance / 2 );
  12121. }
  12122. // Create Animation Object:
  12123. animation[ size ] = show ? distance : 0;
  12124. animation[ position ] = show ? 0 : distance / 2;
  12125. // Animate
  12126. animate.animate( animation, {
  12127. queue: false,
  12128. duration: o.duration,
  12129. easing: o.easing,
  12130. complete: function() {
  12131. if ( !show ) {
  12132. el.hide();
  12133. }
  12134. $.effects.restore( el, props );
  12135. $.effects.removeWrapper( el );
  12136. done();
  12137. }
  12138. });
  12139. };
  12140. })(jQuery);
  12141. (function( $, undefined ) {
  12142. $.effects.effect.drop = function( o, done ) {
  12143. var el = $( this ),
  12144. props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
  12145. mode = $.effects.setMode( el, o.mode || "hide" ),
  12146. show = mode === "show",
  12147. direction = o.direction || "left",
  12148. ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
  12149. motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
  12150. animation = {
  12151. opacity: show ? 1 : 0
  12152. },
  12153. distance;
  12154. // Adjust
  12155. $.effects.save( el, props );
  12156. el.show();
  12157. $.effects.createWrapper( el );
  12158. distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2;
  12159. if ( show ) {
  12160. el
  12161. .css( "opacity", 0 )
  12162. .css( ref, motion === "pos" ? -distance : distance );
  12163. }
  12164. // Animation
  12165. animation[ ref ] = ( show ?
  12166. ( motion === "pos" ? "+=" : "-=" ) :
  12167. ( motion === "pos" ? "-=" : "+=" ) ) +
  12168. distance;
  12169. // Animate
  12170. el.animate( animation, {
  12171. queue: false,
  12172. duration: o.duration,
  12173. easing: o.easing,
  12174. complete: function() {
  12175. if ( mode === "hide" ) {
  12176. el.hide();
  12177. }
  12178. $.effects.restore( el, props );
  12179. $.effects.removeWrapper( el );
  12180. done();
  12181. }
  12182. });
  12183. };
  12184. })(jQuery);
  12185. (function( $, undefined ) {
  12186. $.effects.effect.explode = function( o, done ) {
  12187. var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
  12188. cells = rows,
  12189. el = $( this ),
  12190. mode = $.effects.setMode( el, o.mode || "hide" ),
  12191. show = mode === "show",
  12192. // show and then visibility:hidden the element before calculating offset
  12193. offset = el.show().css( "visibility", "hidden" ).offset(),
  12194. // width and height of a piece
  12195. width = Math.ceil( el.outerWidth() / cells ),
  12196. height = Math.ceil( el.outerHeight() / rows ),
  12197. pieces = [],
  12198. // loop
  12199. i, j, left, top, mx, my;
  12200. // children animate complete:
  12201. function childComplete() {
  12202. pieces.push( this );
  12203. if ( pieces.length === rows * cells ) {
  12204. animComplete();
  12205. }
  12206. }
  12207. // clone the element for each row and cell.
  12208. for( i = 0; i < rows ; i++ ) { // ===>
  12209. top = offset.top + i * height;
  12210. my = i - ( rows - 1 ) / 2 ;
  12211. for( j = 0; j < cells ; j++ ) { // |||
  12212. left = offset.left + j * width;
  12213. mx = j - ( cells - 1 ) / 2 ;
  12214. // Create a clone of the now hidden main element that will be absolute positioned
  12215. // within a wrapper div off the -left and -top equal to size of our pieces
  12216. el
  12217. .clone()
  12218. .appendTo( "body" )
  12219. .wrap( "<div></div>" )
  12220. .css({
  12221. position: "absolute",
  12222. visibility: "visible",
  12223. left: -j * width,
  12224. top: -i * height
  12225. })
  12226. // select the wrapper - make it overflow: hidden and absolute positioned based on
  12227. // where the original was located +left and +top equal to the size of pieces
  12228. .parent()
  12229. .addClass( "ui-effects-explode" )
  12230. .css({
  12231. position: "absolute",
  12232. overflow: "hidden",
  12233. width: width,
  12234. height: height,
  12235. left: left + ( show ? mx * width : 0 ),
  12236. top: top + ( show ? my * height : 0 ),
  12237. opacity: show ? 0 : 1
  12238. }).animate({
  12239. left: left + ( show ? 0 : mx * width ),
  12240. top: top + ( show ? 0 : my * height ),
  12241. opacity: show ? 1 : 0
  12242. }, o.duration || 500, o.easing, childComplete );
  12243. }
  12244. }
  12245. function animComplete() {
  12246. el.css({
  12247. visibility: "visible"
  12248. });
  12249. $( pieces ).remove();
  12250. if ( !show ) {
  12251. el.hide();
  12252. }
  12253. done();
  12254. }
  12255. };
  12256. })(jQuery);
  12257. (function( $, undefined ) {
  12258. $.effects.effect.fade = function( o, done ) {
  12259. var el = $( this ),
  12260. mode = $.effects.setMode( el, o.mode || "toggle" );
  12261. el.animate({
  12262. opacity: mode
  12263. }, {
  12264. queue: false,
  12265. duration: o.duration,
  12266. easing: o.easing,
  12267. complete: done
  12268. });
  12269. };
  12270. })( jQuery );
  12271. (function( $, undefined ) {
  12272. $.effects.effect.fold = function( o, done ) {
  12273. // Create element
  12274. var el = $( this ),
  12275. props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
  12276. mode = $.effects.setMode( el, o.mode || "hide" ),
  12277. show = mode === "show",
  12278. hide = mode === "hide",
  12279. size = o.size || 15,
  12280. percent = /([0-9]+)%/.exec( size ),
  12281. horizFirst = !!o.horizFirst,
  12282. widthFirst = show !== horizFirst,
  12283. ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
  12284. duration = o.duration / 2,
  12285. wrapper, distance,
  12286. animation1 = {},
  12287. animation2 = {};
  12288. $.effects.save( el, props );
  12289. el.show();
  12290. // Create Wrapper
  12291. wrapper = $.effects.createWrapper( el ).css({
  12292. overflow: "hidden"
  12293. });
  12294. distance = widthFirst ?
  12295. [ wrapper.width(), wrapper.height() ] :
  12296. [ wrapper.height(), wrapper.width() ];
  12297. if ( percent ) {
  12298. size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
  12299. }
  12300. if ( show ) {
  12301. wrapper.css( horizFirst ? {
  12302. height: 0,
  12303. width: size
  12304. } : {
  12305. height: size,
  12306. width: 0
  12307. });
  12308. }
  12309. // Animation
  12310. animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
  12311. animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
  12312. // Animate
  12313. wrapper
  12314. .animate( animation1, duration, o.easing )
  12315. .animate( animation2, duration, o.easing, function() {
  12316. if ( hide ) {
  12317. el.hide();
  12318. }
  12319. $.effects.restore( el, props );
  12320. $.effects.removeWrapper( el );
  12321. done();
  12322. });
  12323. };
  12324. })(jQuery);
  12325. (function( $, undefined ) {
  12326. $.effects.effect.highlight = function( o, done ) {
  12327. var elem = $( this ),
  12328. props = [ "backgroundImage", "backgroundColor", "opacity" ],
  12329. mode = $.effects.setMode( elem, o.mode || "show" ),
  12330. animation = {
  12331. backgroundColor: elem.css( "backgroundColor" )
  12332. };
  12333. if (mode === "hide") {
  12334. animation.opacity = 0;
  12335. }
  12336. $.effects.save( elem, props );
  12337. elem
  12338. .show()
  12339. .css({
  12340. backgroundImage: "none",
  12341. backgroundColor: o.color || "#ffff99"
  12342. })
  12343. .animate( animation, {
  12344. queue: false,
  12345. duration: o.duration,
  12346. easing: o.easing,
  12347. complete: function() {
  12348. if ( mode === "hide" ) {
  12349. elem.hide();
  12350. }
  12351. $.effects.restore( elem, props );
  12352. done();
  12353. }
  12354. });
  12355. };
  12356. })(jQuery);
  12357. (function( $, undefined ) {
  12358. $.effects.effect.pulsate = function( o, done ) {
  12359. var elem = $( this ),
  12360. mode = $.effects.setMode( elem, o.mode || "show" ),
  12361. show = mode === "show",
  12362. hide = mode === "hide",
  12363. showhide = ( show || mode === "hide" ),
  12364. // showing or hiding leaves of the "last" animation
  12365. anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
  12366. duration = o.duration / anims,
  12367. animateTo = 0,
  12368. queue = elem.queue(),
  12369. queuelen = queue.length,
  12370. i;
  12371. if ( show || !elem.is(":visible")) {
  12372. elem.css( "opacity", 0 ).show();
  12373. animateTo = 1;
  12374. }
  12375. // anims - 1 opacity "toggles"
  12376. for ( i = 1; i < anims; i++ ) {
  12377. elem.animate({
  12378. opacity: animateTo
  12379. }, duration, o.easing );
  12380. animateTo = 1 - animateTo;
  12381. }
  12382. elem.animate({
  12383. opacity: animateTo
  12384. }, duration, o.easing);
  12385. elem.queue(function() {
  12386. if ( hide ) {
  12387. elem.hide();
  12388. }
  12389. done();
  12390. });
  12391. // We just queued up "anims" animations, we need to put them next in the queue
  12392. if ( queuelen > 1 ) {
  12393. queue.splice.apply( queue,
  12394. [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
  12395. }
  12396. elem.dequeue();
  12397. };
  12398. })(jQuery);
  12399. (function( $, undefined ) {
  12400. $.effects.effect.puff = function( o, done ) {
  12401. var elem = $( this ),
  12402. mode = $.effects.setMode( elem, o.mode || "hide" ),
  12403. hide = mode === "hide",
  12404. percent = parseInt( o.percent, 10 ) || 150,
  12405. factor = percent / 100,
  12406. original = {
  12407. height: elem.height(),
  12408. width: elem.width()
  12409. };
  12410. $.extend( o, {
  12411. effect: "scale",
  12412. queue: false,
  12413. fade: true,
  12414. mode: mode,
  12415. complete: done,
  12416. percent: hide ? percent : 100,
  12417. from: hide ?
  12418. original :
  12419. {
  12420. height: original.height * factor,
  12421. width: original.width * factor
  12422. }
  12423. });
  12424. elem.effect( o );
  12425. };
  12426. $.effects.effect.scale = function( o, done ) {
  12427. // Create element
  12428. var el = $( this ),
  12429. options = $.extend( true, {}, o ),
  12430. mode = $.effects.setMode( el, o.mode || "effect" ),
  12431. percent = parseInt( o.percent, 10 ) ||
  12432. ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
  12433. direction = o.direction || "both",
  12434. origin = o.origin,
  12435. original = {
  12436. height: el.height(),
  12437. width: el.width(),
  12438. outerHeight: el.outerHeight(),
  12439. outerWidth: el.outerWidth()
  12440. },
  12441. factor = {
  12442. y: direction !== "horizontal" ? (percent / 100) : 1,
  12443. x: direction !== "vertical" ? (percent / 100) : 1
  12444. };
  12445. // We are going to pass this effect to the size effect:
  12446. options.effect = "size";
  12447. options.queue = false;
  12448. options.complete = done;
  12449. // Set default origin and restore for show/hide
  12450. if ( mode !== "effect" ) {
  12451. options.origin = origin || ["middle","center"];
  12452. options.restore = true;
  12453. }
  12454. options.from = o.from || ( mode === "show" ? { height: 0, width: 0 } : original );
  12455. options.to = {
  12456. height: original.height * factor.y,
  12457. width: original.width * factor.x,
  12458. outerHeight: original.outerHeight * factor.y,
  12459. outerWidth: original.outerWidth * factor.x
  12460. };
  12461. // Fade option to support puff
  12462. if ( options.fade ) {
  12463. if ( mode === "show" ) {
  12464. options.from.opacity = 0;
  12465. options.to.opacity = 1;
  12466. }
  12467. if ( mode === "hide" ) {
  12468. options.from.opacity = 1;
  12469. options.to.opacity = 0;
  12470. }
  12471. }
  12472. // Animate
  12473. el.effect( options );
  12474. };
  12475. $.effects.effect.size = function( o, done ) {
  12476. // Create element
  12477. var original, baseline, factor,
  12478. el = $( this ),
  12479. props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
  12480. // Always restore
  12481. props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
  12482. // Copy for children
  12483. props2 = [ "width", "height", "overflow" ],
  12484. cProps = [ "fontSize" ],
  12485. vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
  12486. hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
  12487. // Set options
  12488. mode = $.effects.setMode( el, o.mode || "effect" ),
  12489. restore = o.restore || mode !== "effect",
  12490. scale = o.scale || "both",
  12491. origin = o.origin || [ "middle", "center" ],
  12492. position = el.css( "position" ),
  12493. props = restore ? props0 : props1,
  12494. zero = {
  12495. height: 0,
  12496. width: 0
  12497. };
  12498. if ( mode === "show" ) {
  12499. el.show();
  12500. }
  12501. original = {
  12502. height: el.height(),
  12503. width: el.width(),
  12504. outerHeight: el.outerHeight(),
  12505. outerWidth: el.outerWidth()
  12506. };
  12507. if ( o.mode === "toggle" && mode === "show" ) {
  12508. el.from = o.to || zero;
  12509. el.to = o.from || original;
  12510. } else {
  12511. el.from = o.from || ( mode === "show" ? zero : original );
  12512. el.to = o.to || ( mode === "hide" ? zero : original );
  12513. }
  12514. // Set scaling factor
  12515. factor = {
  12516. from: {
  12517. y: el.from.height / original.height,
  12518. x: el.from.width / original.width
  12519. },
  12520. to: {
  12521. y: el.to.height / original.height,
  12522. x: el.to.width / original.width
  12523. }
  12524. };
  12525. // Scale the css box
  12526. if ( scale === "box" || scale === "both" ) {
  12527. // Vertical props scaling
  12528. if ( factor.from.y !== factor.to.y ) {
  12529. props = props.concat( vProps );
  12530. el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
  12531. el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
  12532. }
  12533. // Horizontal props scaling
  12534. if ( factor.from.x !== factor.to.x ) {
  12535. props = props.concat( hProps );
  12536. el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
  12537. el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
  12538. }
  12539. }
  12540. // Scale the content
  12541. if ( scale === "content" || scale === "both" ) {
  12542. // Vertical props scaling
  12543. if ( factor.from.y !== factor.to.y ) {
  12544. props = props.concat( cProps ).concat( props2 );
  12545. el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
  12546. el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
  12547. }
  12548. }
  12549. $.effects.save( el, props );
  12550. el.show();
  12551. $.effects.createWrapper( el );
  12552. el.css( "overflow", "hidden" ).css( el.from );
  12553. // Adjust
  12554. if (origin) { // Calculate baseline shifts
  12555. baseline = $.effects.getBaseline( origin, original );
  12556. el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
  12557. el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
  12558. el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
  12559. el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
  12560. }
  12561. el.css( el.from ); // set top & left
  12562. // Animate
  12563. if ( scale === "content" || scale === "both" ) { // Scale the children
  12564. // Add margins/font-size
  12565. vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
  12566. hProps = hProps.concat([ "marginLeft", "marginRight" ]);
  12567. props2 = props0.concat(vProps).concat(hProps);
  12568. el.find( "*[width]" ).each( function(){
  12569. var child = $( this ),
  12570. c_original = {
  12571. height: child.height(),
  12572. width: child.width()
  12573. };
  12574. if (restore) {
  12575. $.effects.save(child, props2);
  12576. }
  12577. child.from = {
  12578. height: c_original.height * factor.from.y,
  12579. width: c_original.width * factor.from.x
  12580. };
  12581. child.to = {
  12582. height: c_original.height * factor.to.y,
  12583. width: c_original.width * factor.to.x
  12584. };
  12585. // Vertical props scaling
  12586. if ( factor.from.y !== factor.to.y ) {
  12587. child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
  12588. child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
  12589. }
  12590. // Horizontal props scaling
  12591. if ( factor.from.x !== factor.to.x ) {
  12592. child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
  12593. child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
  12594. }
  12595. // Animate children
  12596. child.css( child.from );
  12597. child.animate( child.to, o.duration, o.easing, function() {
  12598. // Restore children
  12599. if ( restore ) {
  12600. $.effects.restore( child, props2 );
  12601. }
  12602. });
  12603. });
  12604. }
  12605. // Animate
  12606. el.animate( el.to, {
  12607. queue: false,
  12608. duration: o.duration,
  12609. easing: o.easing,
  12610. complete: function() {
  12611. if ( el.to.opacity === 0 ) {
  12612. el.css( "opacity", el.from.opacity );
  12613. }
  12614. if( mode === "hide" ) {
  12615. el.hide();
  12616. }
  12617. $.effects.restore( el, props );
  12618. if ( !restore ) {
  12619. // we need to calculate our new positioning based on the scaling
  12620. if ( position === "static" ) {
  12621. el.css({
  12622. position: "relative",
  12623. top: el.to.top,
  12624. left: el.to.left
  12625. });
  12626. } else {
  12627. $.each([ "top", "left" ], function( idx, pos ) {
  12628. el.css( pos, function( _, str ) {
  12629. var val = parseInt( str, 10 ),
  12630. toRef = idx ? el.to.left : el.to.top;
  12631. // if original was "auto", recalculate the new value from wrapper
  12632. if ( str === "auto" ) {
  12633. return toRef + "px";
  12634. }
  12635. return val + toRef + "px";
  12636. });
  12637. });
  12638. }
  12639. }
  12640. $.effects.removeWrapper( el );
  12641. done();
  12642. }
  12643. });
  12644. };
  12645. })(jQuery);
  12646. (function( $, undefined ) {
  12647. $.effects.effect.shake = function( o, done ) {
  12648. var el = $( this ),
  12649. props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
  12650. mode = $.effects.setMode( el, o.mode || "effect" ),
  12651. direction = o.direction || "left",
  12652. distance = o.distance || 20,
  12653. times = o.times || 3,
  12654. anims = times * 2 + 1,
  12655. speed = Math.round(o.duration/anims),
  12656. ref = (direction === "up" || direction === "down") ? "top" : "left",
  12657. positiveMotion = (direction === "up" || direction === "left"),
  12658. animation = {},
  12659. animation1 = {},
  12660. animation2 = {},
  12661. i,
  12662. // we will need to re-assemble the queue to stack our animations in place
  12663. queue = el.queue(),
  12664. queuelen = queue.length;
  12665. $.effects.save( el, props );
  12666. el.show();
  12667. $.effects.createWrapper( el );
  12668. // Animation
  12669. animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
  12670. animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
  12671. animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
  12672. // Animate
  12673. el.animate( animation, speed, o.easing );
  12674. // Shakes
  12675. for ( i = 1; i < times; i++ ) {
  12676. el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
  12677. }
  12678. el
  12679. .animate( animation1, speed, o.easing )
  12680. .animate( animation, speed / 2, o.easing )
  12681. .queue(function() {
  12682. if ( mode === "hide" ) {
  12683. el.hide();
  12684. }
  12685. $.effects.restore( el, props );
  12686. $.effects.removeWrapper( el );
  12687. done();
  12688. });
  12689. // inject all the animations we just queued to be first in line (after "inprogress")
  12690. if ( queuelen > 1) {
  12691. queue.splice.apply( queue,
  12692. [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
  12693. }
  12694. el.dequeue();
  12695. };
  12696. })(jQuery);
  12697. (function( $, undefined ) {
  12698. $.effects.effect.slide = function( o, done ) {
  12699. // Create element
  12700. var el = $( this ),
  12701. props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
  12702. mode = $.effects.setMode( el, o.mode || "show" ),
  12703. show = mode === "show",
  12704. direction = o.direction || "left",
  12705. ref = (direction === "up" || direction === "down") ? "top" : "left",
  12706. positiveMotion = (direction === "up" || direction === "left"),
  12707. distance,
  12708. animation = {};
  12709. // Adjust
  12710. $.effects.save( el, props );
  12711. el.show();
  12712. distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
  12713. $.effects.createWrapper( el ).css({
  12714. overflow: "hidden"
  12715. });
  12716. if ( show ) {
  12717. el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
  12718. }
  12719. // Animation
  12720. animation[ ref ] = ( show ?
  12721. ( positiveMotion ? "+=" : "-=") :
  12722. ( positiveMotion ? "-=" : "+=")) +
  12723. distance;
  12724. // Animate
  12725. el.animate( animation, {
  12726. queue: false,
  12727. duration: o.duration,
  12728. easing: o.easing,
  12729. complete: function() {
  12730. if ( mode === "hide" ) {
  12731. el.hide();
  12732. }
  12733. $.effects.restore( el, props );
  12734. $.effects.removeWrapper( el );
  12735. done();
  12736. }
  12737. });
  12738. };
  12739. })(jQuery);
  12740. (function( $, undefined ) {
  12741. $.effects.effect.transfer = function( o, done ) {
  12742. var elem = $( this ),
  12743. target = $( o.to ),
  12744. targetFixed = target.css( "position" ) === "fixed",
  12745. body = $("body"),
  12746. fixTop = targetFixed ? body.scrollTop() : 0,
  12747. fixLeft = targetFixed ? body.scrollLeft() : 0,
  12748. endPosition = target.offset(),
  12749. animation = {
  12750. top: endPosition.top - fixTop ,
  12751. left: endPosition.left - fixLeft ,
  12752. height: target.innerHeight(),
  12753. width: target.innerWidth()
  12754. },
  12755. startPosition = elem.offset(),
  12756. transfer = $( '<div class="ui-effects-transfer"></div>' )
  12757. .appendTo( document.body )
  12758. .addClass( o.className )
  12759. .css({
  12760. top: startPosition.top - fixTop ,
  12761. left: startPosition.left - fixLeft ,
  12762. height: elem.innerHeight(),
  12763. width: elem.innerWidth(),
  12764. position: targetFixed ? "fixed" : "absolute"
  12765. })
  12766. .animate( animation, o.duration, o.easing, function() {
  12767. transfer.remove();
  12768. done();
  12769. });
  12770. };
  12771. })(jQuery);