jquery-ui-1.9.2.custom.js 440 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879
  1. /*! jQuery UI - v1.9.2 - 2015-03-29
  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 2015 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.2",
  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. // selectors
  113. function focusable( element, isTabIndexNotNaN ) {
  114. var map, mapName, img,
  115. nodeName = element.nodeName.toLowerCase();
  116. if ( "area" === nodeName ) {
  117. map = element.parentNode;
  118. mapName = map.name;
  119. if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
  120. return false;
  121. }
  122. img = $( "img[usemap=#" + mapName + "]" )[0];
  123. return !!img && visible( img );
  124. }
  125. return ( /input|select|textarea|button|object/.test( nodeName ) ?
  126. !element.disabled :
  127. "a" === nodeName ?
  128. element.href || isTabIndexNotNaN :
  129. isTabIndexNotNaN) &&
  130. // the element and all of its ancestors must be visible
  131. visible( element );
  132. }
  133. function visible( element ) {
  134. return $.expr.filters.visible( element ) &&
  135. !$( element ).parents().andSelf().filter(function() {
  136. return $.css( this, "visibility" ) === "hidden";
  137. }).length;
  138. }
  139. $.extend( $.expr[ ":" ], {
  140. data: $.expr.createPseudo ?
  141. $.expr.createPseudo(function( dataName ) {
  142. return function( elem ) {
  143. return !!$.data( elem, dataName );
  144. };
  145. }) :
  146. // support: jQuery <1.8
  147. function( elem, i, match ) {
  148. return !!$.data( elem, match[ 3 ] );
  149. },
  150. focusable: function( element ) {
  151. return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
  152. },
  153. tabbable: function( element ) {
  154. var tabIndex = $.attr( element, "tabindex" ),
  155. isTabIndexNaN = isNaN( tabIndex );
  156. return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
  157. }
  158. });
  159. // support
  160. $(function() {
  161. var body = document.body,
  162. div = body.appendChild( div = document.createElement( "div" ) );
  163. // access offsetHeight before setting the style to prevent a layout bug
  164. // in IE 9 which causes the element to continue to take up space even
  165. // after it is removed from the DOM (#8026)
  166. div.offsetHeight;
  167. $.extend( div.style, {
  168. minHeight: "100px",
  169. height: "auto",
  170. padding: 0,
  171. borderWidth: 0
  172. });
  173. $.support.minHeight = div.offsetHeight === 100;
  174. $.support.selectstart = "onselectstart" in div;
  175. // set display to none to avoid a layout bug in IE
  176. // http://dev.jquery.com/ticket/4014
  177. body.removeChild( div ).style.display = "none";
  178. });
  179. // support: jQuery <1.8
  180. if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
  181. $.each( [ "Width", "Height" ], function( i, name ) {
  182. var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
  183. type = name.toLowerCase(),
  184. orig = {
  185. innerWidth: $.fn.innerWidth,
  186. innerHeight: $.fn.innerHeight,
  187. outerWidth: $.fn.outerWidth,
  188. outerHeight: $.fn.outerHeight
  189. };
  190. function reduce( elem, size, border, margin ) {
  191. $.each( side, function() {
  192. size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
  193. if ( border ) {
  194. size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
  195. }
  196. if ( margin ) {
  197. size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
  198. }
  199. });
  200. return size;
  201. }
  202. $.fn[ "inner" + name ] = function( size ) {
  203. if ( size === undefined ) {
  204. return orig[ "inner" + name ].call( this );
  205. }
  206. return this.each(function() {
  207. $( this ).css( type, reduce( this, size ) + "px" );
  208. });
  209. };
  210. $.fn[ "outer" + name] = function( size, margin ) {
  211. if ( typeof size !== "number" ) {
  212. return orig[ "outer" + name ].call( this, size );
  213. }
  214. return this.each(function() {
  215. $( this).css( type, reduce( this, size, true, margin ) + "px" );
  216. });
  217. };
  218. });
  219. }
  220. // support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
  221. if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
  222. $.fn.removeData = (function( removeData ) {
  223. return function( key ) {
  224. if ( arguments.length ) {
  225. return removeData.call( this, $.camelCase( key ) );
  226. } else {
  227. return removeData.call( this );
  228. }
  229. };
  230. })( $.fn.removeData );
  231. }
  232. // deprecated
  233. (function() {
  234. var uaMatch = /msie ([\w.]+)/.exec( navigator.userAgent.toLowerCase() ) || [];
  235. $.ui.ie = uaMatch.length ? true : false;
  236. $.ui.ie6 = parseFloat( uaMatch[ 1 ], 10 ) === 6;
  237. })();
  238. $.fn.extend({
  239. disableSelection: function() {
  240. return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
  241. ".ui-disableSelection", function( event ) {
  242. event.preventDefault();
  243. });
  244. },
  245. enableSelection: function() {
  246. return this.unbind( ".ui-disableSelection" );
  247. }
  248. });
  249. $.extend( $.ui, {
  250. // $.ui.plugin is deprecated. Use the proxy pattern instead.
  251. plugin: {
  252. add: function( module, option, set ) {
  253. var i,
  254. proto = $.ui[ module ].prototype;
  255. for ( i in set ) {
  256. proto.plugins[ i ] = proto.plugins[ i ] || [];
  257. proto.plugins[ i ].push( [ option, set[ i ] ] );
  258. }
  259. },
  260. call: function( instance, name, args ) {
  261. var i,
  262. set = instance.plugins[ name ];
  263. if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
  264. return;
  265. }
  266. for ( i = 0; i < set.length; i++ ) {
  267. if ( instance.options[ set[ i ][ 0 ] ] ) {
  268. set[ i ][ 1 ].apply( instance.element, args );
  269. }
  270. }
  271. }
  272. },
  273. contains: $.contains,
  274. // only used by resizable
  275. hasScroll: function( el, a ) {
  276. //If overflow is hidden, the element might have extra content, but the user wants to hide it
  277. if ( $( el ).css( "overflow" ) === "hidden") {
  278. return false;
  279. }
  280. var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
  281. has = false;
  282. if ( el[ scroll ] > 0 ) {
  283. return true;
  284. }
  285. // TODO: determine which cases actually cause this to happen
  286. // if the element doesn't have the scroll set, see if it's possible to
  287. // set the scroll
  288. el[ scroll ] = 1;
  289. has = ( el[ scroll ] > 0 );
  290. el[ scroll ] = 0;
  291. return has;
  292. },
  293. // these are odd functions, fix the API or move into individual plugins
  294. isOverAxis: function( x, reference, size ) {
  295. //Determines when x coordinate is over "b" element axis
  296. return ( x > reference ) && ( x < ( reference + size ) );
  297. },
  298. isOver: function( y, x, top, left, height, width ) {
  299. //Determines when x, y coordinates is over "b" element
  300. return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
  301. }
  302. });
  303. })( jQuery );
  304. (function( $, undefined ) {
  305. var uuid = 0,
  306. slice = Array.prototype.slice,
  307. _cleanData = $.cleanData;
  308. $.cleanData = function( elems ) {
  309. for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
  310. try {
  311. $( elem ).triggerHandler( "remove" );
  312. // http://bugs.jquery.com/ticket/8235
  313. } catch( e ) {}
  314. }
  315. _cleanData( elems );
  316. };
  317. $.widget = function( name, base, prototype ) {
  318. var fullName, existingConstructor, constructor, basePrototype,
  319. namespace = name.split( "." )[ 0 ];
  320. name = name.split( "." )[ 1 ];
  321. fullName = namespace + "-" + name;
  322. if ( !prototype ) {
  323. prototype = base;
  324. base = $.Widget;
  325. }
  326. // create selector for plugin
  327. $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
  328. return !!$.data( elem, fullName );
  329. };
  330. $[ namespace ] = $[ namespace ] || {};
  331. existingConstructor = $[ namespace ][ name ];
  332. constructor = $[ namespace ][ name ] = function( options, element ) {
  333. // allow instantiation without "new" keyword
  334. if ( !this._createWidget ) {
  335. return new constructor( options, element );
  336. }
  337. // allow instantiation without initializing for simple inheritance
  338. // must use "new" keyword (the code above always passes args)
  339. if ( arguments.length ) {
  340. this._createWidget( options, element );
  341. }
  342. };
  343. // extend with the existing constructor to carry over any static properties
  344. $.extend( constructor, existingConstructor, {
  345. version: prototype.version,
  346. // copy the object used to create the prototype in case we need to
  347. // redefine the widget later
  348. _proto: $.extend( {}, prototype ),
  349. // track widgets that inherit from this widget in case this widget is
  350. // redefined after a widget inherits from it
  351. _childConstructors: []
  352. });
  353. basePrototype = new base();
  354. // we need to make the options hash a property directly on the new instance
  355. // otherwise we'll modify the options hash on the prototype that we're
  356. // inheriting from
  357. basePrototype.options = $.widget.extend( {}, basePrototype.options );
  358. $.each( prototype, function( prop, value ) {
  359. if ( $.isFunction( value ) ) {
  360. prototype[ prop ] = (function() {
  361. var _super = function() {
  362. return base.prototype[ prop ].apply( this, arguments );
  363. },
  364. _superApply = function( args ) {
  365. return base.prototype[ prop ].apply( this, args );
  366. };
  367. return function() {
  368. var __super = this._super,
  369. __superApply = this._superApply,
  370. returnValue;
  371. this._super = _super;
  372. this._superApply = _superApply;
  373. returnValue = value.apply( this, arguments );
  374. this._super = __super;
  375. this._superApply = __superApply;
  376. return returnValue;
  377. };
  378. })();
  379. }
  380. });
  381. constructor.prototype = $.widget.extend( basePrototype, {
  382. // TODO: remove support for widgetEventPrefix
  383. // always use the name + a colon as the prefix, e.g., draggable:start
  384. // don't prefix for widgets that aren't DOM-based
  385. widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
  386. }, prototype, {
  387. constructor: constructor,
  388. namespace: namespace,
  389. widgetName: name,
  390. // TODO remove widgetBaseClass, see #8155
  391. widgetBaseClass: fullName,
  392. widgetFullName: fullName
  393. });
  394. // If this widget is being redefined then we need to find all widgets that
  395. // are inheriting from it and redefine all of them so that they inherit from
  396. // the new version of this widget. We're essentially trying to replace one
  397. // level in the prototype chain.
  398. if ( existingConstructor ) {
  399. $.each( existingConstructor._childConstructors, function( i, child ) {
  400. var childPrototype = child.prototype;
  401. // redefine the child widget using the same prototype that was
  402. // originally used, but inherit from the new version of the base
  403. $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
  404. });
  405. // remove the list of existing child constructors from the old constructor
  406. // so the old child constructors can be garbage collected
  407. delete existingConstructor._childConstructors;
  408. } else {
  409. base._childConstructors.push( constructor );
  410. }
  411. $.widget.bridge( name, constructor );
  412. };
  413. $.widget.extend = function( target ) {
  414. var input = slice.call( arguments, 1 ),
  415. inputIndex = 0,
  416. inputLength = input.length,
  417. key,
  418. value;
  419. for ( ; inputIndex < inputLength; inputIndex++ ) {
  420. for ( key in input[ inputIndex ] ) {
  421. value = input[ inputIndex ][ key ];
  422. if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
  423. // Clone objects
  424. if ( $.isPlainObject( value ) ) {
  425. target[ key ] = $.isPlainObject( target[ key ] ) ?
  426. $.widget.extend( {}, target[ key ], value ) :
  427. // Don't extend strings, arrays, etc. with objects
  428. $.widget.extend( {}, value );
  429. // Copy everything else by reference
  430. } else {
  431. target[ key ] = value;
  432. }
  433. }
  434. }
  435. }
  436. return target;
  437. };
  438. $.widget.bridge = function( name, object ) {
  439. var fullName = object.prototype.widgetFullName || name;
  440. $.fn[ name ] = function( options ) {
  441. var isMethodCall = typeof options === "string",
  442. args = slice.call( arguments, 1 ),
  443. returnValue = this;
  444. // allow multiple hashes to be passed on init
  445. options = !isMethodCall && args.length ?
  446. $.widget.extend.apply( null, [ options ].concat(args) ) :
  447. options;
  448. if ( isMethodCall ) {
  449. this.each(function() {
  450. var methodValue,
  451. instance = $.data( this, fullName );
  452. if ( !instance ) {
  453. return $.error( "cannot call methods on " + name + " prior to initialization; " +
  454. "attempted to call method '" + options + "'" );
  455. }
  456. if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
  457. return $.error( "no such method '" + options + "' for " + name + " widget instance" );
  458. }
  459. methodValue = instance[ options ].apply( instance, args );
  460. if ( methodValue !== instance && methodValue !== undefined ) {
  461. returnValue = methodValue && methodValue.jquery ?
  462. returnValue.pushStack( methodValue.get() ) :
  463. methodValue;
  464. return false;
  465. }
  466. });
  467. } else {
  468. this.each(function() {
  469. var instance = $.data( this, fullName );
  470. if ( instance ) {
  471. instance.option( options || {} )._init();
  472. } else {
  473. $.data( this, fullName, new object( options, this ) );
  474. }
  475. });
  476. }
  477. return returnValue;
  478. };
  479. };
  480. $.Widget = function( /* options, element */ ) {};
  481. $.Widget._childConstructors = [];
  482. $.Widget.prototype = {
  483. widgetName: "widget",
  484. widgetEventPrefix: "",
  485. defaultElement: "<div>",
  486. options: {
  487. disabled: false,
  488. // callbacks
  489. create: null
  490. },
  491. _createWidget: function( options, element ) {
  492. element = $( element || this.defaultElement || this )[ 0 ];
  493. this.element = $( element );
  494. this.uuid = uuid++;
  495. this.eventNamespace = "." + this.widgetName + this.uuid;
  496. this.options = $.widget.extend( {},
  497. this.options,
  498. this._getCreateOptions(),
  499. options );
  500. this.bindings = $();
  501. this.hoverable = $();
  502. this.focusable = $();
  503. if ( element !== this ) {
  504. // 1.9 BC for #7810
  505. // TODO remove dual storage
  506. $.data( element, this.widgetName, this );
  507. $.data( element, this.widgetFullName, this );
  508. this._on( true, this.element, {
  509. remove: function( event ) {
  510. if ( event.target === element ) {
  511. this.destroy();
  512. }
  513. }
  514. });
  515. this.document = $( element.style ?
  516. // element within the document
  517. element.ownerDocument :
  518. // element is window or document
  519. element.document || element );
  520. this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
  521. }
  522. this._create();
  523. this._trigger( "create", null, this._getCreateEventData() );
  524. this._init();
  525. },
  526. _getCreateOptions: $.noop,
  527. _getCreateEventData: $.noop,
  528. _create: $.noop,
  529. _init: $.noop,
  530. destroy: function() {
  531. this._destroy();
  532. // we can probably remove the unbind calls in 2.0
  533. // all event bindings should go through this._on()
  534. this.element
  535. .unbind( this.eventNamespace )
  536. // 1.9 BC for #7810
  537. // TODO remove dual storage
  538. .removeData( this.widgetName )
  539. .removeData( this.widgetFullName )
  540. // support: jquery <1.6.3
  541. // http://bugs.jquery.com/ticket/9413
  542. .removeData( $.camelCase( this.widgetFullName ) );
  543. this.widget()
  544. .unbind( this.eventNamespace )
  545. .removeAttr( "aria-disabled" )
  546. .removeClass(
  547. this.widgetFullName + "-disabled " +
  548. "ui-state-disabled" );
  549. // clean up events and states
  550. this.bindings.unbind( this.eventNamespace );
  551. this.hoverable.removeClass( "ui-state-hover" );
  552. this.focusable.removeClass( "ui-state-focus" );
  553. },
  554. _destroy: $.noop,
  555. widget: function() {
  556. return this.element;
  557. },
  558. option: function( key, value ) {
  559. var options = key,
  560. parts,
  561. curOption,
  562. i;
  563. if ( arguments.length === 0 ) {
  564. // don't return a reference to the internal hash
  565. return $.widget.extend( {}, this.options );
  566. }
  567. if ( typeof key === "string" ) {
  568. // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
  569. options = {};
  570. parts = key.split( "." );
  571. key = parts.shift();
  572. if ( parts.length ) {
  573. curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
  574. for ( i = 0; i < parts.length - 1; i++ ) {
  575. curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
  576. curOption = curOption[ parts[ i ] ];
  577. }
  578. key = parts.pop();
  579. if ( value === undefined ) {
  580. return curOption[ key ] === undefined ? null : curOption[ key ];
  581. }
  582. curOption[ key ] = value;
  583. } else {
  584. if ( value === undefined ) {
  585. return this.options[ key ] === undefined ? null : this.options[ key ];
  586. }
  587. options[ key ] = value;
  588. }
  589. }
  590. this._setOptions( options );
  591. return this;
  592. },
  593. _setOptions: function( options ) {
  594. var key;
  595. for ( key in options ) {
  596. this._setOption( key, options[ key ] );
  597. }
  598. return this;
  599. },
  600. _setOption: function( key, value ) {
  601. this.options[ key ] = value;
  602. if ( key === "disabled" ) {
  603. this.widget()
  604. .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
  605. .attr( "aria-disabled", value );
  606. this.hoverable.removeClass( "ui-state-hover" );
  607. this.focusable.removeClass( "ui-state-focus" );
  608. }
  609. return this;
  610. },
  611. enable: function() {
  612. return this._setOption( "disabled", false );
  613. },
  614. disable: function() {
  615. return this._setOption( "disabled", true );
  616. },
  617. _on: function( suppressDisabledCheck, element, handlers ) {
  618. var delegateElement,
  619. instance = this;
  620. // no suppressDisabledCheck flag, shuffle arguments
  621. if ( typeof suppressDisabledCheck !== "boolean" ) {
  622. handlers = element;
  623. element = suppressDisabledCheck;
  624. suppressDisabledCheck = false;
  625. }
  626. // no element argument, shuffle and use this.element
  627. if ( !handlers ) {
  628. handlers = element;
  629. element = this.element;
  630. delegateElement = this.widget();
  631. } else {
  632. // accept selectors, DOM elements
  633. element = delegateElement = $( element );
  634. this.bindings = this.bindings.add( element );
  635. }
  636. $.each( handlers, function( event, handler ) {
  637. function handlerProxy() {
  638. // allow widgets to customize the disabled handling
  639. // - disabled as an array instead of boolean
  640. // - disabled class as method for disabling individual parts
  641. if ( !suppressDisabledCheck &&
  642. ( instance.options.disabled === true ||
  643. $( this ).hasClass( "ui-state-disabled" ) ) ) {
  644. return;
  645. }
  646. return ( typeof handler === "string" ? instance[ handler ] : handler )
  647. .apply( instance, arguments );
  648. }
  649. // copy the guid so direct unbinding works
  650. if ( typeof handler !== "string" ) {
  651. handlerProxy.guid = handler.guid =
  652. handler.guid || handlerProxy.guid || $.guid++;
  653. }
  654. var match = event.match( /^(\w+)\s*(.*)$/ ),
  655. eventName = match[1] + instance.eventNamespace,
  656. selector = match[2];
  657. if ( selector ) {
  658. delegateElement.delegate( selector, eventName, handlerProxy );
  659. } else {
  660. element.bind( eventName, handlerProxy );
  661. }
  662. });
  663. },
  664. _off: function( element, eventName ) {
  665. eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
  666. element.unbind( eventName ).undelegate( eventName );
  667. },
  668. _delay: function( handler, delay ) {
  669. function handlerProxy() {
  670. return ( typeof handler === "string" ? instance[ handler ] : handler )
  671. .apply( instance, arguments );
  672. }
  673. var instance = this;
  674. return setTimeout( handlerProxy, delay || 0 );
  675. },
  676. _hoverable: function( element ) {
  677. this.hoverable = this.hoverable.add( element );
  678. this._on( element, {
  679. mouseenter: function( event ) {
  680. $( event.currentTarget ).addClass( "ui-state-hover" );
  681. },
  682. mouseleave: function( event ) {
  683. $( event.currentTarget ).removeClass( "ui-state-hover" );
  684. }
  685. });
  686. },
  687. _focusable: function( element ) {
  688. this.focusable = this.focusable.add( element );
  689. this._on( element, {
  690. focusin: function( event ) {
  691. $( event.currentTarget ).addClass( "ui-state-focus" );
  692. },
  693. focusout: function( event ) {
  694. $( event.currentTarget ).removeClass( "ui-state-focus" );
  695. }
  696. });
  697. },
  698. _trigger: function( type, event, data ) {
  699. var prop, orig,
  700. callback = this.options[ type ];
  701. data = data || {};
  702. event = $.Event( event );
  703. event.type = ( type === this.widgetEventPrefix ?
  704. type :
  705. this.widgetEventPrefix + type ).toLowerCase();
  706. // the original event may come from any element
  707. // so we need to reset the target on the new event
  708. event.target = this.element[ 0 ];
  709. // copy original event properties over to the new event
  710. orig = event.originalEvent;
  711. if ( orig ) {
  712. for ( prop in orig ) {
  713. if ( !( prop in event ) ) {
  714. event[ prop ] = orig[ prop ];
  715. }
  716. }
  717. }
  718. this.element.trigger( event, data );
  719. return !( $.isFunction( callback ) &&
  720. callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
  721. event.isDefaultPrevented() );
  722. }
  723. };
  724. $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
  725. $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
  726. if ( typeof options === "string" ) {
  727. options = { effect: options };
  728. }
  729. var hasOptions,
  730. effectName = !options ?
  731. method :
  732. options === true || typeof options === "number" ?
  733. defaultEffect :
  734. options.effect || defaultEffect;
  735. options = options || {};
  736. if ( typeof options === "number" ) {
  737. options = { duration: options };
  738. }
  739. hasOptions = !$.isEmptyObject( options );
  740. options.complete = callback;
  741. if ( options.delay ) {
  742. element.delay( options.delay );
  743. }
  744. if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) {
  745. element[ method ]( options );
  746. } else if ( effectName !== method && element[ effectName ] ) {
  747. element[ effectName ]( options.duration, options.easing, callback );
  748. } else {
  749. element.queue(function( next ) {
  750. $( this )[ method ]();
  751. if ( callback ) {
  752. callback.call( element[ 0 ] );
  753. }
  754. next();
  755. });
  756. }
  757. };
  758. });
  759. // DEPRECATED
  760. if ( $.uiBackCompat !== false ) {
  761. $.Widget.prototype._getCreateOptions = function() {
  762. return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
  763. };
  764. }
  765. })( jQuery );
  766. (function( $, undefined ) {
  767. var mouseHandled = false;
  768. $( document ).mouseup( function( e ) {
  769. mouseHandled = false;
  770. });
  771. $.widget("ui.mouse", {
  772. version: "1.9.2",
  773. options: {
  774. cancel: 'input,textarea,button,select,option',
  775. distance: 1,
  776. delay: 0
  777. },
  778. _mouseInit: function() {
  779. var that = this;
  780. this.element
  781. .bind('mousedown.'+this.widgetName, function(event) {
  782. return that._mouseDown(event);
  783. })
  784. .bind('click.'+this.widgetName, function(event) {
  785. if (true === $.data(event.target, that.widgetName + '.preventClickEvent')) {
  786. $.removeData(event.target, that.widgetName + '.preventClickEvent');
  787. event.stopImmediatePropagation();
  788. return false;
  789. }
  790. });
  791. this.started = false;
  792. },
  793. // TODO: make sure destroying one instance of mouse doesn't mess with
  794. // other instances of mouse
  795. _mouseDestroy: function() {
  796. this.element.unbind('.'+this.widgetName);
  797. if ( this._mouseMoveDelegate ) {
  798. $(document)
  799. .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
  800. .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
  801. }
  802. },
  803. _mouseDown: function(event) {
  804. // don't let more than one widget handle mouseStart
  805. if( mouseHandled ) { return; }
  806. // we may have missed mouseup (out of window)
  807. (this._mouseStarted && this._mouseUp(event));
  808. this._mouseDownEvent = event;
  809. var that = this,
  810. btnIsLeft = (event.which === 1),
  811. // event.target.nodeName works around a bug in IE 8 with
  812. // disabled inputs (#7620)
  813. elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
  814. if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
  815. return true;
  816. }
  817. this.mouseDelayMet = !this.options.delay;
  818. if (!this.mouseDelayMet) {
  819. this._mouseDelayTimer = setTimeout(function() {
  820. that.mouseDelayMet = true;
  821. }, this.options.delay);
  822. }
  823. if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
  824. this._mouseStarted = (this._mouseStart(event) !== false);
  825. if (!this._mouseStarted) {
  826. event.preventDefault();
  827. return true;
  828. }
  829. }
  830. // Click event may never have fired (Gecko & Opera)
  831. if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) {
  832. $.removeData(event.target, this.widgetName + '.preventClickEvent');
  833. }
  834. // these delegates are required to keep context
  835. this._mouseMoveDelegate = function(event) {
  836. return that._mouseMove(event);
  837. };
  838. this._mouseUpDelegate = function(event) {
  839. return that._mouseUp(event);
  840. };
  841. $(document)
  842. .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
  843. .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
  844. event.preventDefault();
  845. mouseHandled = true;
  846. return true;
  847. },
  848. _mouseMove: function(event) {
  849. // IE mouseup check - mouseup happened when mouse was out of window
  850. if ($.ui.ie && !(document.documentMode >= 9) && !event.button) {
  851. return this._mouseUp(event);
  852. }
  853. if (this._mouseStarted) {
  854. this._mouseDrag(event);
  855. return event.preventDefault();
  856. }
  857. if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
  858. this._mouseStarted =
  859. (this._mouseStart(this._mouseDownEvent, event) !== false);
  860. (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
  861. }
  862. return !this._mouseStarted;
  863. },
  864. _mouseUp: function(event) {
  865. $(document)
  866. .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
  867. .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
  868. if (this._mouseStarted) {
  869. this._mouseStarted = false;
  870. if (event.target === this._mouseDownEvent.target) {
  871. $.data(event.target, this.widgetName + '.preventClickEvent', true);
  872. }
  873. this._mouseStop(event);
  874. }
  875. return false;
  876. },
  877. _mouseDistanceMet: function(event) {
  878. return (Math.max(
  879. Math.abs(this._mouseDownEvent.pageX - event.pageX),
  880. Math.abs(this._mouseDownEvent.pageY - event.pageY)
  881. ) >= this.options.distance
  882. );
  883. },
  884. _mouseDelayMet: function(event) {
  885. return this.mouseDelayMet;
  886. },
  887. // These are placeholder methods, to be overriden by extending plugin
  888. _mouseStart: function(event) {},
  889. _mouseDrag: function(event) {},
  890. _mouseStop: function(event) {},
  891. _mouseCapture: function(event) { return true; }
  892. });
  893. })(jQuery);
  894. (function( $, undefined ) {
  895. $.ui = $.ui || {};
  896. var cachedScrollbarWidth,
  897. max = Math.max,
  898. abs = Math.abs,
  899. round = Math.round,
  900. rhorizontal = /left|center|right/,
  901. rvertical = /top|center|bottom/,
  902. roffset = /[\+\-]\d+%?/,
  903. rposition = /^\w+/,
  904. rpercent = /%$/,
  905. _position = $.fn.position;
  906. function getOffsets( offsets, width, height ) {
  907. return [
  908. parseInt( offsets[ 0 ], 10 ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
  909. parseInt( offsets[ 1 ], 10 ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
  910. ];
  911. }
  912. function parseCss( element, property ) {
  913. return parseInt( $.css( element, property ), 10 ) || 0;
  914. }
  915. $.position = {
  916. scrollbarWidth: function() {
  917. if ( cachedScrollbarWidth !== undefined ) {
  918. return cachedScrollbarWidth;
  919. }
  920. var w1, w2,
  921. div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
  922. innerDiv = div.children()[0];
  923. $( "body" ).append( div );
  924. w1 = innerDiv.offsetWidth;
  925. div.css( "overflow", "scroll" );
  926. w2 = innerDiv.offsetWidth;
  927. if ( w1 === w2 ) {
  928. w2 = div[0].clientWidth;
  929. }
  930. div.remove();
  931. return (cachedScrollbarWidth = w1 - w2);
  932. },
  933. getScrollInfo: function( within ) {
  934. var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ),
  935. overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ),
  936. hasOverflowX = overflowX === "scroll" ||
  937. ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
  938. hasOverflowY = overflowY === "scroll" ||
  939. ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
  940. return {
  941. width: hasOverflowX ? $.position.scrollbarWidth() : 0,
  942. height: hasOverflowY ? $.position.scrollbarWidth() : 0
  943. };
  944. },
  945. getWithinInfo: function( element ) {
  946. var withinElement = $( element || window ),
  947. isWindow = $.isWindow( withinElement[0] );
  948. return {
  949. element: withinElement,
  950. isWindow: isWindow,
  951. offset: withinElement.offset() || { left: 0, top: 0 },
  952. scrollLeft: withinElement.scrollLeft(),
  953. scrollTop: withinElement.scrollTop(),
  954. width: isWindow ? withinElement.width() : withinElement.outerWidth(),
  955. height: isWindow ? withinElement.height() : withinElement.outerHeight()
  956. };
  957. }
  958. };
  959. $.fn.position = function( options ) {
  960. if ( !options || !options.of ) {
  961. return _position.apply( this, arguments );
  962. }
  963. // make a copy, we don't want to modify arguments
  964. options = $.extend( {}, options );
  965. var atOffset, targetWidth, targetHeight, targetOffset, basePosition,
  966. target = $( options.of ),
  967. within = $.position.getWithinInfo( options.within ),
  968. scrollInfo = $.position.getScrollInfo( within ),
  969. targetElem = target[0],
  970. collision = ( options.collision || "flip" ).split( " " ),
  971. offsets = {};
  972. if ( targetElem.nodeType === 9 ) {
  973. targetWidth = target.width();
  974. targetHeight = target.height();
  975. targetOffset = { top: 0, left: 0 };
  976. } else if ( $.isWindow( targetElem ) ) {
  977. targetWidth = target.width();
  978. targetHeight = target.height();
  979. targetOffset = { top: target.scrollTop(), left: target.scrollLeft() };
  980. } else if ( targetElem.preventDefault ) {
  981. // force left top to allow flipping
  982. options.at = "left top";
  983. targetWidth = targetHeight = 0;
  984. targetOffset = { top: targetElem.pageY, left: targetElem.pageX };
  985. } else {
  986. targetWidth = target.outerWidth();
  987. targetHeight = target.outerHeight();
  988. targetOffset = target.offset();
  989. }
  990. // clone to reuse original targetOffset later
  991. basePosition = $.extend( {}, targetOffset );
  992. // force my and at to have valid horizontal and vertical positions
  993. // if a value is missing or invalid, it will be converted to center
  994. $.each( [ "my", "at" ], function() {
  995. var pos = ( options[ this ] || "" ).split( " " ),
  996. horizontalOffset,
  997. verticalOffset;
  998. if ( pos.length === 1) {
  999. pos = rhorizontal.test( pos[ 0 ] ) ?
  1000. pos.concat( [ "center" ] ) :
  1001. rvertical.test( pos[ 0 ] ) ?
  1002. [ "center" ].concat( pos ) :
  1003. [ "center", "center" ];
  1004. }
  1005. pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
  1006. pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
  1007. // calculate offsets
  1008. horizontalOffset = roffset.exec( pos[ 0 ] );
  1009. verticalOffset = roffset.exec( pos[ 1 ] );
  1010. offsets[ this ] = [
  1011. horizontalOffset ? horizontalOffset[ 0 ] : 0,
  1012. verticalOffset ? verticalOffset[ 0 ] : 0
  1013. ];
  1014. // reduce to just the positions without the offsets
  1015. options[ this ] = [
  1016. rposition.exec( pos[ 0 ] )[ 0 ],
  1017. rposition.exec( pos[ 1 ] )[ 0 ]
  1018. ];
  1019. });
  1020. // normalize collision option
  1021. if ( collision.length === 1 ) {
  1022. collision[ 1 ] = collision[ 0 ];
  1023. }
  1024. if ( options.at[ 0 ] === "right" ) {
  1025. basePosition.left += targetWidth;
  1026. } else if ( options.at[ 0 ] === "center" ) {
  1027. basePosition.left += targetWidth / 2;
  1028. }
  1029. if ( options.at[ 1 ] === "bottom" ) {
  1030. basePosition.top += targetHeight;
  1031. } else if ( options.at[ 1 ] === "center" ) {
  1032. basePosition.top += targetHeight / 2;
  1033. }
  1034. atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
  1035. basePosition.left += atOffset[ 0 ];
  1036. basePosition.top += atOffset[ 1 ];
  1037. return this.each(function() {
  1038. var collisionPosition, using,
  1039. elem = $( this ),
  1040. elemWidth = elem.outerWidth(),
  1041. elemHeight = elem.outerHeight(),
  1042. marginLeft = parseCss( this, "marginLeft" ),
  1043. marginTop = parseCss( this, "marginTop" ),
  1044. collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
  1045. collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
  1046. position = $.extend( {}, basePosition ),
  1047. myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
  1048. if ( options.my[ 0 ] === "right" ) {
  1049. position.left -= elemWidth;
  1050. } else if ( options.my[ 0 ] === "center" ) {
  1051. position.left -= elemWidth / 2;
  1052. }
  1053. if ( options.my[ 1 ] === "bottom" ) {
  1054. position.top -= elemHeight;
  1055. } else if ( options.my[ 1 ] === "center" ) {
  1056. position.top -= elemHeight / 2;
  1057. }
  1058. position.left += myOffset[ 0 ];
  1059. position.top += myOffset[ 1 ];
  1060. // if the browser doesn't support fractions, then round for consistent results
  1061. if ( !$.support.offsetFractions ) {
  1062. position.left = round( position.left );
  1063. position.top = round( position.top );
  1064. }
  1065. collisionPosition = {
  1066. marginLeft: marginLeft,
  1067. marginTop: marginTop
  1068. };
  1069. $.each( [ "left", "top" ], function( i, dir ) {
  1070. if ( $.ui.position[ collision[ i ] ] ) {
  1071. $.ui.position[ collision[ i ] ][ dir ]( position, {
  1072. targetWidth: targetWidth,
  1073. targetHeight: targetHeight,
  1074. elemWidth: elemWidth,
  1075. elemHeight: elemHeight,
  1076. collisionPosition: collisionPosition,
  1077. collisionWidth: collisionWidth,
  1078. collisionHeight: collisionHeight,
  1079. offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
  1080. my: options.my,
  1081. at: options.at,
  1082. within: within,
  1083. elem : elem
  1084. });
  1085. }
  1086. });
  1087. if ( $.fn.bgiframe ) {
  1088. elem.bgiframe();
  1089. }
  1090. if ( options.using ) {
  1091. // adds feedback as second argument to using callback, if present
  1092. using = function( props ) {
  1093. var left = targetOffset.left - position.left,
  1094. right = left + targetWidth - elemWidth,
  1095. top = targetOffset.top - position.top,
  1096. bottom = top + targetHeight - elemHeight,
  1097. feedback = {
  1098. target: {
  1099. element: target,
  1100. left: targetOffset.left,
  1101. top: targetOffset.top,
  1102. width: targetWidth,
  1103. height: targetHeight
  1104. },
  1105. element: {
  1106. element: elem,
  1107. left: position.left,
  1108. top: position.top,
  1109. width: elemWidth,
  1110. height: elemHeight
  1111. },
  1112. horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
  1113. vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
  1114. };
  1115. if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
  1116. feedback.horizontal = "center";
  1117. }
  1118. if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
  1119. feedback.vertical = "middle";
  1120. }
  1121. if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
  1122. feedback.important = "horizontal";
  1123. } else {
  1124. feedback.important = "vertical";
  1125. }
  1126. options.using.call( this, props, feedback );
  1127. };
  1128. }
  1129. elem.offset( $.extend( position, { using: using } ) );
  1130. });
  1131. };
  1132. $.ui.position = {
  1133. fit: {
  1134. left: function( position, data ) {
  1135. var within = data.within,
  1136. withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
  1137. outerWidth = within.width,
  1138. collisionPosLeft = position.left - data.collisionPosition.marginLeft,
  1139. overLeft = withinOffset - collisionPosLeft,
  1140. overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
  1141. newOverRight;
  1142. // element is wider than within
  1143. if ( data.collisionWidth > outerWidth ) {
  1144. // element is initially over the left side of within
  1145. if ( overLeft > 0 && overRight <= 0 ) {
  1146. newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
  1147. position.left += overLeft - newOverRight;
  1148. // element is initially over right side of within
  1149. } else if ( overRight > 0 && overLeft <= 0 ) {
  1150. position.left = withinOffset;
  1151. // element is initially over both left and right sides of within
  1152. } else {
  1153. if ( overLeft > overRight ) {
  1154. position.left = withinOffset + outerWidth - data.collisionWidth;
  1155. } else {
  1156. position.left = withinOffset;
  1157. }
  1158. }
  1159. // too far left -> align with left edge
  1160. } else if ( overLeft > 0 ) {
  1161. position.left += overLeft;
  1162. // too far right -> align with right edge
  1163. } else if ( overRight > 0 ) {
  1164. position.left -= overRight;
  1165. // adjust based on position and margin
  1166. } else {
  1167. position.left = max( position.left - collisionPosLeft, position.left );
  1168. }
  1169. },
  1170. top: function( position, data ) {
  1171. var within = data.within,
  1172. withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
  1173. outerHeight = data.within.height,
  1174. collisionPosTop = position.top - data.collisionPosition.marginTop,
  1175. overTop = withinOffset - collisionPosTop,
  1176. overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
  1177. newOverBottom;
  1178. // element is taller than within
  1179. if ( data.collisionHeight > outerHeight ) {
  1180. // element is initially over the top of within
  1181. if ( overTop > 0 && overBottom <= 0 ) {
  1182. newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
  1183. position.top += overTop - newOverBottom;
  1184. // element is initially over bottom of within
  1185. } else if ( overBottom > 0 && overTop <= 0 ) {
  1186. position.top = withinOffset;
  1187. // element is initially over both top and bottom of within
  1188. } else {
  1189. if ( overTop > overBottom ) {
  1190. position.top = withinOffset + outerHeight - data.collisionHeight;
  1191. } else {
  1192. position.top = withinOffset;
  1193. }
  1194. }
  1195. // too far up -> align with top
  1196. } else if ( overTop > 0 ) {
  1197. position.top += overTop;
  1198. // too far down -> align with bottom edge
  1199. } else if ( overBottom > 0 ) {
  1200. position.top -= overBottom;
  1201. // adjust based on position and margin
  1202. } else {
  1203. position.top = max( position.top - collisionPosTop, position.top );
  1204. }
  1205. }
  1206. },
  1207. flip: {
  1208. left: function( position, data ) {
  1209. var within = data.within,
  1210. withinOffset = within.offset.left + within.scrollLeft,
  1211. outerWidth = within.width,
  1212. offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
  1213. collisionPosLeft = position.left - data.collisionPosition.marginLeft,
  1214. overLeft = collisionPosLeft - offsetLeft,
  1215. overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
  1216. myOffset = data.my[ 0 ] === "left" ?
  1217. -data.elemWidth :
  1218. data.my[ 0 ] === "right" ?
  1219. data.elemWidth :
  1220. 0,
  1221. atOffset = data.at[ 0 ] === "left" ?
  1222. data.targetWidth :
  1223. data.at[ 0 ] === "right" ?
  1224. -data.targetWidth :
  1225. 0,
  1226. offset = -2 * data.offset[ 0 ],
  1227. newOverRight,
  1228. newOverLeft;
  1229. if ( overLeft < 0 ) {
  1230. newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
  1231. if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
  1232. position.left += myOffset + atOffset + offset;
  1233. }
  1234. }
  1235. else if ( overRight > 0 ) {
  1236. newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
  1237. if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
  1238. position.left += myOffset + atOffset + offset;
  1239. }
  1240. }
  1241. },
  1242. top: function( position, data ) {
  1243. var within = data.within,
  1244. withinOffset = within.offset.top + within.scrollTop,
  1245. outerHeight = within.height,
  1246. offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
  1247. collisionPosTop = position.top - data.collisionPosition.marginTop,
  1248. overTop = collisionPosTop - offsetTop,
  1249. overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
  1250. top = data.my[ 1 ] === "top",
  1251. myOffset = top ?
  1252. -data.elemHeight :
  1253. data.my[ 1 ] === "bottom" ?
  1254. data.elemHeight :
  1255. 0,
  1256. atOffset = data.at[ 1 ] === "top" ?
  1257. data.targetHeight :
  1258. data.at[ 1 ] === "bottom" ?
  1259. -data.targetHeight :
  1260. 0,
  1261. offset = -2 * data.offset[ 1 ],
  1262. newOverTop,
  1263. newOverBottom;
  1264. if ( overTop < 0 ) {
  1265. newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
  1266. if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
  1267. position.top += myOffset + atOffset + offset;
  1268. }
  1269. }
  1270. else if ( overBottom > 0 ) {
  1271. newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
  1272. if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
  1273. position.top += myOffset + atOffset + offset;
  1274. }
  1275. }
  1276. }
  1277. },
  1278. flipfit: {
  1279. left: function() {
  1280. $.ui.position.flip.left.apply( this, arguments );
  1281. $.ui.position.fit.left.apply( this, arguments );
  1282. },
  1283. top: function() {
  1284. $.ui.position.flip.top.apply( this, arguments );
  1285. $.ui.position.fit.top.apply( this, arguments );
  1286. }
  1287. }
  1288. };
  1289. // fraction support test
  1290. (function () {
  1291. var testElement, testElementParent, testElementStyle, offsetLeft, i,
  1292. body = document.getElementsByTagName( "body" )[ 0 ],
  1293. div = document.createElement( "div" );
  1294. //Create a "fake body" for testing based on method used in jQuery.support
  1295. testElement = document.createElement( body ? "div" : "body" );
  1296. testElementStyle = {
  1297. visibility: "hidden",
  1298. width: 0,
  1299. height: 0,
  1300. border: 0,
  1301. margin: 0,
  1302. background: "none"
  1303. };
  1304. if ( body ) {
  1305. $.extend( testElementStyle, {
  1306. position: "absolute",
  1307. left: "-1000px",
  1308. top: "-1000px"
  1309. });
  1310. }
  1311. for ( i in testElementStyle ) {
  1312. testElement.style[ i ] = testElementStyle[ i ];
  1313. }
  1314. testElement.appendChild( div );
  1315. testElementParent = body || document.documentElement;
  1316. testElementParent.insertBefore( testElement, testElementParent.firstChild );
  1317. div.style.cssText = "position: absolute; left: 10.7432222px;";
  1318. offsetLeft = $( div ).offset().left;
  1319. $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
  1320. testElement.innerHTML = "";
  1321. testElementParent.removeChild( testElement );
  1322. })();
  1323. // DEPRECATED
  1324. if ( $.uiBackCompat !== false ) {
  1325. // offset option
  1326. (function( $ ) {
  1327. var _position = $.fn.position;
  1328. $.fn.position = function( options ) {
  1329. if ( !options || !options.offset ) {
  1330. return _position.call( this, options );
  1331. }
  1332. var offset = options.offset.split( " " ),
  1333. at = options.at.split( " " );
  1334. if ( offset.length === 1 ) {
  1335. offset[ 1 ] = offset[ 0 ];
  1336. }
  1337. if ( /^\d/.test( offset[ 0 ] ) ) {
  1338. offset[ 0 ] = "+" + offset[ 0 ];
  1339. }
  1340. if ( /^\d/.test( offset[ 1 ] ) ) {
  1341. offset[ 1 ] = "+" + offset[ 1 ];
  1342. }
  1343. if ( at.length === 1 ) {
  1344. if ( /left|center|right/.test( at[ 0 ] ) ) {
  1345. at[ 1 ] = "center";
  1346. } else {
  1347. at[ 1 ] = at[ 0 ];
  1348. at[ 0 ] = "center";
  1349. }
  1350. }
  1351. return _position.call( this, $.extend( options, {
  1352. at: at[ 0 ] + offset[ 0 ] + " " + at[ 1 ] + offset[ 1 ],
  1353. offset: undefined
  1354. } ) );
  1355. };
  1356. }( jQuery ) );
  1357. }
  1358. }( jQuery ) );
  1359. (function( $, undefined ) {
  1360. $.widget("ui.draggable", $.ui.mouse, {
  1361. version: "1.9.2",
  1362. widgetEventPrefix: "drag",
  1363. options: {
  1364. addClasses: true,
  1365. appendTo: "parent",
  1366. axis: false,
  1367. connectToSortable: false,
  1368. containment: false,
  1369. cursor: "auto",
  1370. cursorAt: false,
  1371. grid: false,
  1372. handle: false,
  1373. helper: "original",
  1374. iframeFix: false,
  1375. opacity: false,
  1376. refreshPositions: false,
  1377. revert: false,
  1378. revertDuration: 500,
  1379. scope: "default",
  1380. scroll: true,
  1381. scrollSensitivity: 20,
  1382. scrollSpeed: 20,
  1383. snap: false,
  1384. snapMode: "both",
  1385. snapTolerance: 20,
  1386. stack: false,
  1387. zIndex: false
  1388. },
  1389. _create: function() {
  1390. if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
  1391. this.element[0].style.position = 'relative';
  1392. (this.options.addClasses && this.element.addClass("ui-draggable"));
  1393. (this.options.disabled && this.element.addClass("ui-draggable-disabled"));
  1394. this._mouseInit();
  1395. },
  1396. _destroy: function() {
  1397. this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
  1398. this._mouseDestroy();
  1399. },
  1400. _mouseCapture: function(event) {
  1401. var o = this.options;
  1402. // among others, prevent a drag on a resizable-handle
  1403. if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
  1404. return false;
  1405. //Quit if we're not on a valid handle
  1406. this.handle = this._getHandle(event);
  1407. if (!this.handle)
  1408. return false;
  1409. $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
  1410. $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
  1411. .css({
  1412. width: this.offsetWidth+"px", height: this.offsetHeight+"px",
  1413. position: "absolute", opacity: "0.001", zIndex: 1000
  1414. })
  1415. .css($(this).offset())
  1416. .appendTo("body");
  1417. });
  1418. return true;
  1419. },
  1420. _mouseStart: function(event) {
  1421. var o = this.options;
  1422. //Create and append the visible helper
  1423. this.helper = this._createHelper(event);
  1424. this.helper.addClass("ui-draggable-dragging");
  1425. //Cache the helper size
  1426. this._cacheHelperProportions();
  1427. //If ddmanager is used for droppables, set the global draggable
  1428. if($.ui.ddmanager)
  1429. $.ui.ddmanager.current = this;
  1430. /*
  1431. * - Position generation -
  1432. * This block generates everything position related - it's the core of draggables.
  1433. */
  1434. //Cache the margins of the original element
  1435. this._cacheMargins();
  1436. //Store the helper's css position
  1437. this.cssPosition = this.helper.css("position");
  1438. this.scrollParent = this.helper.scrollParent();
  1439. //The element's absolute position on the page minus margins
  1440. this.offset = this.positionAbs = this.element.offset();
  1441. this.offset = {
  1442. top: this.offset.top - this.margins.top,
  1443. left: this.offset.left - this.margins.left
  1444. };
  1445. $.extend(this.offset, {
  1446. click: { //Where the click happened, relative to the element
  1447. left: event.pageX - this.offset.left,
  1448. top: event.pageY - this.offset.top
  1449. },
  1450. parent: this._getParentOffset(),
  1451. relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
  1452. });
  1453. //Generate the original position
  1454. this.originalPosition = this.position = this._generatePosition(event);
  1455. this.originalPageX = event.pageX;
  1456. this.originalPageY = event.pageY;
  1457. //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
  1458. (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
  1459. //Set a containment if given in the options
  1460. if(o.containment)
  1461. this._setContainment();
  1462. //Trigger event + callbacks
  1463. if(this._trigger("start", event) === false) {
  1464. this._clear();
  1465. return false;
  1466. }
  1467. //Recache the helper size
  1468. this._cacheHelperProportions();
  1469. //Prepare the droppable offsets
  1470. if ($.ui.ddmanager && !o.dropBehaviour)
  1471. $.ui.ddmanager.prepareOffsets(this, event);
  1472. this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
  1473. //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
  1474. if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event);
  1475. return true;
  1476. },
  1477. _mouseDrag: function(event, noPropagation) {
  1478. //Compute the helpers position
  1479. this.position = this._generatePosition(event);
  1480. this.positionAbs = this._convertPositionTo("absolute");
  1481. //Call plugins and callbacks and use the resulting position if something is returned
  1482. if (!noPropagation) {
  1483. var ui = this._uiHash();
  1484. if(this._trigger('drag', event, ui) === false) {
  1485. this._mouseUp({});
  1486. return false;
  1487. }
  1488. this.position = ui.position;
  1489. }
  1490. if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
  1491. if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
  1492. if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
  1493. return false;
  1494. },
  1495. _mouseStop: function(event) {
  1496. //If we are using droppables, inform the manager about the drop
  1497. var dropped = false;
  1498. if ($.ui.ddmanager && !this.options.dropBehaviour)
  1499. dropped = $.ui.ddmanager.drop(this, event);
  1500. //if a drop comes from outside (a sortable)
  1501. if(this.dropped) {
  1502. dropped = this.dropped;
  1503. this.dropped = false;
  1504. }
  1505. //if the original element is no longer in the DOM don't bother to continue (see #8269)
  1506. var element = this.element[0], elementInDom = false;
  1507. while ( element && (element = element.parentNode) ) {
  1508. if (element == document ) {
  1509. elementInDom = true;
  1510. }
  1511. }
  1512. if ( !elementInDom && this.options.helper === "original" )
  1513. return false;
  1514. 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))) {
  1515. var that = this;
  1516. $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
  1517. if(that._trigger("stop", event) !== false) {
  1518. that._clear();
  1519. }
  1520. });
  1521. } else {
  1522. if(this._trigger("stop", event) !== false) {
  1523. this._clear();
  1524. }
  1525. }
  1526. return false;
  1527. },
  1528. _mouseUp: function(event) {
  1529. //Remove frame helpers
  1530. $("div.ui-draggable-iframeFix").each(function() {
  1531. this.parentNode.removeChild(this);
  1532. });
  1533. //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
  1534. if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event);
  1535. return $.ui.mouse.prototype._mouseUp.call(this, event);
  1536. },
  1537. cancel: function() {
  1538. if(this.helper.is(".ui-draggable-dragging")) {
  1539. this._mouseUp({});
  1540. } else {
  1541. this._clear();
  1542. }
  1543. return this;
  1544. },
  1545. _getHandle: function(event) {
  1546. var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
  1547. $(this.options.handle, this.element)
  1548. .find("*")
  1549. .andSelf()
  1550. .each(function() {
  1551. if(this == event.target) handle = true;
  1552. });
  1553. return handle;
  1554. },
  1555. _createHelper: function(event) {
  1556. var o = this.options;
  1557. var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element);
  1558. if(!helper.parents('body').length)
  1559. helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
  1560. if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
  1561. helper.css("position", "absolute");
  1562. return helper;
  1563. },
  1564. _adjustOffsetFromHelper: function(obj) {
  1565. if (typeof obj == 'string') {
  1566. obj = obj.split(' ');
  1567. }
  1568. if ($.isArray(obj)) {
  1569. obj = {left: +obj[0], top: +obj[1] || 0};
  1570. }
  1571. if ('left' in obj) {
  1572. this.offset.click.left = obj.left + this.margins.left;
  1573. }
  1574. if ('right' in obj) {
  1575. this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
  1576. }
  1577. if ('top' in obj) {
  1578. this.offset.click.top = obj.top + this.margins.top;
  1579. }
  1580. if ('bottom' in obj) {
  1581. this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
  1582. }
  1583. },
  1584. _getParentOffset: function() {
  1585. //Get the offsetParent and cache its position
  1586. this.offsetParent = this.helper.offsetParent();
  1587. var po = this.offsetParent.offset();
  1588. // This is a special case where we need to modify a offset calculated on start, since the following happened:
  1589. // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
  1590. // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
  1591. // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
  1592. if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
  1593. po.left += this.scrollParent.scrollLeft();
  1594. po.top += this.scrollParent.scrollTop();
  1595. }
  1596. if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
  1597. || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix
  1598. po = { top: 0, left: 0 };
  1599. return {
  1600. top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
  1601. left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
  1602. };
  1603. },
  1604. _getRelativeOffset: function() {
  1605. if(this.cssPosition == "relative") {
  1606. var p = this.element.position();
  1607. return {
  1608. top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
  1609. left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
  1610. };
  1611. } else {
  1612. return { top: 0, left: 0 };
  1613. }
  1614. },
  1615. _cacheMargins: function() {
  1616. this.margins = {
  1617. left: (parseInt(this.element.css("marginLeft"),10) || 0),
  1618. top: (parseInt(this.element.css("marginTop"),10) || 0),
  1619. right: (parseInt(this.element.css("marginRight"),10) || 0),
  1620. bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
  1621. };
  1622. },
  1623. _cacheHelperProportions: function() {
  1624. this.helperProportions = {
  1625. width: this.helper.outerWidth(),
  1626. height: this.helper.outerHeight()
  1627. };
  1628. },
  1629. _setContainment: function() {
  1630. var o = this.options;
  1631. if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
  1632. if(o.containment == 'document' || o.containment == 'window') this.containment = [
  1633. o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
  1634. o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
  1635. (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
  1636. (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
  1637. ];
  1638. if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
  1639. var c = $(o.containment);
  1640. var ce = c[0]; if(!ce) return;
  1641. var co = c.offset();
  1642. var over = ($(ce).css("overflow") != 'hidden');
  1643. this.containment = [
  1644. (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
  1645. (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
  1646. (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,
  1647. (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
  1648. ];
  1649. this.relative_container = c;
  1650. } else if(o.containment.constructor == Array) {
  1651. this.containment = o.containment;
  1652. }
  1653. },
  1654. _convertPositionTo: function(d, pos) {
  1655. if(!pos) pos = this.position;
  1656. var mod = d == "absolute" ? 1 : -1;
  1657. 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);
  1658. return {
  1659. top: (
  1660. pos.top // The absolute mouse position
  1661. + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
  1662. + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
  1663. - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
  1664. ),
  1665. left: (
  1666. pos.left // The absolute mouse position
  1667. + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
  1668. + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
  1669. - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
  1670. )
  1671. };
  1672. },
  1673. _generatePosition: function(event) {
  1674. 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);
  1675. var pageX = event.pageX;
  1676. var pageY = event.pageY;
  1677. /*
  1678. * - Position constraining -
  1679. * Constrain the position to a mix of grid, containment.
  1680. */
  1681. if(this.originalPosition) { //If we are not dragging yet, we won't check for options
  1682. var containment;
  1683. if(this.containment) {
  1684. if (this.relative_container){
  1685. var co = this.relative_container.offset();
  1686. containment = [ this.containment[0] + co.left,
  1687. this.containment[1] + co.top,
  1688. this.containment[2] + co.left,
  1689. this.containment[3] + co.top ];
  1690. }
  1691. else {
  1692. containment = this.containment;
  1693. }
  1694. if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left;
  1695. if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top;
  1696. if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left;
  1697. if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top;
  1698. }
  1699. if(o.grid) {
  1700. //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
  1701. var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
  1702. 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;
  1703. var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
  1704. 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;
  1705. }
  1706. }
  1707. return {
  1708. top: (
  1709. pageY // The absolute mouse position
  1710. - this.offset.click.top // Click offset (relative to the element)
  1711. - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
  1712. - this.offset.parent.top // The offsetParent's offset without borders (offset + border)
  1713. + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
  1714. ),
  1715. left: (
  1716. pageX // The absolute mouse position
  1717. - this.offset.click.left // Click offset (relative to the element)
  1718. - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
  1719. - this.offset.parent.left // The offsetParent's offset without borders (offset + border)
  1720. + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
  1721. )
  1722. };
  1723. },
  1724. _clear: function() {
  1725. this.helper.removeClass("ui-draggable-dragging");
  1726. if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
  1727. //if($.ui.ddmanager) $.ui.ddmanager.current = null;
  1728. this.helper = null;
  1729. this.cancelHelperRemoval = false;
  1730. },
  1731. // From now on bulk stuff - mainly helpers
  1732. _trigger: function(type, event, ui) {
  1733. ui = ui || this._uiHash();
  1734. $.ui.plugin.call(this, type, [event, ui]);
  1735. if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
  1736. return $.Widget.prototype._trigger.call(this, type, event, ui);
  1737. },
  1738. plugins: {},
  1739. _uiHash: function(event) {
  1740. return {
  1741. helper: this.helper,
  1742. position: this.position,
  1743. originalPosition: this.originalPosition,
  1744. offset: this.positionAbs
  1745. };
  1746. }
  1747. });
  1748. $.ui.plugin.add("draggable", "connectToSortable", {
  1749. start: function(event, ui) {
  1750. var inst = $(this).data("draggable"), o = inst.options,
  1751. uiSortable = $.extend({}, ui, { item: inst.element });
  1752. inst.sortables = [];
  1753. $(o.connectToSortable).each(function() {
  1754. var sortable = $.data(this, 'sortable');
  1755. if (sortable && !sortable.options.disabled) {
  1756. inst.sortables.push({
  1757. instance: sortable,
  1758. shouldRevert: sortable.options.revert
  1759. });
  1760. 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).
  1761. sortable._trigger("activate", event, uiSortable);
  1762. }
  1763. });
  1764. },
  1765. stop: function(event, ui) {
  1766. //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
  1767. var inst = $(this).data("draggable"),
  1768. uiSortable = $.extend({}, ui, { item: inst.element });
  1769. $.each(inst.sortables, function() {
  1770. if(this.instance.isOver) {
  1771. this.instance.isOver = 0;
  1772. inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
  1773. this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
  1774. //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
  1775. if(this.shouldRevert) this.instance.options.revert = true;
  1776. //Trigger the stop of the sortable
  1777. this.instance._mouseStop(event);
  1778. this.instance.options.helper = this.instance.options._helper;
  1779. //If the helper has been the original item, restore properties in the sortable
  1780. if(inst.options.helper == 'original')
  1781. this.instance.currentItem.css({ top: 'auto', left: 'auto' });
  1782. } else {
  1783. this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
  1784. this.instance._trigger("deactivate", event, uiSortable);
  1785. }
  1786. });
  1787. },
  1788. drag: function(event, ui) {
  1789. var inst = $(this).data("draggable"), that = this;
  1790. var checkPos = function(o) {
  1791. var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
  1792. var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
  1793. var itemHeight = o.height, itemWidth = o.width;
  1794. var itemTop = o.top, itemLeft = o.left;
  1795. return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
  1796. };
  1797. $.each(inst.sortables, function(i) {
  1798. var innermostIntersecting = false;
  1799. var thisSortable = this;
  1800. //Copy over some variables to allow calling the sortable's native _intersectsWith
  1801. this.instance.positionAbs = inst.positionAbs;
  1802. this.instance.helperProportions = inst.helperProportions;
  1803. this.instance.offset.click = inst.offset.click;
  1804. if(this.instance._intersectsWith(this.instance.containerCache)) {
  1805. innermostIntersecting = true;
  1806. $.each(inst.sortables, function () {
  1807. this.instance.positionAbs = inst.positionAbs;
  1808. this.instance.helperProportions = inst.helperProportions;
  1809. this.instance.offset.click = inst.offset.click;
  1810. if (this != thisSortable
  1811. && this.instance._intersectsWith(this.instance.containerCache)
  1812. && $.ui.contains(thisSortable.instance.element[0], this.instance.element[0]))
  1813. innermostIntersecting = false;
  1814. return innermostIntersecting;
  1815. });
  1816. }
  1817. if(innermostIntersecting) {
  1818. //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
  1819. if(!this.instance.isOver) {
  1820. this.instance.isOver = 1;
  1821. //Now we fake the start of dragging for the sortable instance,
  1822. //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
  1823. //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)
  1824. this.instance.currentItem = $(that).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true);
  1825. this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
  1826. this.instance.options.helper = function() { return ui.helper[0]; };
  1827. event.target = this.instance.currentItem[0];
  1828. this.instance._mouseCapture(event, true);
  1829. this.instance._mouseStart(event, true, true);
  1830. //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
  1831. this.instance.offset.click.top = inst.offset.click.top;
  1832. this.instance.offset.click.left = inst.offset.click.left;
  1833. this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
  1834. this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
  1835. inst._trigger("toSortable", event);
  1836. inst.dropped = this.instance.element; //draggable revert needs that
  1837. //hack so receive/update callbacks work (mostly)
  1838. inst.currentItem = inst.element;
  1839. this.instance.fromOutside = inst;
  1840. }
  1841. //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
  1842. if(this.instance.currentItem) this.instance._mouseDrag(event);
  1843. } else {
  1844. //If it doesn't intersect with the sortable, and it intersected before,
  1845. //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
  1846. if(this.instance.isOver) {
  1847. this.instance.isOver = 0;
  1848. this.instance.cancelHelperRemoval = true;
  1849. //Prevent reverting on this forced stop
  1850. this.instance.options.revert = false;
  1851. // The out event needs to be triggered independently
  1852. this.instance._trigger('out', event, this.instance._uiHash(this.instance));
  1853. this.instance._mouseStop(event, true);
  1854. this.instance.options.helper = this.instance.options._helper;
  1855. //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
  1856. this.instance.currentItem.remove();
  1857. if(this.instance.placeholder) this.instance.placeholder.remove();
  1858. inst._trigger("fromSortable", event);
  1859. inst.dropped = false; //draggable revert needs that
  1860. }
  1861. };
  1862. });
  1863. }
  1864. });
  1865. $.ui.plugin.add("draggable", "cursor", {
  1866. start: function(event, ui) {
  1867. var t = $('body'), o = $(this).data('draggable').options;
  1868. if (t.css("cursor")) o._cursor = t.css("cursor");
  1869. t.css("cursor", o.cursor);
  1870. },
  1871. stop: function(event, ui) {
  1872. var o = $(this).data('draggable').options;
  1873. if (o._cursor) $('body').css("cursor", o._cursor);
  1874. }
  1875. });
  1876. $.ui.plugin.add("draggable", "opacity", {
  1877. start: function(event, ui) {
  1878. var t = $(ui.helper), o = $(this).data('draggable').options;
  1879. if(t.css("opacity")) o._opacity = t.css("opacity");
  1880. t.css('opacity', o.opacity);
  1881. },
  1882. stop: function(event, ui) {
  1883. var o = $(this).data('draggable').options;
  1884. if(o._opacity) $(ui.helper).css('opacity', o._opacity);
  1885. }
  1886. });
  1887. $.ui.plugin.add("draggable", "scroll", {
  1888. start: function(event, ui) {
  1889. var i = $(this).data("draggable");
  1890. if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
  1891. },
  1892. drag: function(event, ui) {
  1893. var i = $(this).data("draggable"), o = i.options, scrolled = false;
  1894. if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
  1895. if(!o.axis || o.axis != 'x') {
  1896. if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
  1897. i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
  1898. else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
  1899. i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
  1900. }
  1901. if(!o.axis || o.axis != 'y') {
  1902. if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
  1903. i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
  1904. else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
  1905. i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
  1906. }
  1907. } else {
  1908. if(!o.axis || o.axis != 'x') {
  1909. if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
  1910. scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
  1911. else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
  1912. scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
  1913. }
  1914. if(!o.axis || o.axis != 'y') {
  1915. if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
  1916. scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
  1917. else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
  1918. scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
  1919. }
  1920. }
  1921. if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
  1922. $.ui.ddmanager.prepareOffsets(i, event);
  1923. }
  1924. });
  1925. $.ui.plugin.add("draggable", "snap", {
  1926. start: function(event, ui) {
  1927. var i = $(this).data("draggable"), o = i.options;
  1928. i.snapElements = [];
  1929. $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
  1930. var $t = $(this); var $o = $t.offset();
  1931. if(this != i.element[0]) i.snapElements.push({
  1932. item: this,
  1933. width: $t.outerWidth(), height: $t.outerHeight(),
  1934. top: $o.top, left: $o.left
  1935. });
  1936. });
  1937. },
  1938. drag: function(event, ui) {
  1939. var inst = $(this).data("draggable"), o = inst.options;
  1940. var d = o.snapTolerance;
  1941. var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
  1942. y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
  1943. for (var i = inst.snapElements.length - 1; i >= 0; i--){
  1944. var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
  1945. t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
  1946. //Yes, I know, this is insane ;)
  1947. 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))) {
  1948. 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 })));
  1949. inst.snapElements[i].snapping = false;
  1950. continue;
  1951. }
  1952. if(o.snapMode != 'inner') {
  1953. var ts = Math.abs(t - y2) <= d;
  1954. var bs = Math.abs(b - y1) <= d;
  1955. var ls = Math.abs(l - x2) <= d;
  1956. var rs = Math.abs(r - x1) <= d;
  1957. if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
  1958. if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
  1959. if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
  1960. if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
  1961. }
  1962. var first = (ts || bs || ls || rs);
  1963. if(o.snapMode != 'outer') {
  1964. var ts = Math.abs(t - y1) <= d;
  1965. var bs = Math.abs(b - y2) <= d;
  1966. var ls = Math.abs(l - x1) <= d;
  1967. var rs = Math.abs(r - x2) <= d;
  1968. if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
  1969. if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
  1970. if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
  1971. if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
  1972. }
  1973. if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
  1974. (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
  1975. inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
  1976. };
  1977. }
  1978. });
  1979. $.ui.plugin.add("draggable", "stack", {
  1980. start: function(event, ui) {
  1981. var o = $(this).data("draggable").options;
  1982. var group = $.makeArray($(o.stack)).sort(function(a,b) {
  1983. return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
  1984. });
  1985. if (!group.length) { return; }
  1986. var min = parseInt(group[0].style.zIndex) || 0;
  1987. $(group).each(function(i) {
  1988. this.style.zIndex = min + i;
  1989. });
  1990. this[0].style.zIndex = min + group.length;
  1991. }
  1992. });
  1993. $.ui.plugin.add("draggable", "zIndex", {
  1994. start: function(event, ui) {
  1995. var t = $(ui.helper), o = $(this).data("draggable").options;
  1996. if(t.css("zIndex")) o._zIndex = t.css("zIndex");
  1997. t.css('zIndex', o.zIndex);
  1998. },
  1999. stop: function(event, ui) {
  2000. var o = $(this).data("draggable").options;
  2001. if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
  2002. }
  2003. });
  2004. })(jQuery);
  2005. (function( $, undefined ) {
  2006. $.widget("ui.droppable", {
  2007. version: "1.9.2",
  2008. widgetEventPrefix: "drop",
  2009. options: {
  2010. accept: '*',
  2011. activeClass: false,
  2012. addClasses: true,
  2013. greedy: false,
  2014. hoverClass: false,
  2015. scope: 'default',
  2016. tolerance: 'intersect'
  2017. },
  2018. _create: function() {
  2019. var o = this.options, accept = o.accept;
  2020. this.isover = 0; this.isout = 1;
  2021. this.accept = $.isFunction(accept) ? accept : function(d) {
  2022. return d.is(accept);
  2023. };
  2024. //Store the droppable's proportions
  2025. this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
  2026. // Add the reference and positions to the manager
  2027. $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
  2028. $.ui.ddmanager.droppables[o.scope].push(this);
  2029. (o.addClasses && this.element.addClass("ui-droppable"));
  2030. },
  2031. _destroy: function() {
  2032. var drop = $.ui.ddmanager.droppables[this.options.scope];
  2033. for ( var i = 0; i < drop.length; i++ )
  2034. if ( drop[i] == this )
  2035. drop.splice(i, 1);
  2036. this.element.removeClass("ui-droppable ui-droppable-disabled");
  2037. },
  2038. _setOption: function(key, value) {
  2039. if(key == 'accept') {
  2040. this.accept = $.isFunction(value) ? value : function(d) {
  2041. return d.is(value);
  2042. };
  2043. }
  2044. $.Widget.prototype._setOption.apply(this, arguments);
  2045. },
  2046. _activate: function(event) {
  2047. var draggable = $.ui.ddmanager.current;
  2048. if(this.options.activeClass) this.element.addClass(this.options.activeClass);
  2049. (draggable && this._trigger('activate', event, this.ui(draggable)));
  2050. },
  2051. _deactivate: function(event) {
  2052. var draggable = $.ui.ddmanager.current;
  2053. if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
  2054. (draggable && this._trigger('deactivate', event, this.ui(draggable)));
  2055. },
  2056. _over: function(event) {
  2057. var draggable = $.ui.ddmanager.current;
  2058. if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
  2059. if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
  2060. if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
  2061. this._trigger('over', event, this.ui(draggable));
  2062. }
  2063. },
  2064. _out: function(event) {
  2065. var draggable = $.ui.ddmanager.current;
  2066. if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
  2067. if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
  2068. if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
  2069. this._trigger('out', event, this.ui(draggable));
  2070. }
  2071. },
  2072. _drop: function(event,custom) {
  2073. var draggable = custom || $.ui.ddmanager.current;
  2074. if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
  2075. var childrenIntersection = false;
  2076. this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
  2077. var inst = $.data(this, 'droppable');
  2078. if(
  2079. inst.options.greedy
  2080. && !inst.options.disabled
  2081. && inst.options.scope == draggable.options.scope
  2082. && inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element))
  2083. && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
  2084. ) { childrenIntersection = true; return false; }
  2085. });
  2086. if(childrenIntersection) return false;
  2087. if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
  2088. if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
  2089. if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
  2090. this._trigger('drop', event, this.ui(draggable));
  2091. return this.element;
  2092. }
  2093. return false;
  2094. },
  2095. ui: function(c) {
  2096. return {
  2097. draggable: (c.currentItem || c.element),
  2098. helper: c.helper,
  2099. position: c.position,
  2100. offset: c.positionAbs
  2101. };
  2102. }
  2103. });
  2104. $.ui.intersect = function(draggable, droppable, toleranceMode) {
  2105. if (!droppable.offset) return false;
  2106. var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
  2107. y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
  2108. var l = droppable.offset.left, r = l + droppable.proportions.width,
  2109. t = droppable.offset.top, b = t + droppable.proportions.height;
  2110. switch (toleranceMode) {
  2111. case 'fit':
  2112. return (l <= x1 && x2 <= r
  2113. && t <= y1 && y2 <= b);
  2114. break;
  2115. case 'intersect':
  2116. return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
  2117. && x2 - (draggable.helperProportions.width / 2) < r // Left Half
  2118. && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
  2119. && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
  2120. break;
  2121. case 'pointer':
  2122. var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
  2123. draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
  2124. isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
  2125. return isOver;
  2126. break;
  2127. case 'touch':
  2128. return (
  2129. (y1 >= t && y1 <= b) || // Top edge touching
  2130. (y2 >= t && y2 <= b) || // Bottom edge touching
  2131. (y1 < t && y2 > b) // Surrounded vertically
  2132. ) && (
  2133. (x1 >= l && x1 <= r) || // Left edge touching
  2134. (x2 >= l && x2 <= r) || // Right edge touching
  2135. (x1 < l && x2 > r) // Surrounded horizontally
  2136. );
  2137. break;
  2138. default:
  2139. return false;
  2140. break;
  2141. }
  2142. };
  2143. /*
  2144. This manager tracks offsets of draggables and droppables
  2145. */
  2146. $.ui.ddmanager = {
  2147. current: null,
  2148. droppables: { 'default': [] },
  2149. prepareOffsets: function(t, event) {
  2150. var m = $.ui.ddmanager.droppables[t.options.scope] || [];
  2151. var type = event ? event.type : null; // workaround for #2317
  2152. var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
  2153. droppablesLoop: for (var i = 0; i < m.length; i++) {
  2154. if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue; //No disabled and non-accepted
  2155. 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
  2156. m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue
  2157. if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
  2158. m[i].offset = m[i].element.offset();
  2159. m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
  2160. }
  2161. },
  2162. drop: function(draggable, event) {
  2163. var dropped = false;
  2164. $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
  2165. if(!this.options) return;
  2166. if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
  2167. dropped = this._drop.call(this, event) || dropped;
  2168. if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
  2169. this.isout = 1; this.isover = 0;
  2170. this._deactivate.call(this, event);
  2171. }
  2172. });
  2173. return dropped;
  2174. },
  2175. dragStart: function( draggable, event ) {
  2176. //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
  2177. draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
  2178. if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
  2179. });
  2180. },
  2181. drag: function(draggable, event) {
  2182. //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
  2183. if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);
  2184. //Run through all droppables and check their positions based on specific tolerance options
  2185. $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
  2186. if(this.options.disabled || this.greedyChild || !this.visible) return;
  2187. var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
  2188. var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
  2189. if(!c) return;
  2190. var parentInstance;
  2191. if (this.options.greedy) {
  2192. // find droppable parents with same scope
  2193. var scope = this.options.scope;
  2194. var parent = this.element.parents(':data(droppable)').filter(function () {
  2195. return $.data(this, 'droppable').options.scope === scope;
  2196. });
  2197. if (parent.length) {
  2198. parentInstance = $.data(parent[0], 'droppable');
  2199. parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
  2200. }
  2201. }
  2202. // we just moved into a greedy child
  2203. if (parentInstance && c == 'isover') {
  2204. parentInstance['isover'] = 0;
  2205. parentInstance['isout'] = 1;
  2206. parentInstance._out.call(parentInstance, event);
  2207. }
  2208. this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
  2209. this[c == "isover" ? "_over" : "_out"].call(this, event);
  2210. // we just moved out of a greedy child
  2211. if (parentInstance && c == 'isout') {
  2212. parentInstance['isout'] = 0;
  2213. parentInstance['isover'] = 1;
  2214. parentInstance._over.call(parentInstance, event);
  2215. }
  2216. });
  2217. },
  2218. dragStop: function( draggable, event ) {
  2219. draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
  2220. //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
  2221. if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
  2222. }
  2223. };
  2224. })(jQuery);
  2225. (function( $, undefined ) {
  2226. $.widget("ui.resizable", $.ui.mouse, {
  2227. version: "1.9.2",
  2228. widgetEventPrefix: "resize",
  2229. options: {
  2230. alsoResize: false,
  2231. animate: false,
  2232. animateDuration: "slow",
  2233. animateEasing: "swing",
  2234. aspectRatio: false,
  2235. autoHide: false,
  2236. containment: false,
  2237. ghost: false,
  2238. grid: false,
  2239. handles: "e,s,se",
  2240. helper: false,
  2241. maxHeight: null,
  2242. maxWidth: null,
  2243. minHeight: 10,
  2244. minWidth: 10,
  2245. zIndex: 1000
  2246. },
  2247. _create: function() {
  2248. var that = this, o = this.options;
  2249. this.element.addClass("ui-resizable");
  2250. $.extend(this, {
  2251. _aspectRatio: !!(o.aspectRatio),
  2252. aspectRatio: o.aspectRatio,
  2253. originalElement: this.element,
  2254. _proportionallyResizeElements: [],
  2255. _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
  2256. });
  2257. //Wrap the element if it cannot hold child nodes
  2258. if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
  2259. //Create a wrapper element and set the wrapper to the new current internal element
  2260. this.element.wrap(
  2261. $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
  2262. position: this.element.css('position'),
  2263. width: this.element.outerWidth(),
  2264. height: this.element.outerHeight(),
  2265. top: this.element.css('top'),
  2266. left: this.element.css('left')
  2267. })
  2268. );
  2269. //Overwrite the original this.element
  2270. this.element = this.element.parent().data(
  2271. "resizable", this.element.data('resizable')
  2272. );
  2273. this.elementIsWrapper = true;
  2274. //Move margins to the wrapper
  2275. this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
  2276. this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
  2277. //Prevent Safari textarea resize
  2278. this.originalResizeStyle = this.originalElement.css('resize');
  2279. this.originalElement.css('resize', 'none');
  2280. //Push the actual element to our proportionallyResize internal array
  2281. this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
  2282. // avoid IE jump (hard set the margin)
  2283. this.originalElement.css({ margin: this.originalElement.css('margin') });
  2284. // fix handlers offset
  2285. this._proportionallyResize();
  2286. }
  2287. 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' });
  2288. if(this.handles.constructor == String) {
  2289. if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
  2290. var n = this.handles.split(","); this.handles = {};
  2291. for(var i = 0; i < n.length; i++) {
  2292. var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
  2293. var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
  2294. // Apply zIndex to all handles - see #7960
  2295. axis.css({ zIndex: o.zIndex });
  2296. //TODO : What's going on here?
  2297. if ('se' == handle) {
  2298. axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
  2299. };
  2300. //Insert into internal handles object and append to element
  2301. this.handles[handle] = '.ui-resizable-'+handle;
  2302. this.element.append(axis);
  2303. }
  2304. }
  2305. this._renderAxis = function(target) {
  2306. target = target || this.element;
  2307. for(var i in this.handles) {
  2308. if(this.handles[i].constructor == String)
  2309. this.handles[i] = $(this.handles[i], this.element).show();
  2310. //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
  2311. if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
  2312. var axis = $(this.handles[i], this.element), padWrapper = 0;
  2313. //Checking the correct pad and border
  2314. padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
  2315. //The padding type i have to apply...
  2316. var padPos = [ 'padding',
  2317. /ne|nw|n/.test(i) ? 'Top' :
  2318. /se|sw|s/.test(i) ? 'Bottom' :
  2319. /^e$/.test(i) ? 'Right' : 'Left' ].join("");
  2320. target.css(padPos, padWrapper);
  2321. this._proportionallyResize();
  2322. }
  2323. //TODO: What's that good for? There's not anything to be executed left
  2324. if(!$(this.handles[i]).length)
  2325. continue;
  2326. }
  2327. };
  2328. //TODO: make renderAxis a prototype function
  2329. this._renderAxis(this.element);
  2330. this._handles = $('.ui-resizable-handle', this.element)
  2331. .disableSelection();
  2332. //Matching axis name
  2333. this._handles.mouseover(function() {
  2334. if (!that.resizing) {
  2335. if (this.className)
  2336. var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
  2337. //Axis, default = se
  2338. that.axis = axis && axis[1] ? axis[1] : 'se';
  2339. }
  2340. });
  2341. //If we want to auto hide the elements
  2342. if (o.autoHide) {
  2343. this._handles.hide();
  2344. $(this.element)
  2345. .addClass("ui-resizable-autohide")
  2346. .mouseenter(function() {
  2347. if (o.disabled) return;
  2348. $(this).removeClass("ui-resizable-autohide");
  2349. that._handles.show();
  2350. })
  2351. .mouseleave(function(){
  2352. if (o.disabled) return;
  2353. if (!that.resizing) {
  2354. $(this).addClass("ui-resizable-autohide");
  2355. that._handles.hide();
  2356. }
  2357. });
  2358. }
  2359. //Initialize the mouse interaction
  2360. this._mouseInit();
  2361. },
  2362. _destroy: function() {
  2363. this._mouseDestroy();
  2364. var _destroy = function(exp) {
  2365. $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
  2366. .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
  2367. };
  2368. //TODO: Unwrap at same DOM position
  2369. if (this.elementIsWrapper) {
  2370. _destroy(this.element);
  2371. var wrapper = this.element;
  2372. this.originalElement.css({
  2373. position: wrapper.css('position'),
  2374. width: wrapper.outerWidth(),
  2375. height: wrapper.outerHeight(),
  2376. top: wrapper.css('top'),
  2377. left: wrapper.css('left')
  2378. }).insertAfter( wrapper );
  2379. wrapper.remove();
  2380. }
  2381. this.originalElement.css('resize', this.originalResizeStyle);
  2382. _destroy(this.originalElement);
  2383. return this;
  2384. },
  2385. _mouseCapture: function(event) {
  2386. var handle = false;
  2387. for (var i in this.handles) {
  2388. if ($(this.handles[i])[0] == event.target) {
  2389. handle = true;
  2390. }
  2391. }
  2392. return !this.options.disabled && handle;
  2393. },
  2394. _mouseStart: function(event) {
  2395. var o = this.options, iniPos = this.element.position(), el = this.element;
  2396. this.resizing = true;
  2397. this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
  2398. // bugfix for http://dev.jquery.com/ticket/1749
  2399. if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
  2400. el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
  2401. }
  2402. this._renderProxy();
  2403. var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
  2404. if (o.containment) {
  2405. curleft += $(o.containment).scrollLeft() || 0;
  2406. curtop += $(o.containment).scrollTop() || 0;
  2407. }
  2408. //Store needed variables
  2409. this.offset = this.helper.offset();
  2410. this.position = { left: curleft, top: curtop };
  2411. this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
  2412. this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
  2413. this.originalPosition = { left: curleft, top: curtop };
  2414. this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
  2415. this.originalMousePosition = { left: event.pageX, top: event.pageY };
  2416. //Aspect Ratio
  2417. this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
  2418. var cursor = $('.ui-resizable-' + this.axis).css('cursor');
  2419. $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
  2420. el.addClass("ui-resizable-resizing");
  2421. this._propagate("start", event);
  2422. return true;
  2423. },
  2424. _mouseDrag: function(event) {
  2425. //Increase performance, avoid regex
  2426. var el = this.helper, o = this.options, props = {},
  2427. that = this, smp = this.originalMousePosition, a = this.axis;
  2428. var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
  2429. var trigger = this._change[a];
  2430. if (!trigger) return false;
  2431. // Calculate the attrs that will be change
  2432. var data = trigger.apply(this, [event, dx, dy]);
  2433. // Put this in the mouseDrag handler since the user can start pressing shift while resizing
  2434. this._updateVirtualBoundaries(event.shiftKey);
  2435. if (this._aspectRatio || event.shiftKey)
  2436. data = this._updateRatio(data, event);
  2437. data = this._respectSize(data, event);
  2438. // plugins callbacks need to be called first
  2439. this._propagate("resize", event);
  2440. el.css({
  2441. top: this.position.top + "px", left: this.position.left + "px",
  2442. width: this.size.width + "px", height: this.size.height + "px"
  2443. });
  2444. if (!this._helper && this._proportionallyResizeElements.length)
  2445. this._proportionallyResize();
  2446. this._updateCache(data);
  2447. // calling the user callback at the end
  2448. this._trigger('resize', event, this.ui());
  2449. return false;
  2450. },
  2451. _mouseStop: function(event) {
  2452. this.resizing = false;
  2453. var o = this.options, that = this;
  2454. if(this._helper) {
  2455. var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
  2456. soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height,
  2457. soffsetw = ista ? 0 : that.sizeDiff.width;
  2458. var s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) },
  2459. left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null,
  2460. top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null;
  2461. if (!o.animate)
  2462. this.element.css($.extend(s, { top: top, left: left }));
  2463. that.helper.height(that.size.height);
  2464. that.helper.width(that.size.width);
  2465. if (this._helper && !o.animate) this._proportionallyResize();
  2466. }
  2467. $('body').css('cursor', 'auto');
  2468. this.element.removeClass("ui-resizable-resizing");
  2469. this._propagate("stop", event);
  2470. if (this._helper) this.helper.remove();
  2471. return false;
  2472. },
  2473. _updateVirtualBoundaries: function(forceAspectRatio) {
  2474. var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b;
  2475. b = {
  2476. minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
  2477. maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
  2478. minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
  2479. maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
  2480. };
  2481. if(this._aspectRatio || forceAspectRatio) {
  2482. // We want to create an enclosing box whose aspect ration is the requested one
  2483. // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
  2484. pMinWidth = b.minHeight * this.aspectRatio;
  2485. pMinHeight = b.minWidth / this.aspectRatio;
  2486. pMaxWidth = b.maxHeight * this.aspectRatio;
  2487. pMaxHeight = b.maxWidth / this.aspectRatio;
  2488. if(pMinWidth > b.minWidth) b.minWidth = pMinWidth;
  2489. if(pMinHeight > b.minHeight) b.minHeight = pMinHeight;
  2490. if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth;
  2491. if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight;
  2492. }
  2493. this._vBoundaries = b;
  2494. },
  2495. _updateCache: function(data) {
  2496. var o = this.options;
  2497. this.offset = this.helper.offset();
  2498. if (isNumber(data.left)) this.position.left = data.left;
  2499. if (isNumber(data.top)) this.position.top = data.top;
  2500. if (isNumber(data.height)) this.size.height = data.height;
  2501. if (isNumber(data.width)) this.size.width = data.width;
  2502. },
  2503. _updateRatio: function(data, event) {
  2504. var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
  2505. if (isNumber(data.height)) data.width = (data.height * this.aspectRatio);
  2506. else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio);
  2507. if (a == 'sw') {
  2508. data.left = cpos.left + (csize.width - data.width);
  2509. data.top = null;
  2510. }
  2511. if (a == 'nw') {
  2512. data.top = cpos.top + (csize.height - data.height);
  2513. data.left = cpos.left + (csize.width - data.width);
  2514. }
  2515. return data;
  2516. },
  2517. _respectSize: function(data, event) {
  2518. var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
  2519. ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
  2520. isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
  2521. if (isminw) data.width = o.minWidth;
  2522. if (isminh) data.height = o.minHeight;
  2523. if (ismaxw) data.width = o.maxWidth;
  2524. if (ismaxh) data.height = o.maxHeight;
  2525. var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
  2526. var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
  2527. if (isminw && cw) data.left = dw - o.minWidth;
  2528. if (ismaxw && cw) data.left = dw - o.maxWidth;
  2529. if (isminh && ch) data.top = dh - o.minHeight;
  2530. if (ismaxh && ch) data.top = dh - o.maxHeight;
  2531. // fixing jump error on top/left - bug #2330
  2532. var isNotwh = !data.width && !data.height;
  2533. if (isNotwh && !data.left && data.top) data.top = null;
  2534. else if (isNotwh && !data.top && data.left) data.left = null;
  2535. return data;
  2536. },
  2537. _proportionallyResize: function() {
  2538. var o = this.options;
  2539. if (!this._proportionallyResizeElements.length) return;
  2540. var element = this.helper || this.element;
  2541. for (var i=0; i < this._proportionallyResizeElements.length; i++) {
  2542. var prel = this._proportionallyResizeElements[i];
  2543. if (!this.borderDif) {
  2544. var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
  2545. p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
  2546. this.borderDif = $.map(b, function(v, i) {
  2547. var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
  2548. return border + padding;
  2549. });
  2550. }
  2551. prel.css({
  2552. height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
  2553. width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
  2554. });
  2555. };
  2556. },
  2557. _renderProxy: function() {
  2558. var el = this.element, o = this.options;
  2559. this.elementOffset = el.offset();
  2560. if(this._helper) {
  2561. this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
  2562. // fix ie6 offset TODO: This seems broken
  2563. var ie6offset = ($.ui.ie6 ? 1 : 0),
  2564. pxyoffset = ( $.ui.ie6 ? 2 : -1 );
  2565. this.helper.addClass(this._helper).css({
  2566. width: this.element.outerWidth() + pxyoffset,
  2567. height: this.element.outerHeight() + pxyoffset,
  2568. position: 'absolute',
  2569. left: this.elementOffset.left - ie6offset +'px',
  2570. top: this.elementOffset.top - ie6offset +'px',
  2571. zIndex: ++o.zIndex //TODO: Don't modify option
  2572. });
  2573. this.helper
  2574. .appendTo("body")
  2575. .disableSelection();
  2576. } else {
  2577. this.helper = this.element;
  2578. }
  2579. },
  2580. _change: {
  2581. e: function(event, dx, dy) {
  2582. return { width: this.originalSize.width + dx };
  2583. },
  2584. w: function(event, dx, dy) {
  2585. var o = this.options, cs = this.originalSize, sp = this.originalPosition;
  2586. return { left: sp.left + dx, width: cs.width - dx };
  2587. },
  2588. n: function(event, dx, dy) {
  2589. var o = this.options, cs = this.originalSize, sp = this.originalPosition;
  2590. return { top: sp.top + dy, height: cs.height - dy };
  2591. },
  2592. s: function(event, dx, dy) {
  2593. return { height: this.originalSize.height + dy };
  2594. },
  2595. se: function(event, dx, dy) {
  2596. return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
  2597. },
  2598. sw: function(event, dx, dy) {
  2599. return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
  2600. },
  2601. ne: function(event, dx, dy) {
  2602. return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
  2603. },
  2604. nw: function(event, dx, dy) {
  2605. return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
  2606. }
  2607. },
  2608. _propagate: function(n, event) {
  2609. $.ui.plugin.call(this, n, [event, this.ui()]);
  2610. (n != "resize" && this._trigger(n, event, this.ui()));
  2611. },
  2612. plugins: {},
  2613. ui: function() {
  2614. return {
  2615. originalElement: this.originalElement,
  2616. element: this.element,
  2617. helper: this.helper,
  2618. position: this.position,
  2619. size: this.size,
  2620. originalSize: this.originalSize,
  2621. originalPosition: this.originalPosition
  2622. };
  2623. }
  2624. });
  2625. /*
  2626. * Resizable Extensions
  2627. */
  2628. $.ui.plugin.add("resizable", "alsoResize", {
  2629. start: function (event, ui) {
  2630. var that = $(this).data("resizable"), o = that.options;
  2631. var _store = function (exp) {
  2632. $(exp).each(function() {
  2633. var el = $(this);
  2634. el.data("resizable-alsoresize", {
  2635. width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
  2636. left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10)
  2637. });
  2638. });
  2639. };
  2640. if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
  2641. if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
  2642. else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
  2643. }else{
  2644. _store(o.alsoResize);
  2645. }
  2646. },
  2647. resize: function (event, ui) {
  2648. var that = $(this).data("resizable"), o = that.options, os = that.originalSize, op = that.originalPosition;
  2649. var delta = {
  2650. height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
  2651. top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0
  2652. },
  2653. _alsoResize = function (exp, c) {
  2654. $(exp).each(function() {
  2655. var el = $(this), start = $(this).data("resizable-alsoresize"), style = {},
  2656. css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left'];
  2657. $.each(css, function (i, prop) {
  2658. var sum = (start[prop]||0) + (delta[prop]||0);
  2659. if (sum && sum >= 0)
  2660. style[prop] = sum || null;
  2661. });
  2662. el.css(style);
  2663. });
  2664. };
  2665. if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
  2666. $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
  2667. }else{
  2668. _alsoResize(o.alsoResize);
  2669. }
  2670. },
  2671. stop: function (event, ui) {
  2672. $(this).removeData("resizable-alsoresize");
  2673. }
  2674. });
  2675. $.ui.plugin.add("resizable", "animate", {
  2676. stop: function(event, ui) {
  2677. var that = $(this).data("resizable"), o = that.options;
  2678. var pr = that._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
  2679. soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height,
  2680. soffsetw = ista ? 0 : that.sizeDiff.width;
  2681. var style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
  2682. left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null,
  2683. top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null;
  2684. that.element.animate(
  2685. $.extend(style, top && left ? { top: top, left: left } : {}), {
  2686. duration: o.animateDuration,
  2687. easing: o.animateEasing,
  2688. step: function() {
  2689. var data = {
  2690. width: parseInt(that.element.css('width'), 10),
  2691. height: parseInt(that.element.css('height'), 10),
  2692. top: parseInt(that.element.css('top'), 10),
  2693. left: parseInt(that.element.css('left'), 10)
  2694. };
  2695. if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
  2696. // propagating resize, and updating values for each animation step
  2697. that._updateCache(data);
  2698. that._propagate("resize", event);
  2699. }
  2700. }
  2701. );
  2702. }
  2703. });
  2704. $.ui.plugin.add("resizable", "containment", {
  2705. start: function(event, ui) {
  2706. var that = $(this).data("resizable"), o = that.options, el = that.element;
  2707. var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
  2708. if (!ce) return;
  2709. that.containerElement = $(ce);
  2710. if (/document/.test(oc) || oc == document) {
  2711. that.containerOffset = { left: 0, top: 0 };
  2712. that.containerPosition = { left: 0, top: 0 };
  2713. that.parentData = {
  2714. element: $(document), left: 0, top: 0,
  2715. width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
  2716. };
  2717. }
  2718. // i'm a node, so compute top, left, right, bottom
  2719. else {
  2720. var element = $(ce), p = [];
  2721. $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
  2722. that.containerOffset = element.offset();
  2723. that.containerPosition = element.position();
  2724. that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
  2725. var co = that.containerOffset, ch = that.containerSize.height, cw = that.containerSize.width,
  2726. width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
  2727. that.parentData = {
  2728. element: ce, left: co.left, top: co.top, width: width, height: height
  2729. };
  2730. }
  2731. },
  2732. resize: function(event, ui) {
  2733. var that = $(this).data("resizable"), o = that.options,
  2734. ps = that.containerSize, co = that.containerOffset, cs = that.size, cp = that.position,
  2735. pRatio = that._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = that.containerElement;
  2736. if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
  2737. if (cp.left < (that._helper ? co.left : 0)) {
  2738. that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));
  2739. if (pRatio) that.size.height = that.size.width / that.aspectRatio;
  2740. that.position.left = o.helper ? co.left : 0;
  2741. }
  2742. if (cp.top < (that._helper ? co.top : 0)) {
  2743. that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);
  2744. if (pRatio) that.size.width = that.size.height * that.aspectRatio;
  2745. that.position.top = that._helper ? co.top : 0;
  2746. }
  2747. that.offset.left = that.parentData.left+that.position.left;
  2748. that.offset.top = that.parentData.top+that.position.top;
  2749. var woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ),
  2750. hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );
  2751. var isParent = that.containerElement.get(0) == that.element.parent().get(0),
  2752. isOffsetRelative = /relative|absolute/.test(that.containerElement.css('position'));
  2753. if(isParent && isOffsetRelative) woset -= that.parentData.left;
  2754. if (woset + that.size.width >= that.parentData.width) {
  2755. that.size.width = that.parentData.width - woset;
  2756. if (pRatio) that.size.height = that.size.width / that.aspectRatio;
  2757. }
  2758. if (hoset + that.size.height >= that.parentData.height) {
  2759. that.size.height = that.parentData.height - hoset;
  2760. if (pRatio) that.size.width = that.size.height * that.aspectRatio;
  2761. }
  2762. },
  2763. stop: function(event, ui){
  2764. var that = $(this).data("resizable"), o = that.options, cp = that.position,
  2765. co = that.containerOffset, cop = that.containerPosition, ce = that.containerElement;
  2766. var helper = $(that.helper), ho = helper.offset(), w = helper.outerWidth() - that.sizeDiff.width, h = helper.outerHeight() - that.sizeDiff.height;
  2767. if (that._helper && !o.animate && (/relative/).test(ce.css('position')))
  2768. $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
  2769. if (that._helper && !o.animate && (/static/).test(ce.css('position')))
  2770. $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
  2771. }
  2772. });
  2773. $.ui.plugin.add("resizable", "ghost", {
  2774. start: function(event, ui) {
  2775. var that = $(this).data("resizable"), o = that.options, cs = that.size;
  2776. that.ghost = that.originalElement.clone();
  2777. that.ghost
  2778. .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
  2779. .addClass('ui-resizable-ghost')
  2780. .addClass(typeof o.ghost == 'string' ? o.ghost : '');
  2781. that.ghost.appendTo(that.helper);
  2782. },
  2783. resize: function(event, ui){
  2784. var that = $(this).data("resizable"), o = that.options;
  2785. if (that.ghost) that.ghost.css({ position: 'relative', height: that.size.height, width: that.size.width });
  2786. },
  2787. stop: function(event, ui){
  2788. var that = $(this).data("resizable"), o = that.options;
  2789. if (that.ghost && that.helper) that.helper.get(0).removeChild(that.ghost.get(0));
  2790. }
  2791. });
  2792. $.ui.plugin.add("resizable", "grid", {
  2793. resize: function(event, ui) {
  2794. 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;
  2795. o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
  2796. 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);
  2797. if (/^(se|s|e)$/.test(a)) {
  2798. that.size.width = os.width + ox;
  2799. that.size.height = os.height + oy;
  2800. }
  2801. else if (/^(ne)$/.test(a)) {
  2802. that.size.width = os.width + ox;
  2803. that.size.height = os.height + oy;
  2804. that.position.top = op.top - oy;
  2805. }
  2806. else if (/^(sw)$/.test(a)) {
  2807. that.size.width = os.width + ox;
  2808. that.size.height = os.height + oy;
  2809. that.position.left = op.left - ox;
  2810. }
  2811. else {
  2812. that.size.width = os.width + ox;
  2813. that.size.height = os.height + oy;
  2814. that.position.top = op.top - oy;
  2815. that.position.left = op.left - ox;
  2816. }
  2817. }
  2818. });
  2819. var num = function(v) {
  2820. return parseInt(v, 10) || 0;
  2821. };
  2822. var isNumber = function(value) {
  2823. return !isNaN(parseInt(value, 10));
  2824. };
  2825. })(jQuery);
  2826. (function( $, undefined ) {
  2827. $.widget("ui.selectable", $.ui.mouse, {
  2828. version: "1.9.2",
  2829. options: {
  2830. appendTo: 'body',
  2831. autoRefresh: true,
  2832. distance: 0,
  2833. filter: '*',
  2834. tolerance: 'touch'
  2835. },
  2836. _create: function() {
  2837. var that = this;
  2838. this.element.addClass("ui-selectable");
  2839. this.dragged = false;
  2840. // cache selectee children based on filter
  2841. var selectees;
  2842. this.refresh = function() {
  2843. selectees = $(that.options.filter, that.element[0]);
  2844. selectees.addClass("ui-selectee");
  2845. selectees.each(function() {
  2846. var $this = $(this);
  2847. var pos = $this.offset();
  2848. $.data(this, "selectable-item", {
  2849. element: this,
  2850. $element: $this,
  2851. left: pos.left,
  2852. top: pos.top,
  2853. right: pos.left + $this.outerWidth(),
  2854. bottom: pos.top + $this.outerHeight(),
  2855. startselected: false,
  2856. selected: $this.hasClass('ui-selected'),
  2857. selecting: $this.hasClass('ui-selecting'),
  2858. unselecting: $this.hasClass('ui-unselecting')
  2859. });
  2860. });
  2861. };
  2862. this.refresh();
  2863. this.selectees = selectees.addClass("ui-selectee");
  2864. this._mouseInit();
  2865. this.helper = $("<div class='ui-selectable-helper'></div>");
  2866. },
  2867. _destroy: function() {
  2868. this.selectees
  2869. .removeClass("ui-selectee")
  2870. .removeData("selectable-item");
  2871. this.element
  2872. .removeClass("ui-selectable ui-selectable-disabled");
  2873. this._mouseDestroy();
  2874. },
  2875. _mouseStart: function(event) {
  2876. var that = this;
  2877. this.opos = [event.pageX, event.pageY];
  2878. if (this.options.disabled)
  2879. return;
  2880. var options = this.options;
  2881. this.selectees = $(options.filter, this.element[0]);
  2882. this._trigger("start", event);
  2883. $(options.appendTo).append(this.helper);
  2884. // position helper (lasso)
  2885. this.helper.css({
  2886. "left": event.clientX,
  2887. "top": event.clientY,
  2888. "width": 0,
  2889. "height": 0
  2890. });
  2891. if (options.autoRefresh) {
  2892. this.refresh();
  2893. }
  2894. this.selectees.filter('.ui-selected').each(function() {
  2895. var selectee = $.data(this, "selectable-item");
  2896. selectee.startselected = true;
  2897. if (!event.metaKey && !event.ctrlKey) {
  2898. selectee.$element.removeClass('ui-selected');
  2899. selectee.selected = false;
  2900. selectee.$element.addClass('ui-unselecting');
  2901. selectee.unselecting = true;
  2902. // selectable UNSELECTING callback
  2903. that._trigger("unselecting", event, {
  2904. unselecting: selectee.element
  2905. });
  2906. }
  2907. });
  2908. $(event.target).parents().andSelf().each(function() {
  2909. var selectee = $.data(this, "selectable-item");
  2910. if (selectee) {
  2911. var doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass('ui-selected');
  2912. selectee.$element
  2913. .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
  2914. .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
  2915. selectee.unselecting = !doSelect;
  2916. selectee.selecting = doSelect;
  2917. selectee.selected = doSelect;
  2918. // selectable (UN)SELECTING callback
  2919. if (doSelect) {
  2920. that._trigger("selecting", event, {
  2921. selecting: selectee.element
  2922. });
  2923. } else {
  2924. that._trigger("unselecting", event, {
  2925. unselecting: selectee.element
  2926. });
  2927. }
  2928. return false;
  2929. }
  2930. });
  2931. },
  2932. _mouseDrag: function(event) {
  2933. var that = this;
  2934. this.dragged = true;
  2935. if (this.options.disabled)
  2936. return;
  2937. var options = this.options;
  2938. var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
  2939. if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
  2940. if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
  2941. this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
  2942. this.selectees.each(function() {
  2943. var selectee = $.data(this, "selectable-item");
  2944. //prevent helper from being selected if appendTo: selectable
  2945. if (!selectee || selectee.element == that.element[0])
  2946. return;
  2947. var hit = false;
  2948. if (options.tolerance == 'touch') {
  2949. hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
  2950. } else if (options.tolerance == 'fit') {
  2951. hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
  2952. }
  2953. if (hit) {
  2954. // SELECT
  2955. if (selectee.selected) {
  2956. selectee.$element.removeClass('ui-selected');
  2957. selectee.selected = false;
  2958. }
  2959. if (selectee.unselecting) {
  2960. selectee.$element.removeClass('ui-unselecting');
  2961. selectee.unselecting = false;
  2962. }
  2963. if (!selectee.selecting) {
  2964. selectee.$element.addClass('ui-selecting');
  2965. selectee.selecting = true;
  2966. // selectable SELECTING callback
  2967. that._trigger("selecting", event, {
  2968. selecting: selectee.element
  2969. });
  2970. }
  2971. } else {
  2972. // UNSELECT
  2973. if (selectee.selecting) {
  2974. if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
  2975. selectee.$element.removeClass('ui-selecting');
  2976. selectee.selecting = false;
  2977. selectee.$element.addClass('ui-selected');
  2978. selectee.selected = true;
  2979. } else {
  2980. selectee.$element.removeClass('ui-selecting');
  2981. selectee.selecting = false;
  2982. if (selectee.startselected) {
  2983. selectee.$element.addClass('ui-unselecting');
  2984. selectee.unselecting = true;
  2985. }
  2986. // selectable UNSELECTING callback
  2987. that._trigger("unselecting", event, {
  2988. unselecting: selectee.element
  2989. });
  2990. }
  2991. }
  2992. if (selectee.selected) {
  2993. if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
  2994. selectee.$element.removeClass('ui-selected');
  2995. selectee.selected = false;
  2996. selectee.$element.addClass('ui-unselecting');
  2997. selectee.unselecting = true;
  2998. // selectable UNSELECTING callback
  2999. that._trigger("unselecting", event, {
  3000. unselecting: selectee.element
  3001. });
  3002. }
  3003. }
  3004. }
  3005. });
  3006. return false;
  3007. },
  3008. _mouseStop: function(event) {
  3009. var that = this;
  3010. this.dragged = false;
  3011. var options = this.options;
  3012. $('.ui-unselecting', this.element[0]).each(function() {
  3013. var selectee = $.data(this, "selectable-item");
  3014. selectee.$element.removeClass('ui-unselecting');
  3015. selectee.unselecting = false;
  3016. selectee.startselected = false;
  3017. that._trigger("unselected", event, {
  3018. unselected: selectee.element
  3019. });
  3020. });
  3021. $('.ui-selecting', this.element[0]).each(function() {
  3022. var selectee = $.data(this, "selectable-item");
  3023. selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
  3024. selectee.selecting = false;
  3025. selectee.selected = true;
  3026. selectee.startselected = true;
  3027. that._trigger("selected", event, {
  3028. selected: selectee.element
  3029. });
  3030. });
  3031. this._trigger("stop", event);
  3032. this.helper.remove();
  3033. return false;
  3034. }
  3035. });
  3036. })(jQuery);
  3037. (function( $, undefined ) {
  3038. $.widget("ui.sortable", $.ui.mouse, {
  3039. version: "1.9.2",
  3040. widgetEventPrefix: "sort",
  3041. ready: false,
  3042. options: {
  3043. appendTo: "parent",
  3044. axis: false,
  3045. connectWith: false,
  3046. containment: false,
  3047. cursor: 'auto',
  3048. cursorAt: false,
  3049. dropOnEmpty: true,
  3050. forcePlaceholderSize: false,
  3051. forceHelperSize: false,
  3052. grid: false,
  3053. handle: false,
  3054. helper: "original",
  3055. items: '> *',
  3056. opacity: false,
  3057. placeholder: false,
  3058. revert: false,
  3059. scroll: true,
  3060. scrollSensitivity: 20,
  3061. scrollSpeed: 20,
  3062. scope: "default",
  3063. tolerance: "intersect",
  3064. zIndex: 1000
  3065. },
  3066. _create: function() {
  3067. var o = this.options;
  3068. this.containerCache = {};
  3069. this.element.addClass("ui-sortable");
  3070. //Get the items
  3071. this.refresh();
  3072. //Let's determine if the items are being displayed horizontally
  3073. 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;
  3074. //Let's determine the parent's offset
  3075. this.offset = this.element.offset();
  3076. //Initialize mouse events for interaction
  3077. this._mouseInit();
  3078. //We're ready to go
  3079. this.ready = true
  3080. },
  3081. _destroy: function() {
  3082. this.element
  3083. .removeClass("ui-sortable ui-sortable-disabled");
  3084. this._mouseDestroy();
  3085. for ( var i = this.items.length - 1; i >= 0; i-- )
  3086. this.items[i].item.removeData(this.widgetName + "-item");
  3087. return this;
  3088. },
  3089. _setOption: function(key, value){
  3090. if ( key === "disabled" ) {
  3091. this.options[ key ] = value;
  3092. this.widget().toggleClass( "ui-sortable-disabled", !!value );
  3093. } else {
  3094. // Don't call widget base _setOption for disable as it adds ui-state-disabled class
  3095. $.Widget.prototype._setOption.apply(this, arguments);
  3096. }
  3097. },
  3098. _mouseCapture: function(event, overrideHandle) {
  3099. var that = this;
  3100. if (this.reverting) {
  3101. return false;
  3102. }
  3103. if(this.options.disabled || this.options.type == 'static') return false;
  3104. //We have to refresh the items data once first
  3105. this._refreshItems(event);
  3106. //Find out if the clicked node (or one of its parents) is a actual item in this.items
  3107. var currentItem = null, nodes = $(event.target).parents().each(function() {
  3108. if($.data(this, that.widgetName + '-item') == that) {
  3109. currentItem = $(this);
  3110. return false;
  3111. }
  3112. });
  3113. if($.data(event.target, that.widgetName + '-item') == that) currentItem = $(event.target);
  3114. if(!currentItem) return false;
  3115. if(this.options.handle && !overrideHandle) {
  3116. var validHandle = false;
  3117. $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
  3118. if(!validHandle) return false;
  3119. }
  3120. this.currentItem = currentItem;
  3121. this._removeCurrentsFromItems();
  3122. return true;
  3123. },
  3124. _mouseStart: function(event, overrideHandle, noActivation) {
  3125. var o = this.options;
  3126. this.currentContainer = this;
  3127. //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
  3128. this.refreshPositions();
  3129. //Create and append the visible helper
  3130. this.helper = this._createHelper(event);
  3131. //Cache the helper size
  3132. this._cacheHelperProportions();
  3133. /*
  3134. * - Position generation -
  3135. * This block generates everything position related - it's the core of draggables.
  3136. */
  3137. //Cache the margins of the original element
  3138. this._cacheMargins();
  3139. //Get the next scrolling parent
  3140. this.scrollParent = this.helper.scrollParent();
  3141. //The element's absolute position on the page minus margins
  3142. this.offset = this.currentItem.offset();
  3143. this.offset = {
  3144. top: this.offset.top - this.margins.top,
  3145. left: this.offset.left - this.margins.left
  3146. };
  3147. $.extend(this.offset, {
  3148. click: { //Where the click happened, relative to the element
  3149. left: event.pageX - this.offset.left,
  3150. top: event.pageY - this.offset.top
  3151. },
  3152. parent: this._getParentOffset(),
  3153. relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
  3154. });
  3155. // Only after we got the offset, we can change the helper's position to absolute
  3156. // TODO: Still need to figure out a way to make relative sorting possible
  3157. this.helper.css("position", "absolute");
  3158. this.cssPosition = this.helper.css("position");
  3159. //Generate the original position
  3160. this.originalPosition = this._generatePosition(event);
  3161. this.originalPageX = event.pageX;
  3162. this.originalPageY = event.pageY;
  3163. //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
  3164. (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
  3165. //Cache the former DOM position
  3166. this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
  3167. //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
  3168. if(this.helper[0] != this.currentItem[0]) {
  3169. this.currentItem.hide();
  3170. }
  3171. //Create the placeholder
  3172. this._createPlaceholder();
  3173. //Set a containment if given in the options
  3174. if(o.containment)
  3175. this._setContainment();
  3176. if(o.cursor) { // cursor option
  3177. if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
  3178. $('body').css("cursor", o.cursor);
  3179. }
  3180. if(o.opacity) { // opacity option
  3181. if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
  3182. this.helper.css("opacity", o.opacity);
  3183. }
  3184. if(o.zIndex) { // zIndex option
  3185. if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
  3186. this.helper.css("zIndex", o.zIndex);
  3187. }
  3188. //Prepare scrolling
  3189. if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
  3190. this.overflowOffset = this.scrollParent.offset();
  3191. //Call callbacks
  3192. this._trigger("start", event, this._uiHash());
  3193. //Recache the helper size
  3194. if(!this._preserveHelperProportions)
  3195. this._cacheHelperProportions();
  3196. //Post 'activate' events to possible containers
  3197. if(!noActivation) {
  3198. for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, this._uiHash(this)); }
  3199. }
  3200. //Prepare possible droppables
  3201. if($.ui.ddmanager)
  3202. $.ui.ddmanager.current = this;
  3203. if ($.ui.ddmanager && !o.dropBehaviour)
  3204. $.ui.ddmanager.prepareOffsets(this, event);
  3205. this.dragging = true;
  3206. this.helper.addClass("ui-sortable-helper");
  3207. this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
  3208. return true;
  3209. },
  3210. _mouseDrag: function(event) {
  3211. //Compute the helpers position
  3212. this.position = this._generatePosition(event);
  3213. this.positionAbs = this._convertPositionTo("absolute");
  3214. if (!this.lastPositionAbs) {
  3215. this.lastPositionAbs = this.positionAbs;
  3216. }
  3217. //Do scrolling
  3218. if(this.options.scroll) {
  3219. var o = this.options, scrolled = false;
  3220. if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
  3221. if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
  3222. this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
  3223. else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
  3224. this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
  3225. if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
  3226. this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
  3227. else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
  3228. this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
  3229. } else {
  3230. if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
  3231. scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
  3232. else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
  3233. scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
  3234. if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
  3235. scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
  3236. else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
  3237. scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
  3238. }
  3239. if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
  3240. $.ui.ddmanager.prepareOffsets(this, event);
  3241. }
  3242. //Regenerate the absolute position used for position checks
  3243. this.positionAbs = this._convertPositionTo("absolute");
  3244. //Set the helper position
  3245. if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
  3246. if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
  3247. //Rearrange
  3248. for (var i = this.items.length - 1; i >= 0; i--) {
  3249. //Cache variables and intersection, continue if no intersection
  3250. var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
  3251. if (!intersection) continue;
  3252. // Only put the placeholder inside the current Container, skip all
  3253. // items form other containers. This works because when moving
  3254. // an item from one container to another the
  3255. // currentContainer is switched before the placeholder is moved.
  3256. //
  3257. // Without this moving items in "sub-sortables" can cause the placeholder to jitter
  3258. // beetween the outer and inner container.
  3259. if (item.instance !== this.currentContainer) continue;
  3260. if (itemElement != this.currentItem[0] //cannot intersect with itself
  3261. && this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
  3262. && !$.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
  3263. && (this.options.type == 'semi-dynamic' ? !$.contains(this.element[0], itemElement) : true)
  3264. //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
  3265. ) {
  3266. this.direction = intersection == 1 ? "down" : "up";
  3267. if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
  3268. this._rearrange(event, item);
  3269. } else {
  3270. break;
  3271. }
  3272. this._trigger("change", event, this._uiHash());
  3273. break;
  3274. }
  3275. }
  3276. //Post events to containers
  3277. this._contactContainers(event);
  3278. //Interconnect with droppables
  3279. if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
  3280. //Call callbacks
  3281. this._trigger('sort', event, this._uiHash());
  3282. this.lastPositionAbs = this.positionAbs;
  3283. return false;
  3284. },
  3285. _mouseStop: function(event, noPropagation) {
  3286. if(!event) return;
  3287. //If we are using droppables, inform the manager about the drop
  3288. if ($.ui.ddmanager && !this.options.dropBehaviour)
  3289. $.ui.ddmanager.drop(this, event);
  3290. if(this.options.revert) {
  3291. var that = this;
  3292. var cur = this.placeholder.offset();
  3293. this.reverting = true;
  3294. $(this.helper).animate({
  3295. left: cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
  3296. top: cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
  3297. }, parseInt(this.options.revert, 10) || 500, function() {
  3298. that._clear(event);
  3299. });
  3300. } else {
  3301. this._clear(event, noPropagation);
  3302. }
  3303. return false;
  3304. },
  3305. cancel: function() {
  3306. if(this.dragging) {
  3307. this._mouseUp({ target: null });
  3308. if(this.options.helper == "original")
  3309. this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
  3310. else
  3311. this.currentItem.show();
  3312. //Post deactivating events to containers
  3313. for (var i = this.containers.length - 1; i >= 0; i--){
  3314. this.containers[i]._trigger("deactivate", null, this._uiHash(this));
  3315. if(this.containers[i].containerCache.over) {
  3316. this.containers[i]._trigger("out", null, this._uiHash(this));
  3317. this.containers[i].containerCache.over = 0;
  3318. }
  3319. }
  3320. }
  3321. if (this.placeholder) {
  3322. //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
  3323. if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
  3324. if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
  3325. $.extend(this, {
  3326. helper: null,
  3327. dragging: false,
  3328. reverting: false,
  3329. _noFinalSort: null
  3330. });
  3331. if(this.domPosition.prev) {
  3332. $(this.domPosition.prev).after(this.currentItem);
  3333. } else {
  3334. $(this.domPosition.parent).prepend(this.currentItem);
  3335. }
  3336. }
  3337. return this;
  3338. },
  3339. serialize: function(o) {
  3340. var items = this._getItemsAsjQuery(o && o.connected);
  3341. var str = []; o = o || {};
  3342. $(items).each(function() {
  3343. var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
  3344. if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
  3345. });
  3346. if(!str.length && o.key) {
  3347. str.push(o.key + '=');
  3348. }
  3349. return str.join('&');
  3350. },
  3351. toArray: function(o) {
  3352. var items = this._getItemsAsjQuery(o && o.connected);
  3353. var ret = []; o = o || {};
  3354. items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
  3355. return ret;
  3356. },
  3357. /* Be careful with the following core functions */
  3358. _intersectsWith: function(item) {
  3359. var x1 = this.positionAbs.left,
  3360. x2 = x1 + this.helperProportions.width,
  3361. y1 = this.positionAbs.top,
  3362. y2 = y1 + this.helperProportions.height;
  3363. var l = item.left,
  3364. r = l + item.width,
  3365. t = item.top,
  3366. b = t + item.height;
  3367. var dyClick = this.offset.click.top,
  3368. dxClick = this.offset.click.left;
  3369. var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
  3370. if( this.options.tolerance == "pointer"
  3371. || this.options.forcePointerForContainers
  3372. || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
  3373. ) {
  3374. return isOverElement;
  3375. } else {
  3376. return (l < x1 + (this.helperProportions.width / 2) // Right Half
  3377. && x2 - (this.helperProportions.width / 2) < r // Left Half
  3378. && t < y1 + (this.helperProportions.height / 2) // Bottom Half
  3379. && y2 - (this.helperProportions.height / 2) < b ); // Top Half
  3380. }
  3381. },
  3382. _intersectsWithPointer: function(item) {
  3383. var isOverElementHeight = (this.options.axis === 'x') || $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
  3384. isOverElementWidth = (this.options.axis === 'y') || $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
  3385. isOverElement = isOverElementHeight && isOverElementWidth,
  3386. verticalDirection = this._getDragVerticalDirection(),
  3387. horizontalDirection = this._getDragHorizontalDirection();
  3388. if (!isOverElement)
  3389. return false;
  3390. return this.floating ?
  3391. ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
  3392. : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
  3393. },
  3394. _intersectsWithSides: function(item) {
  3395. var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
  3396. isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
  3397. verticalDirection = this._getDragVerticalDirection(),
  3398. horizontalDirection = this._getDragHorizontalDirection();
  3399. if (this.floating && horizontalDirection) {
  3400. return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
  3401. } else {
  3402. return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
  3403. }
  3404. },
  3405. _getDragVerticalDirection: function() {
  3406. var delta = this.positionAbs.top - this.lastPositionAbs.top;
  3407. return delta != 0 && (delta > 0 ? "down" : "up");
  3408. },
  3409. _getDragHorizontalDirection: function() {
  3410. var delta = this.positionAbs.left - this.lastPositionAbs.left;
  3411. return delta != 0 && (delta > 0 ? "right" : "left");
  3412. },
  3413. refresh: function(event) {
  3414. this._refreshItems(event);
  3415. this.refreshPositions();
  3416. return this;
  3417. },
  3418. _connectWith: function() {
  3419. var options = this.options;
  3420. return options.connectWith.constructor == String
  3421. ? [options.connectWith]
  3422. : options.connectWith;
  3423. },
  3424. _getItemsAsjQuery: function(connected) {
  3425. var items = [];
  3426. var queries = [];
  3427. var connectWith = this._connectWith();
  3428. if(connectWith && connected) {
  3429. for (var i = connectWith.length - 1; i >= 0; i--){
  3430. var cur = $(connectWith[i]);
  3431. for (var j = cur.length - 1; j >= 0; j--){
  3432. var inst = $.data(cur[j], this.widgetName);
  3433. if(inst && inst != this && !inst.options.disabled) {
  3434. 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]);
  3435. }
  3436. };
  3437. };
  3438. }
  3439. 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]);
  3440. for (var i = queries.length - 1; i >= 0; i--){
  3441. queries[i][0].each(function() {
  3442. items.push(this);
  3443. });
  3444. };
  3445. return $(items);
  3446. },
  3447. _removeCurrentsFromItems: function() {
  3448. var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
  3449. this.items = $.grep(this.items, function (item) {
  3450. for (var j=0; j < list.length; j++) {
  3451. if(list[j] == item.item[0])
  3452. return false;
  3453. };
  3454. return true;
  3455. });
  3456. },
  3457. _refreshItems: function(event) {
  3458. this.items = [];
  3459. this.containers = [this];
  3460. var items = this.items;
  3461. var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
  3462. var connectWith = this._connectWith();
  3463. if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
  3464. for (var i = connectWith.length - 1; i >= 0; i--){
  3465. var cur = $(connectWith[i]);
  3466. for (var j = cur.length - 1; j >= 0; j--){
  3467. var inst = $.data(cur[j], this.widgetName);
  3468. if(inst && inst != this && !inst.options.disabled) {
  3469. queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
  3470. this.containers.push(inst);
  3471. }
  3472. };
  3473. };
  3474. }
  3475. for (var i = queries.length - 1; i >= 0; i--) {
  3476. var targetData = queries[i][1];
  3477. var _queries = queries[i][0];
  3478. for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
  3479. var item = $(_queries[j]);
  3480. item.data(this.widgetName + '-item', targetData); // Data for target checking (mouse manager)
  3481. items.push({
  3482. item: item,
  3483. instance: targetData,
  3484. width: 0, height: 0,
  3485. left: 0, top: 0
  3486. });
  3487. };
  3488. };
  3489. },
  3490. refreshPositions: function(fast) {
  3491. //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
  3492. if(this.offsetParent && this.helper) {
  3493. this.offset.parent = this._getParentOffset();
  3494. }
  3495. for (var i = this.items.length - 1; i >= 0; i--){
  3496. var item = this.items[i];
  3497. //We ignore calculating positions of all connected containers when we're not over them
  3498. if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
  3499. continue;
  3500. var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
  3501. if (!fast) {
  3502. item.width = t.outerWidth();
  3503. item.height = t.outerHeight();
  3504. }
  3505. var p = t.offset();
  3506. item.left = p.left;
  3507. item.top = p.top;
  3508. };
  3509. if(this.options.custom && this.options.custom.refreshContainers) {
  3510. this.options.custom.refreshContainers.call(this);
  3511. } else {
  3512. for (var i = this.containers.length - 1; i >= 0; i--){
  3513. var p = this.containers[i].element.offset();
  3514. this.containers[i].containerCache.left = p.left;
  3515. this.containers[i].containerCache.top = p.top;
  3516. this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
  3517. this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
  3518. };
  3519. }
  3520. return this;
  3521. },
  3522. _createPlaceholder: function(that) {
  3523. that = that || this;
  3524. var o = that.options;
  3525. if(!o.placeholder || o.placeholder.constructor == String) {
  3526. var className = o.placeholder;
  3527. o.placeholder = {
  3528. element: function() {
  3529. var el = $(document.createElement(that.currentItem[0].nodeName))
  3530. .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
  3531. .removeClass("ui-sortable-helper")[0];
  3532. if(!className)
  3533. el.style.visibility = "hidden";
  3534. return el;
  3535. },
  3536. update: function(container, p) {
  3537. // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
  3538. // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
  3539. if(className && !o.forcePlaceholderSize) return;
  3540. //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
  3541. if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css('paddingTop')||0, 10) - parseInt(that.currentItem.css('paddingBottom')||0, 10)); };
  3542. if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css('paddingLeft')||0, 10) - parseInt(that.currentItem.css('paddingRight')||0, 10)); };
  3543. }
  3544. };
  3545. }
  3546. //Create the placeholder
  3547. that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
  3548. //Append it after the actual current item
  3549. that.currentItem.after(that.placeholder);
  3550. //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
  3551. o.placeholder.update(that, that.placeholder);
  3552. },
  3553. _contactContainers: function(event) {
  3554. // get innermost container that intersects with item
  3555. var innermostContainer = null, innermostIndex = null;
  3556. for (var i = this.containers.length - 1; i >= 0; i--){
  3557. // never consider a container that's located within the item itself
  3558. if($.contains(this.currentItem[0], this.containers[i].element[0]))
  3559. continue;
  3560. if(this._intersectsWith(this.containers[i].containerCache)) {
  3561. // if we've already found a container and it's more "inner" than this, then continue
  3562. if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0]))
  3563. continue;
  3564. innermostContainer = this.containers[i];
  3565. innermostIndex = i;
  3566. } else {
  3567. // container doesn't intersect. trigger "out" event if necessary
  3568. if(this.containers[i].containerCache.over) {
  3569. this.containers[i]._trigger("out", event, this._uiHash(this));
  3570. this.containers[i].containerCache.over = 0;
  3571. }
  3572. }
  3573. }
  3574. // if no intersecting containers found, return
  3575. if(!innermostContainer) return;
  3576. // move the item into the container if it's not there already
  3577. if(this.containers.length === 1) {
  3578. this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
  3579. this.containers[innermostIndex].containerCache.over = 1;
  3580. } else {
  3581. //When entering a new container, we will find the item with the least distance and append our item near it
  3582. var dist = 10000; var itemWithLeastDistance = null;
  3583. var posProperty = this.containers[innermostIndex].floating ? 'left' : 'top';
  3584. var sizeProperty = this.containers[innermostIndex].floating ? 'width' : 'height';
  3585. var base = this.positionAbs[posProperty] + this.offset.click[posProperty];
  3586. for (var j = this.items.length - 1; j >= 0; j--) {
  3587. if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue;
  3588. if(this.items[j].item[0] == this.currentItem[0]) continue;
  3589. var cur = this.items[j].item.offset()[posProperty];
  3590. var nearBottom = false;
  3591. if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
  3592. nearBottom = true;
  3593. cur += this.items[j][sizeProperty];
  3594. }
  3595. if(Math.abs(cur - base) < dist) {
  3596. dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
  3597. this.direction = nearBottom ? "up": "down";
  3598. }
  3599. }
  3600. if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled
  3601. return;
  3602. this.currentContainer = this.containers[innermostIndex];
  3603. itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
  3604. this._trigger("change", event, this._uiHash());
  3605. this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
  3606. //Update the placeholder
  3607. this.options.placeholder.update(this.currentContainer, this.placeholder);
  3608. this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
  3609. this.containers[innermostIndex].containerCache.over = 1;
  3610. }
  3611. },
  3612. _createHelper: function(event) {
  3613. var o = this.options;
  3614. var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
  3615. if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
  3616. $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
  3617. if(helper[0] == this.currentItem[0])
  3618. 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") };
  3619. if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
  3620. if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
  3621. return helper;
  3622. },
  3623. _adjustOffsetFromHelper: function(obj) {
  3624. if (typeof obj == 'string') {
  3625. obj = obj.split(' ');
  3626. }
  3627. if ($.isArray(obj)) {
  3628. obj = {left: +obj[0], top: +obj[1] || 0};
  3629. }
  3630. if ('left' in obj) {
  3631. this.offset.click.left = obj.left + this.margins.left;
  3632. }
  3633. if ('right' in obj) {
  3634. this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
  3635. }
  3636. if ('top' in obj) {
  3637. this.offset.click.top = obj.top + this.margins.top;
  3638. }
  3639. if ('bottom' in obj) {
  3640. this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
  3641. }
  3642. },
  3643. _getParentOffset: function() {
  3644. //Get the offsetParent and cache its position
  3645. this.offsetParent = this.helper.offsetParent();
  3646. var po = this.offsetParent.offset();
  3647. // This is a special case where we need to modify a offset calculated on start, since the following happened:
  3648. // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
  3649. // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
  3650. // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
  3651. if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
  3652. po.left += this.scrollParent.scrollLeft();
  3653. po.top += this.scrollParent.scrollTop();
  3654. }
  3655. if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
  3656. || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix
  3657. po = { top: 0, left: 0 };
  3658. return {
  3659. top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
  3660. left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
  3661. };
  3662. },
  3663. _getRelativeOffset: function() {
  3664. if(this.cssPosition == "relative") {
  3665. var p = this.currentItem.position();
  3666. return {
  3667. top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
  3668. left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
  3669. };
  3670. } else {
  3671. return { top: 0, left: 0 };
  3672. }
  3673. },
  3674. _cacheMargins: function() {
  3675. this.margins = {
  3676. left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
  3677. top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
  3678. };
  3679. },
  3680. _cacheHelperProportions: function() {
  3681. this.helperProportions = {
  3682. width: this.helper.outerWidth(),
  3683. height: this.helper.outerHeight()
  3684. };
  3685. },
  3686. _setContainment: function() {
  3687. var o = this.options;
  3688. if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
  3689. if(o.containment == 'document' || o.containment == 'window') this.containment = [
  3690. 0 - this.offset.relative.left - this.offset.parent.left,
  3691. 0 - this.offset.relative.top - this.offset.parent.top,
  3692. $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
  3693. ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
  3694. ];
  3695. if(!(/^(document|window|parent)$/).test(o.containment)) {
  3696. var ce = $(o.containment)[0];
  3697. var co = $(o.containment).offset();
  3698. var over = ($(ce).css("overflow") != 'hidden');
  3699. this.containment = [
  3700. co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
  3701. co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
  3702. 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,
  3703. 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
  3704. ];
  3705. }
  3706. },
  3707. _convertPositionTo: function(d, pos) {
  3708. if(!pos) pos = this.position;
  3709. var mod = d == "absolute" ? 1 : -1;
  3710. 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);
  3711. return {
  3712. top: (
  3713. pos.top // The absolute mouse position
  3714. + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
  3715. + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
  3716. - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
  3717. ),
  3718. left: (
  3719. pos.left // The absolute mouse position
  3720. + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
  3721. + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
  3722. - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
  3723. )
  3724. };
  3725. },
  3726. _generatePosition: function(event) {
  3727. 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);
  3728. // This is another very weird special case that only happens for relative elements:
  3729. // 1. If the css position is relative
  3730. // 2. and the scroll parent is the document or similar to the offset parent
  3731. // we have to refresh the relative offset during the scroll so there are no jumps
  3732. if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
  3733. this.offset.relative = this._getRelativeOffset();
  3734. }
  3735. var pageX = event.pageX;
  3736. var pageY = event.pageY;
  3737. /*
  3738. * - Position constraining -
  3739. * Constrain the position to a mix of grid, containment.
  3740. */
  3741. if(this.originalPosition) { //If we are not dragging yet, we won't check for options
  3742. if(this.containment) {
  3743. if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
  3744. if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
  3745. if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
  3746. if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
  3747. }
  3748. if(o.grid) {
  3749. var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
  3750. 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;
  3751. var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
  3752. 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;
  3753. }
  3754. }
  3755. return {
  3756. top: (
  3757. pageY // The absolute mouse position
  3758. - this.offset.click.top // Click offset (relative to the element)
  3759. - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
  3760. - this.offset.parent.top // The offsetParent's offset without borders (offset + border)
  3761. + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
  3762. ),
  3763. left: (
  3764. pageX // The absolute mouse position
  3765. - this.offset.click.left // Click offset (relative to the element)
  3766. - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
  3767. - this.offset.parent.left // The offsetParent's offset without borders (offset + border)
  3768. + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
  3769. )
  3770. };
  3771. },
  3772. _rearrange: function(event, i, a, hardRefresh) {
  3773. 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));
  3774. //Various things done here to improve the performance:
  3775. // 1. we create a setTimeout, that calls refreshPositions
  3776. // 2. on the instance, we have a counter variable, that get's higher after every append
  3777. // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
  3778. // 4. this lets only the last addition to the timeout stack through
  3779. this.counter = this.counter ? ++this.counter : 1;
  3780. var counter = this.counter;
  3781. this._delay(function() {
  3782. if(counter == this.counter) this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
  3783. });
  3784. },
  3785. _clear: function(event, noPropagation) {
  3786. this.reverting = false;
  3787. // We delay all events that have to be triggered to after the point where the placeholder has been removed and
  3788. // everything else normalized again
  3789. var delayedTriggers = [];
  3790. // We first have to update the dom position of the actual currentItem
  3791. // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
  3792. if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem);
  3793. this._noFinalSort = null;
  3794. if(this.helper[0] == this.currentItem[0]) {
  3795. for(var i in this._storedCSS) {
  3796. if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
  3797. }
  3798. this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
  3799. } else {
  3800. this.currentItem.show();
  3801. }
  3802. if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
  3803. 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
  3804. // Check if the items Container has Changed and trigger appropriate
  3805. // events.
  3806. if (this !== this.currentContainer) {
  3807. if(!noPropagation) {
  3808. delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
  3809. delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
  3810. delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
  3811. }
  3812. }
  3813. //Post events to containers
  3814. for (var i = this.containers.length - 1; i >= 0; i--){
  3815. if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
  3816. if(this.containers[i].containerCache.over) {
  3817. delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
  3818. this.containers[i].containerCache.over = 0;
  3819. }
  3820. }
  3821. //Do what was originally in plugins
  3822. if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
  3823. if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity
  3824. if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index
  3825. this.dragging = false;
  3826. if(this.cancelHelperRemoval) {
  3827. if(!noPropagation) {
  3828. this._trigger("beforeStop", event, this._uiHash());
  3829. for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
  3830. this._trigger("stop", event, this._uiHash());
  3831. }
  3832. this.fromOutside = false;
  3833. return false;
  3834. }
  3835. if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());
  3836. //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
  3837. this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
  3838. if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
  3839. if(!noPropagation) {
  3840. for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
  3841. this._trigger("stop", event, this._uiHash());
  3842. }
  3843. this.fromOutside = false;
  3844. return true;
  3845. },
  3846. _trigger: function() {
  3847. if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
  3848. this.cancel();
  3849. }
  3850. },
  3851. _uiHash: function(_inst) {
  3852. var inst = _inst || this;
  3853. return {
  3854. helper: inst.helper,
  3855. placeholder: inst.placeholder || $([]),
  3856. position: inst.position,
  3857. originalPosition: inst.originalPosition,
  3858. offset: inst.positionAbs,
  3859. item: inst.currentItem,
  3860. sender: _inst ? _inst.element : null
  3861. };
  3862. }
  3863. });
  3864. })(jQuery);
  3865. (function( $, undefined ) {
  3866. var uid = 0,
  3867. hideProps = {},
  3868. showProps = {};
  3869. hideProps.height = hideProps.paddingTop = hideProps.paddingBottom =
  3870. hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide";
  3871. showProps.height = showProps.paddingTop = showProps.paddingBottom =
  3872. showProps.borderTopWidth = showProps.borderBottomWidth = "show";
  3873. $.widget( "ui.accordion", {
  3874. version: "1.9.2",
  3875. options: {
  3876. active: 0,
  3877. animate: {},
  3878. collapsible: false,
  3879. event: "click",
  3880. header: "> li > :first-child,> :not(li):even",
  3881. heightStyle: "auto",
  3882. icons: {
  3883. activeHeader: "ui-icon-triangle-1-s",
  3884. header: "ui-icon-triangle-1-e"
  3885. },
  3886. // callbacks
  3887. activate: null,
  3888. beforeActivate: null
  3889. },
  3890. _create: function() {
  3891. var accordionId = this.accordionId = "ui-accordion-" +
  3892. (this.element.attr( "id" ) || ++uid),
  3893. options = this.options;
  3894. this.prevShow = this.prevHide = $();
  3895. this.element.addClass( "ui-accordion ui-widget ui-helper-reset" );
  3896. this.headers = this.element.find( options.header )
  3897. .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" );
  3898. this._hoverable( this.headers );
  3899. this._focusable( this.headers );
  3900. this.headers.next()
  3901. .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
  3902. .hide();
  3903. // don't allow collapsible: false and active: false / null
  3904. if ( !options.collapsible && (options.active === false || options.active == null) ) {
  3905. options.active = 0;
  3906. }
  3907. // handle negative values
  3908. if ( options.active < 0 ) {
  3909. options.active += this.headers.length;
  3910. }
  3911. this.active = this._findActive( options.active )
  3912. .addClass( "ui-accordion-header-active ui-state-active" )
  3913. .toggleClass( "ui-corner-all ui-corner-top" );
  3914. this.active.next()
  3915. .addClass( "ui-accordion-content-active" )
  3916. .show();
  3917. this._createIcons();
  3918. this.refresh();
  3919. // ARIA
  3920. this.element.attr( "role", "tablist" );
  3921. this.headers
  3922. .attr( "role", "tab" )
  3923. .each(function( i ) {
  3924. var header = $( this ),
  3925. headerId = header.attr( "id" ),
  3926. panel = header.next(),
  3927. panelId = panel.attr( "id" );
  3928. if ( !headerId ) {
  3929. headerId = accordionId + "-header-" + i;
  3930. header.attr( "id", headerId );
  3931. }
  3932. if ( !panelId ) {
  3933. panelId = accordionId + "-panel-" + i;
  3934. panel.attr( "id", panelId );
  3935. }
  3936. header.attr( "aria-controls", panelId );
  3937. panel.attr( "aria-labelledby", headerId );
  3938. })
  3939. .next()
  3940. .attr( "role", "tabpanel" );
  3941. this.headers
  3942. .not( this.active )
  3943. .attr({
  3944. "aria-selected": "false",
  3945. tabIndex: -1
  3946. })
  3947. .next()
  3948. .attr({
  3949. "aria-expanded": "false",
  3950. "aria-hidden": "true"
  3951. })
  3952. .hide();
  3953. // make sure at least one header is in the tab order
  3954. if ( !this.active.length ) {
  3955. this.headers.eq( 0 ).attr( "tabIndex", 0 );
  3956. } else {
  3957. this.active.attr({
  3958. "aria-selected": "true",
  3959. tabIndex: 0
  3960. })
  3961. .next()
  3962. .attr({
  3963. "aria-expanded": "true",
  3964. "aria-hidden": "false"
  3965. });
  3966. }
  3967. this._on( this.headers, { keydown: "_keydown" });
  3968. this._on( this.headers.next(), { keydown: "_panelKeyDown" });
  3969. this._setupEvents( options.event );
  3970. },
  3971. _getCreateEventData: function() {
  3972. return {
  3973. header: this.active,
  3974. content: !this.active.length ? $() : this.active.next()
  3975. };
  3976. },
  3977. _createIcons: function() {
  3978. var icons = this.options.icons;
  3979. if ( icons ) {
  3980. $( "<span>" )
  3981. .addClass( "ui-accordion-header-icon ui-icon " + icons.header )
  3982. .prependTo( this.headers );
  3983. this.active.children( ".ui-accordion-header-icon" )
  3984. .removeClass( icons.header )
  3985. .addClass( icons.activeHeader );
  3986. this.headers.addClass( "ui-accordion-icons" );
  3987. }
  3988. },
  3989. _destroyIcons: function() {
  3990. this.headers
  3991. .removeClass( "ui-accordion-icons" )
  3992. .children( ".ui-accordion-header-icon" )
  3993. .remove();
  3994. },
  3995. _destroy: function() {
  3996. var contents;
  3997. // clean up main element
  3998. this.element
  3999. .removeClass( "ui-accordion ui-widget ui-helper-reset" )
  4000. .removeAttr( "role" );
  4001. // clean up headers
  4002. this.headers
  4003. .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" )
  4004. .removeAttr( "role" )
  4005. .removeAttr( "aria-selected" )
  4006. .removeAttr( "aria-controls" )
  4007. .removeAttr( "tabIndex" )
  4008. .each(function() {
  4009. if ( /^ui-accordion/.test( this.id ) ) {
  4010. this.removeAttribute( "id" );
  4011. }
  4012. });
  4013. this._destroyIcons();
  4014. // clean up content panels
  4015. contents = this.headers.next()
  4016. .css( "display", "" )
  4017. .removeAttr( "role" )
  4018. .removeAttr( "aria-expanded" )
  4019. .removeAttr( "aria-hidden" )
  4020. .removeAttr( "aria-labelledby" )
  4021. .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" )
  4022. .each(function() {
  4023. if ( /^ui-accordion/.test( this.id ) ) {
  4024. this.removeAttribute( "id" );
  4025. }
  4026. });
  4027. if ( this.options.heightStyle !== "content" ) {
  4028. contents.css( "height", "" );
  4029. }
  4030. },
  4031. _setOption: function( key, value ) {
  4032. if ( key === "active" ) {
  4033. // _activate() will handle invalid values and update this.options
  4034. this._activate( value );
  4035. return;
  4036. }
  4037. if ( key === "event" ) {
  4038. if ( this.options.event ) {
  4039. this._off( this.headers, this.options.event );
  4040. }
  4041. this._setupEvents( value );
  4042. }
  4043. this._super( key, value );
  4044. // setting collapsible: false while collapsed; open first panel
  4045. if ( key === "collapsible" && !value && this.options.active === false ) {
  4046. this._activate( 0 );
  4047. }
  4048. if ( key === "icons" ) {
  4049. this._destroyIcons();
  4050. if ( value ) {
  4051. this._createIcons();
  4052. }
  4053. }
  4054. // #5332 - opacity doesn't cascade to positioned elements in IE
  4055. // so we need to add the disabled class to the headers and panels
  4056. if ( key === "disabled" ) {
  4057. this.headers.add( this.headers.next() )
  4058. .toggleClass( "ui-state-disabled", !!value );
  4059. }
  4060. },
  4061. _keydown: function( event ) {
  4062. if ( event.altKey || event.ctrlKey ) {
  4063. return;
  4064. }
  4065. var keyCode = $.ui.keyCode,
  4066. length = this.headers.length,
  4067. currentIndex = this.headers.index( event.target ),
  4068. toFocus = false;
  4069. switch ( event.keyCode ) {
  4070. case keyCode.RIGHT:
  4071. case keyCode.DOWN:
  4072. toFocus = this.headers[ ( currentIndex + 1 ) % length ];
  4073. break;
  4074. case keyCode.LEFT:
  4075. case keyCode.UP:
  4076. toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
  4077. break;
  4078. case keyCode.SPACE:
  4079. case keyCode.ENTER:
  4080. this._eventHandler( event );
  4081. break;
  4082. case keyCode.HOME:
  4083. toFocus = this.headers[ 0 ];
  4084. break;
  4085. case keyCode.END:
  4086. toFocus = this.headers[ length - 1 ];
  4087. break;
  4088. }
  4089. if ( toFocus ) {
  4090. $( event.target ).attr( "tabIndex", -1 );
  4091. $( toFocus ).attr( "tabIndex", 0 );
  4092. toFocus.focus();
  4093. event.preventDefault();
  4094. }
  4095. },
  4096. _panelKeyDown : function( event ) {
  4097. if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
  4098. $( event.currentTarget ).prev().focus();
  4099. }
  4100. },
  4101. refresh: function() {
  4102. var maxHeight, overflow,
  4103. heightStyle = this.options.heightStyle,
  4104. parent = this.element.parent();
  4105. if ( heightStyle === "fill" ) {
  4106. // IE 6 treats height like minHeight, so we need to turn off overflow
  4107. // in order to get a reliable height
  4108. // we use the minHeight support test because we assume that only
  4109. // browsers that don't support minHeight will treat height as minHeight
  4110. if ( !$.support.minHeight ) {
  4111. overflow = parent.css( "overflow" );
  4112. parent.css( "overflow", "hidden");
  4113. }
  4114. maxHeight = parent.height();
  4115. this.element.siblings( ":visible" ).each(function() {
  4116. var elem = $( this ),
  4117. position = elem.css( "position" );
  4118. if ( position === "absolute" || position === "fixed" ) {
  4119. return;
  4120. }
  4121. maxHeight -= elem.outerHeight( true );
  4122. });
  4123. if ( overflow ) {
  4124. parent.css( "overflow", overflow );
  4125. }
  4126. this.headers.each(function() {
  4127. maxHeight -= $( this ).outerHeight( true );
  4128. });
  4129. this.headers.next()
  4130. .each(function() {
  4131. $( this ).height( Math.max( 0, maxHeight -
  4132. $( this ).innerHeight() + $( this ).height() ) );
  4133. })
  4134. .css( "overflow", "auto" );
  4135. } else if ( heightStyle === "auto" ) {
  4136. maxHeight = 0;
  4137. this.headers.next()
  4138. .each(function() {
  4139. maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
  4140. })
  4141. .height( maxHeight );
  4142. }
  4143. },
  4144. _activate: function( index ) {
  4145. var active = this._findActive( index )[ 0 ];
  4146. // trying to activate the already active panel
  4147. if ( active === this.active[ 0 ] ) {
  4148. return;
  4149. }
  4150. // trying to collapse, simulate a click on the currently active header
  4151. active = active || this.active[ 0 ];
  4152. this._eventHandler({
  4153. target: active,
  4154. currentTarget: active,
  4155. preventDefault: $.noop
  4156. });
  4157. },
  4158. _findActive: function( selector ) {
  4159. return typeof selector === "number" ? this.headers.eq( selector ) : $();
  4160. },
  4161. _setupEvents: function( event ) {
  4162. var events = {};
  4163. if ( !event ) {
  4164. return;
  4165. }
  4166. $.each( event.split(" "), function( index, eventName ) {
  4167. events[ eventName ] = "_eventHandler";
  4168. });
  4169. this._on( this.headers, events );
  4170. },
  4171. _eventHandler: function( event ) {
  4172. var options = this.options,
  4173. active = this.active,
  4174. clicked = $( event.currentTarget ),
  4175. clickedIsActive = clicked[ 0 ] === active[ 0 ],
  4176. collapsing = clickedIsActive && options.collapsible,
  4177. toShow = collapsing ? $() : clicked.next(),
  4178. toHide = active.next(),
  4179. eventData = {
  4180. oldHeader: active,
  4181. oldPanel: toHide,
  4182. newHeader: collapsing ? $() : clicked,
  4183. newPanel: toShow
  4184. };
  4185. event.preventDefault();
  4186. if (
  4187. // click on active header, but not collapsible
  4188. ( clickedIsActive && !options.collapsible ) ||
  4189. // allow canceling activation
  4190. ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
  4191. return;
  4192. }
  4193. options.active = collapsing ? false : this.headers.index( clicked );
  4194. // when the call to ._toggle() comes after the class changes
  4195. // it causes a very odd bug in IE 8 (see #6720)
  4196. this.active = clickedIsActive ? $() : clicked;
  4197. this._toggle( eventData );
  4198. // switch classes
  4199. // corner classes on the previously active header stay after the animation
  4200. active.removeClass( "ui-accordion-header-active ui-state-active" );
  4201. if ( options.icons ) {
  4202. active.children( ".ui-accordion-header-icon" )
  4203. .removeClass( options.icons.activeHeader )
  4204. .addClass( options.icons.header );
  4205. }
  4206. if ( !clickedIsActive ) {
  4207. clicked
  4208. .removeClass( "ui-corner-all" )
  4209. .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
  4210. if ( options.icons ) {
  4211. clicked.children( ".ui-accordion-header-icon" )
  4212. .removeClass( options.icons.header )
  4213. .addClass( options.icons.activeHeader );
  4214. }
  4215. clicked
  4216. .next()
  4217. .addClass( "ui-accordion-content-active" );
  4218. }
  4219. },
  4220. _toggle: function( data ) {
  4221. var toShow = data.newPanel,
  4222. toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
  4223. // handle activating a panel during the animation for another activation
  4224. this.prevShow.add( this.prevHide ).stop( true, true );
  4225. this.prevShow = toShow;
  4226. this.prevHide = toHide;
  4227. if ( this.options.animate ) {
  4228. this._animate( toShow, toHide, data );
  4229. } else {
  4230. toHide.hide();
  4231. toShow.show();
  4232. this._toggleComplete( data );
  4233. }
  4234. toHide.attr({
  4235. "aria-expanded": "false",
  4236. "aria-hidden": "true"
  4237. });
  4238. toHide.prev().attr( "aria-selected", "false" );
  4239. // if we're switching panels, remove the old header from the tab order
  4240. // if we're opening from collapsed state, remove the previous header from the tab order
  4241. // if we're collapsing, then keep the collapsing header in the tab order
  4242. if ( toShow.length && toHide.length ) {
  4243. toHide.prev().attr( "tabIndex", -1 );
  4244. } else if ( toShow.length ) {
  4245. this.headers.filter(function() {
  4246. return $( this ).attr( "tabIndex" ) === 0;
  4247. })
  4248. .attr( "tabIndex", -1 );
  4249. }
  4250. toShow
  4251. .attr({
  4252. "aria-expanded": "true",
  4253. "aria-hidden": "false"
  4254. })
  4255. .prev()
  4256. .attr({
  4257. "aria-selected": "true",
  4258. tabIndex: 0
  4259. });
  4260. },
  4261. _animate: function( toShow, toHide, data ) {
  4262. var total, easing, duration,
  4263. that = this,
  4264. adjust = 0,
  4265. down = toShow.length &&
  4266. ( !toHide.length || ( toShow.index() < toHide.index() ) ),
  4267. animate = this.options.animate || {},
  4268. options = down && animate.down || animate,
  4269. complete = function() {
  4270. that._toggleComplete( data );
  4271. };
  4272. if ( typeof options === "number" ) {
  4273. duration = options;
  4274. }
  4275. if ( typeof options === "string" ) {
  4276. easing = options;
  4277. }
  4278. // fall back from options to animation in case of partial down settings
  4279. easing = easing || options.easing || animate.easing;
  4280. duration = duration || options.duration || animate.duration;
  4281. if ( !toHide.length ) {
  4282. return toShow.animate( showProps, duration, easing, complete );
  4283. }
  4284. if ( !toShow.length ) {
  4285. return toHide.animate( hideProps, duration, easing, complete );
  4286. }
  4287. total = toShow.show().outerHeight();
  4288. toHide.animate( hideProps, {
  4289. duration: duration,
  4290. easing: easing,
  4291. step: function( now, fx ) {
  4292. fx.now = Math.round( now );
  4293. }
  4294. });
  4295. toShow
  4296. .hide()
  4297. .animate( showProps, {
  4298. duration: duration,
  4299. easing: easing,
  4300. complete: complete,
  4301. step: function( now, fx ) {
  4302. fx.now = Math.round( now );
  4303. if ( fx.prop !== "height" ) {
  4304. adjust += fx.now;
  4305. } else if ( that.options.heightStyle !== "content" ) {
  4306. fx.now = Math.round( total - toHide.outerHeight() - adjust );
  4307. adjust = 0;
  4308. }
  4309. }
  4310. });
  4311. },
  4312. _toggleComplete: function( data ) {
  4313. var toHide = data.oldPanel;
  4314. toHide
  4315. .removeClass( "ui-accordion-content-active" )
  4316. .prev()
  4317. .removeClass( "ui-corner-top" )
  4318. .addClass( "ui-corner-all" );
  4319. // Work around for rendering bug in IE (#5421)
  4320. if ( toHide.length ) {
  4321. toHide.parent()[0].className = toHide.parent()[0].className;
  4322. }
  4323. this._trigger( "activate", null, data );
  4324. }
  4325. });
  4326. // DEPRECATED
  4327. if ( $.uiBackCompat !== false ) {
  4328. // navigation options
  4329. (function( $, prototype ) {
  4330. $.extend( prototype.options, {
  4331. navigation: false,
  4332. navigationFilter: function() {
  4333. return this.href.toLowerCase() === location.href.toLowerCase();
  4334. }
  4335. });
  4336. var _create = prototype._create;
  4337. prototype._create = function() {
  4338. if ( this.options.navigation ) {
  4339. var that = this,
  4340. headers = this.element.find( this.options.header ),
  4341. content = headers.next(),
  4342. current = headers.add( content )
  4343. .find( "a" )
  4344. .filter( this.options.navigationFilter )
  4345. [ 0 ];
  4346. if ( current ) {
  4347. headers.add( content ).each( function( index ) {
  4348. if ( $.contains( this, current ) ) {
  4349. that.options.active = Math.floor( index / 2 );
  4350. return false;
  4351. }
  4352. });
  4353. }
  4354. }
  4355. _create.call( this );
  4356. };
  4357. }( jQuery, jQuery.ui.accordion.prototype ) );
  4358. // height options
  4359. (function( $, prototype ) {
  4360. $.extend( prototype.options, {
  4361. heightStyle: null, // remove default so we fall back to old values
  4362. autoHeight: true, // use heightStyle: "auto"
  4363. clearStyle: false, // use heightStyle: "content"
  4364. fillSpace: false // use heightStyle: "fill"
  4365. });
  4366. var _create = prototype._create,
  4367. _setOption = prototype._setOption;
  4368. $.extend( prototype, {
  4369. _create: function() {
  4370. this.options.heightStyle = this.options.heightStyle ||
  4371. this._mergeHeightStyle();
  4372. _create.call( this );
  4373. },
  4374. _setOption: function( key ) {
  4375. if ( key === "autoHeight" || key === "clearStyle" || key === "fillSpace" ) {
  4376. this.options.heightStyle = this._mergeHeightStyle();
  4377. }
  4378. _setOption.apply( this, arguments );
  4379. },
  4380. _mergeHeightStyle: function() {
  4381. var options = this.options;
  4382. if ( options.fillSpace ) {
  4383. return "fill";
  4384. }
  4385. if ( options.clearStyle ) {
  4386. return "content";
  4387. }
  4388. if ( options.autoHeight ) {
  4389. return "auto";
  4390. }
  4391. }
  4392. });
  4393. }( jQuery, jQuery.ui.accordion.prototype ) );
  4394. // icon options
  4395. (function( $, prototype ) {
  4396. $.extend( prototype.options.icons, {
  4397. activeHeader: null, // remove default so we fall back to old values
  4398. headerSelected: "ui-icon-triangle-1-s"
  4399. });
  4400. var _createIcons = prototype._createIcons;
  4401. prototype._createIcons = function() {
  4402. if ( this.options.icons ) {
  4403. this.options.icons.activeHeader = this.options.icons.activeHeader ||
  4404. this.options.icons.headerSelected;
  4405. }
  4406. _createIcons.call( this );
  4407. };
  4408. }( jQuery, jQuery.ui.accordion.prototype ) );
  4409. // expanded active option, activate method
  4410. (function( $, prototype ) {
  4411. prototype.activate = prototype._activate;
  4412. var _findActive = prototype._findActive;
  4413. prototype._findActive = function( index ) {
  4414. if ( index === -1 ) {
  4415. index = false;
  4416. }
  4417. if ( index && typeof index !== "number" ) {
  4418. index = this.headers.index( this.headers.filter( index ) );
  4419. if ( index === -1 ) {
  4420. index = false;
  4421. }
  4422. }
  4423. return _findActive.call( this, index );
  4424. };
  4425. }( jQuery, jQuery.ui.accordion.prototype ) );
  4426. // resize method
  4427. jQuery.ui.accordion.prototype.resize = jQuery.ui.accordion.prototype.refresh;
  4428. // change events
  4429. (function( $, prototype ) {
  4430. $.extend( prototype.options, {
  4431. change: null,
  4432. changestart: null
  4433. });
  4434. var _trigger = prototype._trigger;
  4435. prototype._trigger = function( type, event, data ) {
  4436. var ret = _trigger.apply( this, arguments );
  4437. if ( !ret ) {
  4438. return false;
  4439. }
  4440. if ( type === "beforeActivate" ) {
  4441. ret = _trigger.call( this, "changestart", event, {
  4442. oldHeader: data.oldHeader,
  4443. oldContent: data.oldPanel,
  4444. newHeader: data.newHeader,
  4445. newContent: data.newPanel
  4446. });
  4447. } else if ( type === "activate" ) {
  4448. ret = _trigger.call( this, "change", event, {
  4449. oldHeader: data.oldHeader,
  4450. oldContent: data.oldPanel,
  4451. newHeader: data.newHeader,
  4452. newContent: data.newPanel
  4453. });
  4454. }
  4455. return ret;
  4456. };
  4457. }( jQuery, jQuery.ui.accordion.prototype ) );
  4458. // animated option
  4459. // NOTE: this only provides support for "slide", "bounceslide", and easings
  4460. // not the full $.ui.accordion.animations API
  4461. (function( $, prototype ) {
  4462. $.extend( prototype.options, {
  4463. animate: null,
  4464. animated: "slide"
  4465. });
  4466. var _create = prototype._create;
  4467. prototype._create = function() {
  4468. var options = this.options;
  4469. if ( options.animate === null ) {
  4470. if ( !options.animated ) {
  4471. options.animate = false;
  4472. } else if ( options.animated === "slide" ) {
  4473. options.animate = 300;
  4474. } else if ( options.animated === "bounceslide" ) {
  4475. options.animate = {
  4476. duration: 200,
  4477. down: {
  4478. easing: "easeOutBounce",
  4479. duration: 1000
  4480. }
  4481. };
  4482. } else {
  4483. options.animate = options.animated;
  4484. }
  4485. }
  4486. _create.call( this );
  4487. };
  4488. }( jQuery, jQuery.ui.accordion.prototype ) );
  4489. }
  4490. })( jQuery );
  4491. (function( $, undefined ) {
  4492. // used to prevent race conditions with remote data sources
  4493. var requestIndex = 0;
  4494. $.widget( "ui.autocomplete", {
  4495. version: "1.9.2",
  4496. defaultElement: "<input>",
  4497. options: {
  4498. appendTo: "body",
  4499. autoFocus: false,
  4500. delay: 300,
  4501. minLength: 1,
  4502. position: {
  4503. my: "left top",
  4504. at: "left bottom",
  4505. collision: "none"
  4506. },
  4507. source: null,
  4508. // callbacks
  4509. change: null,
  4510. close: null,
  4511. focus: null,
  4512. open: null,
  4513. response: null,
  4514. search: null,
  4515. select: null
  4516. },
  4517. pending: 0,
  4518. _create: function() {
  4519. // Some browsers only repeat keydown events, not keypress events,
  4520. // so we use the suppressKeyPress flag to determine if we've already
  4521. // handled the keydown event. #7269
  4522. // Unfortunately the code for & in keypress is the same as the up arrow,
  4523. // so we use the suppressKeyPressRepeat flag to avoid handling keypress
  4524. // events when we know the keydown event was used to modify the
  4525. // search term. #7799
  4526. var suppressKeyPress, suppressKeyPressRepeat, suppressInput;
  4527. this.isMultiLine = this._isMultiLine();
  4528. this.valueMethod = this.element[ this.element.is( "input,textarea" ) ? "val" : "text" ];
  4529. this.isNewMenu = true;
  4530. this.element
  4531. .addClass( "ui-autocomplete-input" )
  4532. .attr( "autocomplete", "off" );
  4533. this._on( this.element, {
  4534. keydown: function( event ) {
  4535. if ( this.element.prop( "readOnly" ) ) {
  4536. suppressKeyPress = true;
  4537. suppressInput = true;
  4538. suppressKeyPressRepeat = true;
  4539. return;
  4540. }
  4541. suppressKeyPress = false;
  4542. suppressInput = false;
  4543. suppressKeyPressRepeat = false;
  4544. var keyCode = $.ui.keyCode;
  4545. switch( event.keyCode ) {
  4546. case keyCode.PAGE_UP:
  4547. suppressKeyPress = true;
  4548. this._move( "previousPage", event );
  4549. break;
  4550. case keyCode.PAGE_DOWN:
  4551. suppressKeyPress = true;
  4552. this._move( "nextPage", event );
  4553. break;
  4554. case keyCode.UP:
  4555. suppressKeyPress = true;
  4556. this._keyEvent( "previous", event );
  4557. break;
  4558. case keyCode.DOWN:
  4559. suppressKeyPress = true;
  4560. this._keyEvent( "next", event );
  4561. break;
  4562. case keyCode.ENTER:
  4563. case keyCode.NUMPAD_ENTER:
  4564. // when menu is open and has focus
  4565. if ( this.menu.active ) {
  4566. // #6055 - Opera still allows the keypress to occur
  4567. // which causes forms to submit
  4568. suppressKeyPress = true;
  4569. event.preventDefault();
  4570. this.menu.select( event );
  4571. }
  4572. break;
  4573. case keyCode.TAB:
  4574. if ( this.menu.active ) {
  4575. this.menu.select( event );
  4576. }
  4577. break;
  4578. case keyCode.ESCAPE:
  4579. if ( this.menu.element.is( ":visible" ) ) {
  4580. this._value( this.term );
  4581. this.close( event );
  4582. // Different browsers have different default behavior for escape
  4583. // Single press can mean undo or clear
  4584. // Double press in IE means clear the whole form
  4585. event.preventDefault();
  4586. }
  4587. break;
  4588. default:
  4589. suppressKeyPressRepeat = true;
  4590. // search timeout should be triggered before the input value is changed
  4591. this._searchTimeout( event );
  4592. break;
  4593. }
  4594. },
  4595. keypress: function( event ) {
  4596. if ( suppressKeyPress ) {
  4597. suppressKeyPress = false;
  4598. event.preventDefault();
  4599. return;
  4600. }
  4601. if ( suppressKeyPressRepeat ) {
  4602. return;
  4603. }
  4604. // replicate some key handlers to allow them to repeat in Firefox and Opera
  4605. var keyCode = $.ui.keyCode;
  4606. switch( event.keyCode ) {
  4607. case keyCode.PAGE_UP:
  4608. this._move( "previousPage", event );
  4609. break;
  4610. case keyCode.PAGE_DOWN:
  4611. this._move( "nextPage", event );
  4612. break;
  4613. case keyCode.UP:
  4614. this._keyEvent( "previous", event );
  4615. break;
  4616. case keyCode.DOWN:
  4617. this._keyEvent( "next", event );
  4618. break;
  4619. }
  4620. },
  4621. input: function( event ) {
  4622. if ( suppressInput ) {
  4623. suppressInput = false;
  4624. event.preventDefault();
  4625. return;
  4626. }
  4627. this._searchTimeout( event );
  4628. },
  4629. focus: function() {
  4630. this.selectedItem = null;
  4631. this.previous = this._value();
  4632. },
  4633. blur: function( event ) {
  4634. if ( this.cancelBlur ) {
  4635. delete this.cancelBlur;
  4636. return;
  4637. }
  4638. clearTimeout( this.searching );
  4639. this.close( event );
  4640. this._change( event );
  4641. }
  4642. });
  4643. this._initSource();
  4644. this.menu = $( "<ul>" )
  4645. .addClass( "ui-autocomplete" )
  4646. .appendTo( this.document.find( this.options.appendTo || "body" )[ 0 ] )
  4647. .menu({
  4648. // custom key handling for now
  4649. input: $(),
  4650. // disable ARIA support, the live region takes care of that
  4651. role: null
  4652. })
  4653. .zIndex( this.element.zIndex() + 1 )
  4654. .hide()
  4655. .data( "menu" );
  4656. this._on( this.menu.element, {
  4657. mousedown: function( event ) {
  4658. // prevent moving focus out of the text field
  4659. event.preventDefault();
  4660. // IE doesn't prevent moving focus even with event.preventDefault()
  4661. // so we set a flag to know when we should ignore the blur event
  4662. this.cancelBlur = true;
  4663. this._delay(function() {
  4664. delete this.cancelBlur;
  4665. });
  4666. // clicking on the scrollbar causes focus to shift to the body
  4667. // but we can't detect a mouseup or a click immediately afterward
  4668. // so we have to track the next mousedown and close the menu if
  4669. // the user clicks somewhere outside of the autocomplete
  4670. var menuElement = this.menu.element[ 0 ];
  4671. if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
  4672. this._delay(function() {
  4673. var that = this;
  4674. this.document.one( "mousedown", function( event ) {
  4675. if ( event.target !== that.element[ 0 ] &&
  4676. event.target !== menuElement &&
  4677. !$.contains( menuElement, event.target ) ) {
  4678. that.close();
  4679. }
  4680. });
  4681. });
  4682. }
  4683. },
  4684. menufocus: function( event, ui ) {
  4685. // #7024 - Prevent accidental activation of menu items in Firefox
  4686. if ( this.isNewMenu ) {
  4687. this.isNewMenu = false;
  4688. if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
  4689. this.menu.blur();
  4690. this.document.one( "mousemove", function() {
  4691. $( event.target ).trigger( event.originalEvent );
  4692. });
  4693. return;
  4694. }
  4695. }
  4696. // back compat for _renderItem using item.autocomplete, via #7810
  4697. // TODO remove the fallback, see #8156
  4698. var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" );
  4699. if ( false !== this._trigger( "focus", event, { item: item } ) ) {
  4700. // use value to match what will end up in the input, if it was a key event
  4701. if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
  4702. this._value( item.value );
  4703. }
  4704. } else {
  4705. // Normally the input is populated with the item's value as the
  4706. // menu is navigated, causing screen readers to notice a change and
  4707. // announce the item. Since the focus event was canceled, this doesn't
  4708. // happen, so we update the live region so that screen readers can
  4709. // still notice the change and announce it.
  4710. this.liveRegion.text( item.value );
  4711. }
  4712. },
  4713. menuselect: function( event, ui ) {
  4714. // back compat for _renderItem using item.autocomplete, via #7810
  4715. // TODO remove the fallback, see #8156
  4716. var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" ),
  4717. previous = this.previous;
  4718. // only trigger when focus was lost (click on menu)
  4719. if ( this.element[0] !== this.document[0].activeElement ) {
  4720. this.element.focus();
  4721. this.previous = previous;
  4722. // #6109 - IE triggers two focus events and the second
  4723. // is asynchronous, so we need to reset the previous
  4724. // term synchronously and asynchronously :-(
  4725. this._delay(function() {
  4726. this.previous = previous;
  4727. this.selectedItem = item;
  4728. });
  4729. }
  4730. if ( false !== this._trigger( "select", event, { item: item } ) ) {
  4731. this._value( item.value );
  4732. }
  4733. // reset the term after the select event
  4734. // this allows custom select handling to work properly
  4735. this.term = this._value();
  4736. this.close( event );
  4737. this.selectedItem = item;
  4738. }
  4739. });
  4740. this.liveRegion = $( "<span>", {
  4741. role: "status",
  4742. "aria-live": "polite"
  4743. })
  4744. .addClass( "ui-helper-hidden-accessible" )
  4745. .insertAfter( this.element );
  4746. if ( $.fn.bgiframe ) {
  4747. this.menu.element.bgiframe();
  4748. }
  4749. // turning off autocomplete prevents the browser from remembering the
  4750. // value when navigating through history, so we re-enable autocomplete
  4751. // if the page is unloaded before the widget is destroyed. #7790
  4752. this._on( this.window, {
  4753. beforeunload: function() {
  4754. this.element.removeAttr( "autocomplete" );
  4755. }
  4756. });
  4757. },
  4758. _destroy: function() {
  4759. clearTimeout( this.searching );
  4760. this.element
  4761. .removeClass( "ui-autocomplete-input" )
  4762. .removeAttr( "autocomplete" );
  4763. this.menu.element.remove();
  4764. this.liveRegion.remove();
  4765. },
  4766. _setOption: function( key, value ) {
  4767. this._super( key, value );
  4768. if ( key === "source" ) {
  4769. this._initSource();
  4770. }
  4771. if ( key === "appendTo" ) {
  4772. this.menu.element.appendTo( this.document.find( value || "body" )[0] );
  4773. }
  4774. if ( key === "disabled" && value && this.xhr ) {
  4775. this.xhr.abort();
  4776. }
  4777. },
  4778. _isMultiLine: function() {
  4779. // Textareas are always multi-line
  4780. if ( this.element.is( "textarea" ) ) {
  4781. return true;
  4782. }
  4783. // Inputs are always single-line, even if inside a contentEditable element
  4784. // IE also treats inputs as contentEditable
  4785. if ( this.element.is( "input" ) ) {
  4786. return false;
  4787. }
  4788. // All other element types are determined by whether or not they're contentEditable
  4789. return this.element.prop( "isContentEditable" );
  4790. },
  4791. _initSource: function() {
  4792. var array, url,
  4793. that = this;
  4794. if ( $.isArray(this.options.source) ) {
  4795. array = this.options.source;
  4796. this.source = function( request, response ) {
  4797. response( $.ui.autocomplete.filter( array, request.term ) );
  4798. };
  4799. } else if ( typeof this.options.source === "string" ) {
  4800. url = this.options.source;
  4801. this.source = function( request, response ) {
  4802. if ( that.xhr ) {
  4803. that.xhr.abort();
  4804. }
  4805. that.xhr = $.ajax({
  4806. url: url,
  4807. data: request,
  4808. dataType: "json",
  4809. success: function( data ) {
  4810. response( data );
  4811. },
  4812. error: function() {
  4813. response( [] );
  4814. }
  4815. });
  4816. };
  4817. } else {
  4818. this.source = this.options.source;
  4819. }
  4820. },
  4821. _searchTimeout: function( event ) {
  4822. clearTimeout( this.searching );
  4823. this.searching = this._delay(function() {
  4824. // only search if the value has changed
  4825. if ( this.term !== this._value() ) {
  4826. this.selectedItem = null;
  4827. this.search( null, event );
  4828. }
  4829. }, this.options.delay );
  4830. },
  4831. search: function( value, event ) {
  4832. value = value != null ? value : this._value();
  4833. // always save the actual value, not the one passed as an argument
  4834. this.term = this._value();
  4835. if ( value.length < this.options.minLength ) {
  4836. return this.close( event );
  4837. }
  4838. if ( this._trigger( "search", event ) === false ) {
  4839. return;
  4840. }
  4841. return this._search( value );
  4842. },
  4843. _search: function( value ) {
  4844. this.pending++;
  4845. this.element.addClass( "ui-autocomplete-loading" );
  4846. this.cancelSearch = false;
  4847. this.source( { term: value }, this._response() );
  4848. },
  4849. _response: function() {
  4850. var that = this,
  4851. index = ++requestIndex;
  4852. return function( content ) {
  4853. if ( index === requestIndex ) {
  4854. that.__response( content );
  4855. }
  4856. that.pending--;
  4857. if ( !that.pending ) {
  4858. that.element.removeClass( "ui-autocomplete-loading" );
  4859. }
  4860. };
  4861. },
  4862. __response: function( content ) {
  4863. if ( content ) {
  4864. content = this._normalize( content );
  4865. }
  4866. this._trigger( "response", null, { content: content } );
  4867. if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
  4868. this._suggest( content );
  4869. this._trigger( "open" );
  4870. } else {
  4871. // use ._close() instead of .close() so we don't cancel future searches
  4872. this._close();
  4873. }
  4874. },
  4875. close: function( event ) {
  4876. this.cancelSearch = true;
  4877. this._close( event );
  4878. },
  4879. _close: function( event ) {
  4880. if ( this.menu.element.is( ":visible" ) ) {
  4881. this.menu.element.hide();
  4882. this.menu.blur();
  4883. this.isNewMenu = true;
  4884. this._trigger( "close", event );
  4885. }
  4886. },
  4887. _change: function( event ) {
  4888. if ( this.previous !== this._value() ) {
  4889. this._trigger( "change", event, { item: this.selectedItem } );
  4890. }
  4891. },
  4892. _normalize: function( items ) {
  4893. // assume all items have the right format when the first item is complete
  4894. if ( items.length && items[0].label && items[0].value ) {
  4895. return items;
  4896. }
  4897. return $.map( items, function( item ) {
  4898. if ( typeof item === "string" ) {
  4899. return {
  4900. label: item,
  4901. value: item
  4902. };
  4903. }
  4904. return $.extend({
  4905. label: item.label || item.value,
  4906. value: item.value || item.label
  4907. }, item );
  4908. });
  4909. },
  4910. _suggest: function( items ) {
  4911. var ul = this.menu.element
  4912. .empty()
  4913. .zIndex( this.element.zIndex() + 1 );
  4914. this._renderMenu( ul, items );
  4915. this.menu.refresh();
  4916. // size and position menu
  4917. ul.show();
  4918. this._resizeMenu();
  4919. ul.position( $.extend({
  4920. of: this.element
  4921. }, this.options.position ));
  4922. if ( this.options.autoFocus ) {
  4923. this.menu.next();
  4924. }
  4925. },
  4926. _resizeMenu: function() {
  4927. var ul = this.menu.element;
  4928. ul.outerWidth( Math.max(
  4929. // Firefox wraps long text (possibly a rounding bug)
  4930. // so we add 1px to avoid the wrapping (#7513)
  4931. ul.width( "" ).outerWidth() + 1,
  4932. this.element.outerWidth()
  4933. ) );
  4934. },
  4935. _renderMenu: function( ul, items ) {
  4936. var that = this;
  4937. $.each( items, function( index, item ) {
  4938. that._renderItemData( ul, item );
  4939. });
  4940. },
  4941. _renderItemData: function( ul, item ) {
  4942. return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
  4943. },
  4944. _renderItem: function( ul, item ) {
  4945. return $( "<li>" )
  4946. .append( $( "<a>" ).text( item.label ) )
  4947. .appendTo( ul );
  4948. },
  4949. _move: function( direction, event ) {
  4950. if ( !this.menu.element.is( ":visible" ) ) {
  4951. this.search( null, event );
  4952. return;
  4953. }
  4954. if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
  4955. this.menu.isLastItem() && /^next/.test( direction ) ) {
  4956. this._value( this.term );
  4957. this.menu.blur();
  4958. return;
  4959. }
  4960. this.menu[ direction ]( event );
  4961. },
  4962. widget: function() {
  4963. return this.menu.element;
  4964. },
  4965. _value: function() {
  4966. return this.valueMethod.apply( this.element, arguments );
  4967. },
  4968. _keyEvent: function( keyEvent, event ) {
  4969. if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
  4970. this._move( keyEvent, event );
  4971. // prevents moving cursor to beginning/end of the text field in some browsers
  4972. event.preventDefault();
  4973. }
  4974. }
  4975. });
  4976. $.extend( $.ui.autocomplete, {
  4977. escapeRegex: function( value ) {
  4978. return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
  4979. },
  4980. filter: function(array, term) {
  4981. var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
  4982. return $.grep( array, function(value) {
  4983. return matcher.test( value.label || value.value || value );
  4984. });
  4985. }
  4986. });
  4987. // live region extension, adding a `messages` option
  4988. // NOTE: This is an experimental API. We are still investigating
  4989. // a full solution for string manipulation and internationalization.
  4990. $.widget( "ui.autocomplete", $.ui.autocomplete, {
  4991. options: {
  4992. messages: {
  4993. noResults: "No search results.",
  4994. results: function( amount ) {
  4995. return amount + ( amount > 1 ? " results are" : " result is" ) +
  4996. " available, use up and down arrow keys to navigate.";
  4997. }
  4998. }
  4999. },
  5000. __response: function( content ) {
  5001. var message;
  5002. this._superApply( arguments );
  5003. if ( this.options.disabled || this.cancelSearch ) {
  5004. return;
  5005. }
  5006. if ( content && content.length ) {
  5007. message = this.options.messages.results( content.length );
  5008. } else {
  5009. message = this.options.messages.noResults;
  5010. }
  5011. this.liveRegion.text( message );
  5012. }
  5013. });
  5014. }( jQuery ));
  5015. (function( $, undefined ) {
  5016. var lastActive, startXPos, startYPos, clickDragged,
  5017. baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
  5018. stateClasses = "ui-state-hover ui-state-active ",
  5019. 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",
  5020. formResetHandler = function() {
  5021. var buttons = $( this ).find( ":ui-button" );
  5022. setTimeout(function() {
  5023. buttons.button( "refresh" );
  5024. }, 1 );
  5025. },
  5026. radioGroup = function( radio ) {
  5027. var name = radio.name,
  5028. form = radio.form,
  5029. radios = $( [] );
  5030. if ( name ) {
  5031. if ( form ) {
  5032. radios = $( form ).find( "[name='" + name + "']" );
  5033. } else {
  5034. radios = $( "[name='" + name + "']", radio.ownerDocument )
  5035. .filter(function() {
  5036. return !this.form;
  5037. });
  5038. }
  5039. }
  5040. return radios;
  5041. };
  5042. $.widget( "ui.button", {
  5043. version: "1.9.2",
  5044. defaultElement: "<button>",
  5045. options: {
  5046. disabled: null,
  5047. text: true,
  5048. label: null,
  5049. icons: {
  5050. primary: null,
  5051. secondary: null
  5052. }
  5053. },
  5054. _create: function() {
  5055. this.element.closest( "form" )
  5056. .unbind( "reset" + this.eventNamespace )
  5057. .bind( "reset" + this.eventNamespace, formResetHandler );
  5058. if ( typeof this.options.disabled !== "boolean" ) {
  5059. this.options.disabled = !!this.element.prop( "disabled" );
  5060. } else {
  5061. this.element.prop( "disabled", this.options.disabled );
  5062. }
  5063. this._determineButtonType();
  5064. this.hasTitle = !!this.buttonElement.attr( "title" );
  5065. var that = this,
  5066. options = this.options,
  5067. toggleButton = this.type === "checkbox" || this.type === "radio",
  5068. activeClass = !toggleButton ? "ui-state-active" : "",
  5069. focusClass = "ui-state-focus";
  5070. if ( options.label === null ) {
  5071. options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
  5072. }
  5073. this._hoverable( this.buttonElement );
  5074. this.buttonElement
  5075. .addClass( baseClasses )
  5076. .attr( "role", "button" )
  5077. .bind( "mouseenter" + this.eventNamespace, function() {
  5078. if ( options.disabled ) {
  5079. return;
  5080. }
  5081. if ( this === lastActive ) {
  5082. $( this ).addClass( "ui-state-active" );
  5083. }
  5084. })
  5085. .bind( "mouseleave" + this.eventNamespace, function() {
  5086. if ( options.disabled ) {
  5087. return;
  5088. }
  5089. $( this ).removeClass( activeClass );
  5090. })
  5091. .bind( "click" + this.eventNamespace, function( event ) {
  5092. if ( options.disabled ) {
  5093. event.preventDefault();
  5094. event.stopImmediatePropagation();
  5095. }
  5096. });
  5097. this.element
  5098. .bind( "focus" + this.eventNamespace, function() {
  5099. // no need to check disabled, focus won't be triggered anyway
  5100. that.buttonElement.addClass( focusClass );
  5101. })
  5102. .bind( "blur" + this.eventNamespace, function() {
  5103. that.buttonElement.removeClass( focusClass );
  5104. });
  5105. if ( toggleButton ) {
  5106. this.element.bind( "change" + this.eventNamespace, function() {
  5107. if ( clickDragged ) {
  5108. return;
  5109. }
  5110. that.refresh();
  5111. });
  5112. // if mouse moves between mousedown and mouseup (drag) set clickDragged flag
  5113. // prevents issue where button state changes but checkbox/radio checked state
  5114. // does not in Firefox (see ticket #6970)
  5115. this.buttonElement
  5116. .bind( "mousedown" + this.eventNamespace, function( event ) {
  5117. if ( options.disabled ) {
  5118. return;
  5119. }
  5120. clickDragged = false;
  5121. startXPos = event.pageX;
  5122. startYPos = event.pageY;
  5123. })
  5124. .bind( "mouseup" + this.eventNamespace, function( event ) {
  5125. if ( options.disabled ) {
  5126. return;
  5127. }
  5128. if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
  5129. clickDragged = true;
  5130. }
  5131. });
  5132. }
  5133. if ( this.type === "checkbox" ) {
  5134. this.buttonElement.bind( "click" + this.eventNamespace, function() {
  5135. if ( options.disabled || clickDragged ) {
  5136. return false;
  5137. }
  5138. $( this ).toggleClass( "ui-state-active" );
  5139. that.buttonElement.attr( "aria-pressed", that.element[0].checked );
  5140. });
  5141. } else if ( this.type === "radio" ) {
  5142. this.buttonElement.bind( "click" + this.eventNamespace, function() {
  5143. if ( options.disabled || clickDragged ) {
  5144. return false;
  5145. }
  5146. $( this ).addClass( "ui-state-active" );
  5147. that.buttonElement.attr( "aria-pressed", "true" );
  5148. var radio = that.element[ 0 ];
  5149. radioGroup( radio )
  5150. .not( radio )
  5151. .map(function() {
  5152. return $( this ).button( "widget" )[ 0 ];
  5153. })
  5154. .removeClass( "ui-state-active" )
  5155. .attr( "aria-pressed", "false" );
  5156. });
  5157. } else {
  5158. this.buttonElement
  5159. .bind( "mousedown" + this.eventNamespace, function() {
  5160. if ( options.disabled ) {
  5161. return false;
  5162. }
  5163. $( this ).addClass( "ui-state-active" );
  5164. lastActive = this;
  5165. that.document.one( "mouseup", function() {
  5166. lastActive = null;
  5167. });
  5168. })
  5169. .bind( "mouseup" + this.eventNamespace, function() {
  5170. if ( options.disabled ) {
  5171. return false;
  5172. }
  5173. $( this ).removeClass( "ui-state-active" );
  5174. })
  5175. .bind( "keydown" + this.eventNamespace, function(event) {
  5176. if ( options.disabled ) {
  5177. return false;
  5178. }
  5179. if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
  5180. $( this ).addClass( "ui-state-active" );
  5181. }
  5182. })
  5183. .bind( "keyup" + this.eventNamespace, function() {
  5184. $( this ).removeClass( "ui-state-active" );
  5185. });
  5186. if ( this.buttonElement.is("a") ) {
  5187. this.buttonElement.keyup(function(event) {
  5188. if ( event.keyCode === $.ui.keyCode.SPACE ) {
  5189. // TODO pass through original event correctly (just as 2nd argument doesn't work)
  5190. $( this ).click();
  5191. }
  5192. });
  5193. }
  5194. }
  5195. // TODO: pull out $.Widget's handling for the disabled option into
  5196. // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
  5197. // be overridden by individual plugins
  5198. this._setOption( "disabled", options.disabled );
  5199. this._resetButton();
  5200. },
  5201. _determineButtonType: function() {
  5202. var ancestor, labelSelector, checked;
  5203. if ( this.element.is("[type=checkbox]") ) {
  5204. this.type = "checkbox";
  5205. } else if ( this.element.is("[type=radio]") ) {
  5206. this.type = "radio";
  5207. } else if ( this.element.is("input") ) {
  5208. this.type = "input";
  5209. } else {
  5210. this.type = "button";
  5211. }
  5212. if ( this.type === "checkbox" || this.type === "radio" ) {
  5213. // we don't search against the document in case the element
  5214. // is disconnected from the DOM
  5215. ancestor = this.element.parents().last();
  5216. labelSelector = "label[for='" + this.element.attr("id") + "']";
  5217. this.buttonElement = ancestor.find( labelSelector );
  5218. if ( !this.buttonElement.length ) {
  5219. ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
  5220. this.buttonElement = ancestor.filter( labelSelector );
  5221. if ( !this.buttonElement.length ) {
  5222. this.buttonElement = ancestor.find( labelSelector );
  5223. }
  5224. }
  5225. this.element.addClass( "ui-helper-hidden-accessible" );
  5226. checked = this.element.is( ":checked" );
  5227. if ( checked ) {
  5228. this.buttonElement.addClass( "ui-state-active" );
  5229. }
  5230. this.buttonElement.prop( "aria-pressed", checked );
  5231. } else {
  5232. this.buttonElement = this.element;
  5233. }
  5234. },
  5235. widget: function() {
  5236. return this.buttonElement;
  5237. },
  5238. _destroy: function() {
  5239. this.element
  5240. .removeClass( "ui-helper-hidden-accessible" );
  5241. this.buttonElement
  5242. .removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
  5243. .removeAttr( "role" )
  5244. .removeAttr( "aria-pressed" )
  5245. .html( this.buttonElement.find(".ui-button-text").html() );
  5246. if ( !this.hasTitle ) {
  5247. this.buttonElement.removeAttr( "title" );
  5248. }
  5249. },
  5250. _setOption: function( key, value ) {
  5251. this._super( key, value );
  5252. if ( key === "disabled" ) {
  5253. if ( value ) {
  5254. this.element.prop( "disabled", true );
  5255. } else {
  5256. this.element.prop( "disabled", false );
  5257. }
  5258. return;
  5259. }
  5260. this._resetButton();
  5261. },
  5262. refresh: function() {
  5263. //See #8237 & #8828
  5264. var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
  5265. if ( isDisabled !== this.options.disabled ) {
  5266. this._setOption( "disabled", isDisabled );
  5267. }
  5268. if ( this.type === "radio" ) {
  5269. radioGroup( this.element[0] ).each(function() {
  5270. if ( $( this ).is( ":checked" ) ) {
  5271. $( this ).button( "widget" )
  5272. .addClass( "ui-state-active" )
  5273. .attr( "aria-pressed", "true" );
  5274. } else {
  5275. $( this ).button( "widget" )
  5276. .removeClass( "ui-state-active" )
  5277. .attr( "aria-pressed", "false" );
  5278. }
  5279. });
  5280. } else if ( this.type === "checkbox" ) {
  5281. if ( this.element.is( ":checked" ) ) {
  5282. this.buttonElement
  5283. .addClass( "ui-state-active" )
  5284. .attr( "aria-pressed", "true" );
  5285. } else {
  5286. this.buttonElement
  5287. .removeClass( "ui-state-active" )
  5288. .attr( "aria-pressed", "false" );
  5289. }
  5290. }
  5291. },
  5292. _resetButton: function() {
  5293. if ( this.type === "input" ) {
  5294. if ( this.options.label ) {
  5295. this.element.val( this.options.label );
  5296. }
  5297. return;
  5298. }
  5299. var buttonElement = this.buttonElement.removeClass( typeClasses ),
  5300. buttonText = $( "<span></span>", this.document[0] )
  5301. .addClass( "ui-button-text" )
  5302. .html( this.options.label )
  5303. .appendTo( buttonElement.empty() )
  5304. .text(),
  5305. icons = this.options.icons,
  5306. multipleIcons = icons.primary && icons.secondary,
  5307. buttonClasses = [];
  5308. if ( icons.primary || icons.secondary ) {
  5309. if ( this.options.text ) {
  5310. buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
  5311. }
  5312. if ( icons.primary ) {
  5313. buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
  5314. }
  5315. if ( icons.secondary ) {
  5316. buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
  5317. }
  5318. if ( !this.options.text ) {
  5319. buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
  5320. if ( !this.hasTitle ) {
  5321. buttonElement.attr( "title", $.trim( buttonText ) );
  5322. }
  5323. }
  5324. } else {
  5325. buttonClasses.push( "ui-button-text-only" );
  5326. }
  5327. buttonElement.addClass( buttonClasses.join( " " ) );
  5328. }
  5329. });
  5330. $.widget( "ui.buttonset", {
  5331. version: "1.9.2",
  5332. options: {
  5333. items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(button)"
  5334. },
  5335. _create: function() {
  5336. this.element.addClass( "ui-buttonset" );
  5337. },
  5338. _init: function() {
  5339. this.refresh();
  5340. },
  5341. _setOption: function( key, value ) {
  5342. if ( key === "disabled" ) {
  5343. this.buttons.button( "option", key, value );
  5344. }
  5345. this._super( key, value );
  5346. },
  5347. refresh: function() {
  5348. var rtl = this.element.css( "direction" ) === "rtl";
  5349. this.buttons = this.element.find( this.options.items )
  5350. .filter( ":ui-button" )
  5351. .button( "refresh" )
  5352. .end()
  5353. .not( ":ui-button" )
  5354. .button()
  5355. .end()
  5356. .map(function() {
  5357. return $( this ).button( "widget" )[ 0 ];
  5358. })
  5359. .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
  5360. .filter( ":first" )
  5361. .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
  5362. .end()
  5363. .filter( ":last" )
  5364. .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
  5365. .end()
  5366. .end();
  5367. },
  5368. _destroy: function() {
  5369. this.element.removeClass( "ui-buttonset" );
  5370. this.buttons
  5371. .map(function() {
  5372. return $( this ).button( "widget" )[ 0 ];
  5373. })
  5374. .removeClass( "ui-corner-left ui-corner-right" )
  5375. .end()
  5376. .button( "destroy" );
  5377. }
  5378. });
  5379. }( jQuery ) );
  5380. (function( $, undefined ) {
  5381. $.extend($.ui, { datepicker: { version: "1.9.2" } });
  5382. var PROP_NAME = 'datepicker';
  5383. var dpuuid = new Date().getTime();
  5384. var instActive;
  5385. /* Date picker manager.
  5386. Use the singleton instance of this class, $.datepicker, to interact with the date picker.
  5387. Settings for (groups of) date pickers are maintained in an instance object,
  5388. allowing multiple different settings on the same page. */
  5389. function Datepicker() {
  5390. this.debug = false; // Change this to true to start debugging
  5391. this._curInst = null; // The current instance in use
  5392. this._keyEvent = false; // If the last event was a key event
  5393. this._disabledInputs = []; // List of date picker inputs that have been disabled
  5394. this._datepickerShowing = false; // True if the popup picker is showing , false if not
  5395. this._inDialog = false; // True if showing within a "dialog", false if not
  5396. this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
  5397. this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
  5398. this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
  5399. this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
  5400. this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
  5401. this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
  5402. this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
  5403. this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
  5404. this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
  5405. this.regional = []; // Available regional settings, indexed by language code
  5406. this.regional[''] = { // Default regional settings
  5407. closeText: 'Done', // Display text for close link
  5408. prevText: 'Prev', // Display text for previous month link
  5409. nextText: 'Next', // Display text for next month link
  5410. currentText: 'Today', // Display text for current month link
  5411. monthNames: ['January','February','March','April','May','June',
  5412. 'July','August','September','October','November','December'], // Names of months for drop-down and formatting
  5413. monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
  5414. dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
  5415. dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
  5416. dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
  5417. weekHeader: 'Wk', // Column header for week of the year
  5418. dateFormat: 'mm/dd/yy', // See format options on parseDate
  5419. firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
  5420. isRTL: false, // True if right-to-left language, false if left-to-right
  5421. showMonthAfterYear: false, // True if the year select precedes month, false for month then year
  5422. yearSuffix: '' // Additional text to append to the year in the month headers
  5423. };
  5424. this._defaults = { // Global defaults for all the date picker instances
  5425. showOn: 'focus', // 'focus' for popup on focus,
  5426. // 'button' for trigger button, or 'both' for either
  5427. showAnim: 'fadeIn', // Name of jQuery animation for popup
  5428. showOptions: {}, // Options for enhanced animations
  5429. defaultDate: null, // Used when field is blank: actual date,
  5430. // +/-number for offset from today, null for today
  5431. appendText: '', // Display text following the input box, e.g. showing the format
  5432. buttonText: '...', // Text for trigger button
  5433. buttonImage: '', // URL for trigger button image
  5434. buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
  5435. hideIfNoPrevNext: false, // True to hide next/previous month links
  5436. // if not applicable, false to just disable them
  5437. navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
  5438. gotoCurrent: false, // True if today link goes back to current selection instead
  5439. changeMonth: false, // True if month can be selected directly, false if only prev/next
  5440. changeYear: false, // True if year can be selected directly, false if only prev/next
  5441. yearRange: 'c-10:c+10', // Range of years to display in drop-down,
  5442. // either relative to today's year (-nn:+nn), relative to currently displayed year
  5443. // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
  5444. showOtherMonths: false, // True to show dates in other months, false to leave blank
  5445. selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
  5446. showWeek: false, // True to show week of the year, false to not show it
  5447. calculateWeek: this.iso8601Week, // How to calculate the week of the year,
  5448. // takes a Date and returns the number of the week for it
  5449. shortYearCutoff: '+10', // Short year values < this are in the current century,
  5450. // > this are in the previous century,
  5451. // string value starting with '+' for current year + value
  5452. minDate: null, // The earliest selectable date, or null for no limit
  5453. maxDate: null, // The latest selectable date, or null for no limit
  5454. duration: 'fast', // Duration of display/closure
  5455. beforeShowDay: null, // Function that takes a date and returns an array with
  5456. // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
  5457. // [2] = cell title (optional), e.g. $.datepicker.noWeekends
  5458. beforeShow: null, // Function that takes an input field and
  5459. // returns a set of custom settings for the date picker
  5460. onSelect: null, // Define a callback function when a date is selected
  5461. onChangeMonthYear: null, // Define a callback function when the month or year is changed
  5462. onClose: null, // Define a callback function when the datepicker is closed
  5463. numberOfMonths: 1, // Number of months to show at a time
  5464. showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
  5465. stepMonths: 1, // Number of months to step back/forward
  5466. stepBigMonths: 12, // Number of months to step back/forward for the big links
  5467. altField: '', // Selector for an alternate field to store selected dates into
  5468. altFormat: '', // The date format to use for the alternate field
  5469. constrainInput: true, // The input is constrained by the current date format
  5470. showButtonPanel: false, // True to show button panel, false to not show it
  5471. autoSize: false, // True to size the input for the date format, false to leave as is
  5472. disabled: false // The initial disabled state
  5473. };
  5474. $.extend(this._defaults, this.regional['']);
  5475. this.dpDiv = bindHover($('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'));
  5476. }
  5477. $.extend(Datepicker.prototype, {
  5478. /* Class name added to elements to indicate already configured with a date picker. */
  5479. markerClassName: 'hasDatepicker',
  5480. //Keep track of the maximum number of rows displayed (see #7043)
  5481. maxRows: 4,
  5482. /* Debug logging (if enabled). */
  5483. log: function () {
  5484. if (this.debug)
  5485. console.log.apply('', arguments);
  5486. },
  5487. // TODO rename to "widget" when switching to widget factory
  5488. _widgetDatepicker: function() {
  5489. return this.dpDiv;
  5490. },
  5491. /* Override the default settings for all instances of the date picker.
  5492. @param settings object - the new settings to use as defaults (anonymous object)
  5493. @return the manager object */
  5494. setDefaults: function(settings) {
  5495. extendRemove(this._defaults, settings || {});
  5496. return this;
  5497. },
  5498. /* Attach the date picker to a jQuery selection.
  5499. @param target element - the target input field or division or span
  5500. @param settings object - the new settings to use for this date picker instance (anonymous) */
  5501. _attachDatepicker: function(target, settings) {
  5502. // check for settings on the control itself - in namespace 'date:'
  5503. var inlineSettings = null;
  5504. for (var attrName in this._defaults) {
  5505. var attrValue = target.getAttribute('date:' + attrName);
  5506. if (attrValue) {
  5507. inlineSettings = inlineSettings || {};
  5508. try {
  5509. inlineSettings[attrName] = eval(attrValue);
  5510. } catch (err) {
  5511. inlineSettings[attrName] = attrValue;
  5512. }
  5513. }
  5514. }
  5515. var nodeName = target.nodeName.toLowerCase();
  5516. var inline = (nodeName == 'div' || nodeName == 'span');
  5517. if (!target.id) {
  5518. this.uuid += 1;
  5519. target.id = 'dp' + this.uuid;
  5520. }
  5521. var inst = this._newInst($(target), inline);
  5522. inst.settings = $.extend({}, settings || {}, inlineSettings || {});
  5523. if (nodeName == 'input') {
  5524. this._connectDatepicker(target, inst);
  5525. } else if (inline) {
  5526. this._inlineDatepicker(target, inst);
  5527. }
  5528. },
  5529. /* Create a new instance object. */
  5530. _newInst: function(target, inline) {
  5531. var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars
  5532. return {id: id, input: target, // associated target
  5533. selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
  5534. drawMonth: 0, drawYear: 0, // month being drawn
  5535. inline: inline, // is datepicker inline or not
  5536. dpDiv: (!inline ? this.dpDiv : // presentation div
  5537. bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))};
  5538. },
  5539. /* Attach the date picker to an input field. */
  5540. _connectDatepicker: function(target, inst) {
  5541. var input = $(target);
  5542. inst.append = $([]);
  5543. inst.trigger = $([]);
  5544. if (input.hasClass(this.markerClassName))
  5545. return;
  5546. this._attachments(input, inst);
  5547. input.addClass(this.markerClassName).keydown(this._doKeyDown).
  5548. keypress(this._doKeyPress).keyup(this._doKeyUp).
  5549. bind("setData.datepicker", function(event, key, value) {
  5550. inst.settings[key] = value;
  5551. }).bind("getData.datepicker", function(event, key) {
  5552. return this._get(inst, key);
  5553. });
  5554. this._autoSize(inst);
  5555. $.data(target, PROP_NAME, inst);
  5556. //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
  5557. if( inst.settings.disabled ) {
  5558. this._disableDatepicker( target );
  5559. }
  5560. },
  5561. /* Make attachments based on settings. */
  5562. _attachments: function(input, inst) {
  5563. var appendText = this._get(inst, 'appendText');
  5564. var isRTL = this._get(inst, 'isRTL');
  5565. if (inst.append)
  5566. inst.append.remove();
  5567. if (appendText) {
  5568. inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>');
  5569. input[isRTL ? 'before' : 'after'](inst.append);
  5570. }
  5571. input.unbind('focus', this._showDatepicker);
  5572. if (inst.trigger)
  5573. inst.trigger.remove();
  5574. var showOn = this._get(inst, 'showOn');
  5575. if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
  5576. input.focus(this._showDatepicker);
  5577. if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
  5578. var buttonText = this._get(inst, 'buttonText');
  5579. var buttonImage = this._get(inst, 'buttonImage');
  5580. inst.trigger = $(this._get(inst, 'buttonImageOnly') ?
  5581. $('<img/>').addClass(this._triggerClass).
  5582. attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
  5583. $('<button type="button"></button>').addClass(this._triggerClass).
  5584. html(buttonImage == '' ? buttonText : $('<img/>').attr(
  5585. { src:buttonImage, alt:buttonText, title:buttonText })));
  5586. input[isRTL ? 'before' : 'after'](inst.trigger);
  5587. inst.trigger.click(function() {
  5588. if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0])
  5589. $.datepicker._hideDatepicker();
  5590. else if ($.datepicker._datepickerShowing && $.datepicker._lastInput != input[0]) {
  5591. $.datepicker._hideDatepicker();
  5592. $.datepicker._showDatepicker(input[0]);
  5593. } else
  5594. $.datepicker._showDatepicker(input[0]);
  5595. return false;
  5596. });
  5597. }
  5598. },
  5599. /* Apply the maximum length for the date format. */
  5600. _autoSize: function(inst) {
  5601. if (this._get(inst, 'autoSize') && !inst.inline) {
  5602. var date = new Date(2009, 12 - 1, 20); // Ensure double digits
  5603. var dateFormat = this._get(inst, 'dateFormat');
  5604. if (dateFormat.match(/[DM]/)) {
  5605. var findMax = function(names) {
  5606. var max = 0;
  5607. var maxI = 0;
  5608. for (var i = 0; i < names.length; i++) {
  5609. if (names[i].length > max) {
  5610. max = names[i].length;
  5611. maxI = i;
  5612. }
  5613. }
  5614. return maxI;
  5615. };
  5616. date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
  5617. 'monthNames' : 'monthNamesShort'))));
  5618. date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
  5619. 'dayNames' : 'dayNamesShort'))) + 20 - date.getDay());
  5620. }
  5621. inst.input.attr('size', this._formatDate(inst, date).length);
  5622. }
  5623. },
  5624. /* Attach an inline date picker to a div. */
  5625. _inlineDatepicker: function(target, inst) {
  5626. var divSpan = $(target);
  5627. if (divSpan.hasClass(this.markerClassName))
  5628. return;
  5629. divSpan.addClass(this.markerClassName).append(inst.dpDiv).
  5630. bind("setData.datepicker", function(event, key, value){
  5631. inst.settings[key] = value;
  5632. }).bind("getData.datepicker", function(event, key){
  5633. return this._get(inst, key);
  5634. });
  5635. $.data(target, PROP_NAME, inst);
  5636. this._setDate(inst, this._getDefaultDate(inst), true);
  5637. this._updateDatepicker(inst);
  5638. this._updateAlternate(inst);
  5639. //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
  5640. if( inst.settings.disabled ) {
  5641. this._disableDatepicker( target );
  5642. }
  5643. // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
  5644. // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
  5645. inst.dpDiv.css( "display", "block" );
  5646. },
  5647. /* Pop-up the date picker in a "dialog" box.
  5648. @param input element - ignored
  5649. @param date string or Date - the initial date to display
  5650. @param onSelect function - the function to call when a date is selected
  5651. @param settings object - update the dialog date picker instance's settings (anonymous object)
  5652. @param pos int[2] - coordinates for the dialog's position within the screen or
  5653. event - with x/y coordinates or
  5654. leave empty for default (screen centre)
  5655. @return the manager object */
  5656. _dialogDatepicker: function(input, date, onSelect, settings, pos) {
  5657. var inst = this._dialogInst; // internal instance
  5658. if (!inst) {
  5659. this.uuid += 1;
  5660. var id = 'dp' + this.uuid;
  5661. this._dialogInput = $('<input type="text" id="' + id +
  5662. '" style="position: absolute; top: -100px; width: 0px;"/>');
  5663. this._dialogInput.keydown(this._doKeyDown);
  5664. $('body').append(this._dialogInput);
  5665. inst = this._dialogInst = this._newInst(this._dialogInput, false);
  5666. inst.settings = {};
  5667. $.data(this._dialogInput[0], PROP_NAME, inst);
  5668. }
  5669. extendRemove(inst.settings, settings || {});
  5670. date = (date && date.constructor == Date ? this._formatDate(inst, date) : date);
  5671. this._dialogInput.val(date);
  5672. this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
  5673. if (!this._pos) {
  5674. var browserWidth = document.documentElement.clientWidth;
  5675. var browserHeight = document.documentElement.clientHeight;
  5676. var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
  5677. var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
  5678. this._pos = // should use actual width/height below
  5679. [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
  5680. }
  5681. // move input on screen for focus, but hidden behind dialog
  5682. this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px');
  5683. inst.settings.onSelect = onSelect;
  5684. this._inDialog = true;
  5685. this.dpDiv.addClass(this._dialogClass);
  5686. this._showDatepicker(this._dialogInput[0]);
  5687. if ($.blockUI)
  5688. $.blockUI(this.dpDiv);
  5689. $.data(this._dialogInput[0], PROP_NAME, inst);
  5690. return this;
  5691. },
  5692. /* Detach a datepicker from its control.
  5693. @param target element - the target input field or division or span */
  5694. _destroyDatepicker: function(target) {
  5695. var $target = $(target);
  5696. var inst = $.data(target, PROP_NAME);
  5697. if (!$target.hasClass(this.markerClassName)) {
  5698. return;
  5699. }
  5700. var nodeName = target.nodeName.toLowerCase();
  5701. $.removeData(target, PROP_NAME);
  5702. if (nodeName == 'input') {
  5703. inst.append.remove();
  5704. inst.trigger.remove();
  5705. $target.removeClass(this.markerClassName).
  5706. unbind('focus', this._showDatepicker).
  5707. unbind('keydown', this._doKeyDown).
  5708. unbind('keypress', this._doKeyPress).
  5709. unbind('keyup', this._doKeyUp);
  5710. } else if (nodeName == 'div' || nodeName == 'span')
  5711. $target.removeClass(this.markerClassName).empty();
  5712. },
  5713. /* Enable the date picker to a jQuery selection.
  5714. @param target element - the target input field or division or span */
  5715. _enableDatepicker: function(target) {
  5716. var $target = $(target);
  5717. var inst = $.data(target, PROP_NAME);
  5718. if (!$target.hasClass(this.markerClassName)) {
  5719. return;
  5720. }
  5721. var nodeName = target.nodeName.toLowerCase();
  5722. if (nodeName == 'input') {
  5723. target.disabled = false;
  5724. inst.trigger.filter('button').
  5725. each(function() { this.disabled = false; }).end().
  5726. filter('img').css({opacity: '1.0', cursor: ''});
  5727. }
  5728. else if (nodeName == 'div' || nodeName == 'span') {
  5729. var inline = $target.children('.' + this._inlineClass);
  5730. inline.children().removeClass('ui-state-disabled');
  5731. inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
  5732. prop("disabled", false);
  5733. }
  5734. this._disabledInputs = $.map(this._disabledInputs,
  5735. function(value) { return (value == target ? null : value); }); // delete entry
  5736. },
  5737. /* Disable the date picker to a jQuery selection.
  5738. @param target element - the target input field or division or span */
  5739. _disableDatepicker: function(target) {
  5740. var $target = $(target);
  5741. var inst = $.data(target, PROP_NAME);
  5742. if (!$target.hasClass(this.markerClassName)) {
  5743. return;
  5744. }
  5745. var nodeName = target.nodeName.toLowerCase();
  5746. if (nodeName == 'input') {
  5747. target.disabled = true;
  5748. inst.trigger.filter('button').
  5749. each(function() { this.disabled = true; }).end().
  5750. filter('img').css({opacity: '0.5', cursor: 'default'});
  5751. }
  5752. else if (nodeName == 'div' || nodeName == 'span') {
  5753. var inline = $target.children('.' + this._inlineClass);
  5754. inline.children().addClass('ui-state-disabled');
  5755. inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
  5756. prop("disabled", true);
  5757. }
  5758. this._disabledInputs = $.map(this._disabledInputs,
  5759. function(value) { return (value == target ? null : value); }); // delete entry
  5760. this._disabledInputs[this._disabledInputs.length] = target;
  5761. },
  5762. /* Is the first field in a jQuery collection disabled as a datepicker?
  5763. @param target element - the target input field or division or span
  5764. @return boolean - true if disabled, false if enabled */
  5765. _isDisabledDatepicker: function(target) {
  5766. if (!target) {
  5767. return false;
  5768. }
  5769. for (var i = 0; i < this._disabledInputs.length; i++) {
  5770. if (this._disabledInputs[i] == target)
  5771. return true;
  5772. }
  5773. return false;
  5774. },
  5775. /* Retrieve the instance data for the target control.
  5776. @param target element - the target input field or division or span
  5777. @return object - the associated instance data
  5778. @throws error if a jQuery problem getting data */
  5779. _getInst: function(target) {
  5780. try {
  5781. return $.data(target, PROP_NAME);
  5782. }
  5783. catch (err) {
  5784. throw 'Missing instance data for this datepicker';
  5785. }
  5786. },
  5787. /* Update or retrieve the settings for a date picker attached to an input field or division.
  5788. @param target element - the target input field or division or span
  5789. @param name object - the new settings to update or
  5790. string - the name of the setting to change or retrieve,
  5791. when retrieving also 'all' for all instance settings or
  5792. 'defaults' for all global defaults
  5793. @param value any - the new value for the setting
  5794. (omit if above is an object or to retrieve a value) */
  5795. _optionDatepicker: function(target, name, value) {
  5796. var inst = this._getInst(target);
  5797. if (arguments.length == 2 && typeof name == 'string') {
  5798. return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) :
  5799. (inst ? (name == 'all' ? $.extend({}, inst.settings) :
  5800. this._get(inst, name)) : null));
  5801. }
  5802. var settings = name || {};
  5803. if (typeof name == 'string') {
  5804. settings = {};
  5805. settings[name] = value;
  5806. }
  5807. if (inst) {
  5808. if (this._curInst == inst) {
  5809. this._hideDatepicker();
  5810. }
  5811. var date = this._getDateDatepicker(target, true);
  5812. var minDate = this._getMinMaxDate(inst, 'min');
  5813. var maxDate = this._getMinMaxDate(inst, 'max');
  5814. extendRemove(inst.settings, settings);
  5815. // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
  5816. if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined)
  5817. inst.settings.minDate = this._formatDate(inst, minDate);
  5818. if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined)
  5819. inst.settings.maxDate = this._formatDate(inst, maxDate);
  5820. this._attachments($(target), inst);
  5821. this._autoSize(inst);
  5822. this._setDate(inst, date);
  5823. this._updateAlternate(inst);
  5824. this._updateDatepicker(inst);
  5825. }
  5826. },
  5827. // change method deprecated
  5828. _changeDatepicker: function(target, name, value) {
  5829. this._optionDatepicker(target, name, value);
  5830. },
  5831. /* Redraw the date picker attached to an input field or division.
  5832. @param target element - the target input field or division or span */
  5833. _refreshDatepicker: function(target) {
  5834. var inst = this._getInst(target);
  5835. if (inst) {
  5836. this._updateDatepicker(inst);
  5837. }
  5838. },
  5839. /* Set the dates for a jQuery selection.
  5840. @param target element - the target input field or division or span
  5841. @param date Date - the new date */
  5842. _setDateDatepicker: function(target, date) {
  5843. var inst = this._getInst(target);
  5844. if (inst) {
  5845. this._setDate(inst, date);
  5846. this._updateDatepicker(inst);
  5847. this._updateAlternate(inst);
  5848. }
  5849. },
  5850. /* Get the date(s) for the first entry in a jQuery selection.
  5851. @param target element - the target input field or division or span
  5852. @param noDefault boolean - true if no default date is to be used
  5853. @return Date - the current date */
  5854. _getDateDatepicker: function(target, noDefault) {
  5855. var inst = this._getInst(target);
  5856. if (inst && !inst.inline)
  5857. this._setDateFromField(inst, noDefault);
  5858. return (inst ? this._getDate(inst) : null);
  5859. },
  5860. /* Handle keystrokes. */
  5861. _doKeyDown: function(event) {
  5862. var inst = $.datepicker._getInst(event.target);
  5863. var handled = true;
  5864. var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
  5865. inst._keyEvent = true;
  5866. if ($.datepicker._datepickerShowing)
  5867. switch (event.keyCode) {
  5868. case 9: $.datepicker._hideDatepicker();
  5869. handled = false;
  5870. break; // hide on tab out
  5871. case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' +
  5872. $.datepicker._currentClass + ')', inst.dpDiv);
  5873. if (sel[0])
  5874. $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
  5875. var onSelect = $.datepicker._get(inst, 'onSelect');
  5876. if (onSelect) {
  5877. var dateStr = $.datepicker._formatDate(inst);
  5878. // trigger custom callback
  5879. onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
  5880. }
  5881. else
  5882. $.datepicker._hideDatepicker();
  5883. return false; // don't submit the form
  5884. break; // select the value on enter
  5885. case 27: $.datepicker._hideDatepicker();
  5886. break; // hide on escape
  5887. case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
  5888. -$.datepicker._get(inst, 'stepBigMonths') :
  5889. -$.datepicker._get(inst, 'stepMonths')), 'M');
  5890. break; // previous month/year on page up/+ ctrl
  5891. case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
  5892. +$.datepicker._get(inst, 'stepBigMonths') :
  5893. +$.datepicker._get(inst, 'stepMonths')), 'M');
  5894. break; // next month/year on page down/+ ctrl
  5895. case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
  5896. handled = event.ctrlKey || event.metaKey;
  5897. break; // clear on ctrl or command +end
  5898. case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
  5899. handled = event.ctrlKey || event.metaKey;
  5900. break; // current on ctrl or command +home
  5901. case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
  5902. handled = event.ctrlKey || event.metaKey;
  5903. // -1 day on ctrl or command +left
  5904. if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
  5905. -$.datepicker._get(inst, 'stepBigMonths') :
  5906. -$.datepicker._get(inst, 'stepMonths')), 'M');
  5907. // next month/year on alt +left on Mac
  5908. break;
  5909. case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
  5910. handled = event.ctrlKey || event.metaKey;
  5911. break; // -1 week on ctrl or command +up
  5912. case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
  5913. handled = event.ctrlKey || event.metaKey;
  5914. // +1 day on ctrl or command +right
  5915. if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
  5916. +$.datepicker._get(inst, 'stepBigMonths') :
  5917. +$.datepicker._get(inst, 'stepMonths')), 'M');
  5918. // next month/year on alt +right
  5919. break;
  5920. case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
  5921. handled = event.ctrlKey || event.metaKey;
  5922. break; // +1 week on ctrl or command +down
  5923. default: handled = false;
  5924. }
  5925. else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
  5926. $.datepicker._showDatepicker(this);
  5927. else {
  5928. handled = false;
  5929. }
  5930. if (handled) {
  5931. event.preventDefault();
  5932. event.stopPropagation();
  5933. }
  5934. },
  5935. /* Filter entered characters - based on date format. */
  5936. _doKeyPress: function(event) {
  5937. var inst = $.datepicker._getInst(event.target);
  5938. if ($.datepicker._get(inst, 'constrainInput')) {
  5939. var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
  5940. var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
  5941. return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
  5942. }
  5943. },
  5944. /* Synchronise manual entry and field/alternate field. */
  5945. _doKeyUp: function(event) {
  5946. var inst = $.datepicker._getInst(event.target);
  5947. if (inst.input.val() != inst.lastVal) {
  5948. try {
  5949. var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
  5950. (inst.input ? inst.input.val() : null),
  5951. $.datepicker._getFormatConfig(inst));
  5952. if (date) { // only if valid
  5953. $.datepicker._setDateFromField(inst);
  5954. $.datepicker._updateAlternate(inst);
  5955. $.datepicker._updateDatepicker(inst);
  5956. }
  5957. }
  5958. catch (err) {
  5959. $.datepicker.log(err);
  5960. }
  5961. }
  5962. return true;
  5963. },
  5964. /* Pop-up the date picker for a given input field.
  5965. If false returned from beforeShow event handler do not show.
  5966. @param input element - the input field attached to the date picker or
  5967. event - if triggered by focus */
  5968. _showDatepicker: function(input) {
  5969. input = input.target || input;
  5970. if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
  5971. input = $('input', input.parentNode)[0];
  5972. if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
  5973. return;
  5974. var inst = $.datepicker._getInst(input);
  5975. if ($.datepicker._curInst && $.datepicker._curInst != inst) {
  5976. $.datepicker._curInst.dpDiv.stop(true, true);
  5977. if ( inst && $.datepicker._datepickerShowing ) {
  5978. $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
  5979. }
  5980. }
  5981. var beforeShow = $.datepicker._get(inst, 'beforeShow');
  5982. var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
  5983. if(beforeShowSettings === false){
  5984. //false
  5985. return;
  5986. }
  5987. extendRemove(inst.settings, beforeShowSettings);
  5988. inst.lastVal = null;
  5989. $.datepicker._lastInput = input;
  5990. $.datepicker._setDateFromField(inst);
  5991. if ($.datepicker._inDialog) // hide cursor
  5992. input.value = '';
  5993. if (!$.datepicker._pos) { // position below input
  5994. $.datepicker._pos = $.datepicker._findPos(input);
  5995. $.datepicker._pos[1] += input.offsetHeight; // add the height
  5996. }
  5997. var isFixed = false;
  5998. $(input).parents().each(function() {
  5999. isFixed |= $(this).css('position') == 'fixed';
  6000. return !isFixed;
  6001. });
  6002. var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
  6003. $.datepicker._pos = null;
  6004. //to avoid flashes on Firefox
  6005. inst.dpDiv.empty();
  6006. // determine sizing offscreen
  6007. inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
  6008. $.datepicker._updateDatepicker(inst);
  6009. // fix width for dynamic number of date pickers
  6010. // and adjust position before showing
  6011. offset = $.datepicker._checkOffset(inst, offset, isFixed);
  6012. inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
  6013. 'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
  6014. left: offset.left + 'px', top: offset.top + 'px'});
  6015. if (!inst.inline) {
  6016. var showAnim = $.datepicker._get(inst, 'showAnim');
  6017. var duration = $.datepicker._get(inst, 'duration');
  6018. var postProcess = function() {
  6019. var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
  6020. if( !! cover.length ){
  6021. var borders = $.datepicker._getBorders(inst.dpDiv);
  6022. cover.css({left: -borders[0], top: -borders[1],
  6023. width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
  6024. }
  6025. };
  6026. inst.dpDiv.zIndex($(input).zIndex()+1);
  6027. $.datepicker._datepickerShowing = true;
  6028. // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
  6029. if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) )
  6030. inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
  6031. else
  6032. inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess);
  6033. if (!showAnim || !duration)
  6034. postProcess();
  6035. if (inst.input.is(':visible') && !inst.input.is(':disabled'))
  6036. inst.input.focus();
  6037. $.datepicker._curInst = inst;
  6038. }
  6039. },
  6040. /* Generate the date picker content. */
  6041. _updateDatepicker: function(inst) {
  6042. this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
  6043. var borders = $.datepicker._getBorders(inst.dpDiv);
  6044. instActive = inst; // for delegate hover events
  6045. inst.dpDiv.empty().append(this._generateHTML(inst));
  6046. this._attachHandlers(inst);
  6047. var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
  6048. if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6
  6049. cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
  6050. }
  6051. inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover();
  6052. var numMonths = this._getNumberOfMonths(inst);
  6053. var cols = numMonths[1];
  6054. var width = 17;
  6055. inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
  6056. if (cols > 1)
  6057. inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
  6058. inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
  6059. 'Class']('ui-datepicker-multi');
  6060. inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
  6061. 'Class']('ui-datepicker-rtl');
  6062. if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
  6063. // #6694 - don't focus the input if it's already focused
  6064. // this breaks the change event in IE
  6065. inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement)
  6066. inst.input.focus();
  6067. // deffered render of the years select (to avoid flashes on Firefox)
  6068. if( inst.yearshtml ){
  6069. var origyearshtml = inst.yearshtml;
  6070. setTimeout(function(){
  6071. //assure that inst.yearshtml didn't change.
  6072. if( origyearshtml === inst.yearshtml && inst.yearshtml ){
  6073. inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml);
  6074. }
  6075. origyearshtml = inst.yearshtml = null;
  6076. }, 0);
  6077. }
  6078. },
  6079. /* Retrieve the size of left and top borders for an element.
  6080. @param elem (jQuery object) the element of interest
  6081. @return (number[2]) the left and top borders */
  6082. _getBorders: function(elem) {
  6083. var convert = function(value) {
  6084. return {thin: 1, medium: 2, thick: 3}[value] || value;
  6085. };
  6086. return [parseFloat(convert(elem.css('border-left-width'))),
  6087. parseFloat(convert(elem.css('border-top-width')))];
  6088. },
  6089. /* Check positioning to remain on screen. */
  6090. _checkOffset: function(inst, offset, isFixed) {
  6091. var dpWidth = inst.dpDiv.outerWidth();
  6092. var dpHeight = inst.dpDiv.outerHeight();
  6093. var inputWidth = inst.input ? inst.input.outerWidth() : 0;
  6094. var inputHeight = inst.input ? inst.input.outerHeight() : 0;
  6095. var viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft());
  6096. var viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
  6097. offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
  6098. offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
  6099. offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
  6100. // now check if datepicker is showing outside window viewport - move to a better place if so.
  6101. offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
  6102. Math.abs(offset.left + dpWidth - viewWidth) : 0);
  6103. offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
  6104. Math.abs(dpHeight + inputHeight) : 0);
  6105. return offset;
  6106. },
  6107. /* Find an object's position on the screen. */
  6108. _findPos: function(obj) {
  6109. var inst = this._getInst(obj);
  6110. var isRTL = this._get(inst, 'isRTL');
  6111. while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) {
  6112. obj = obj[isRTL ? 'previousSibling' : 'nextSibling'];
  6113. }
  6114. var position = $(obj).offset();
  6115. return [position.left, position.top];
  6116. },
  6117. /* Hide the date picker from view.
  6118. @param input element - the input field attached to the date picker */
  6119. _hideDatepicker: function(input) {
  6120. var inst = this._curInst;
  6121. if (!inst || (input && inst != $.data(input, PROP_NAME)))
  6122. return;
  6123. if (this._datepickerShowing) {
  6124. var showAnim = this._get(inst, 'showAnim');
  6125. var duration = this._get(inst, 'duration');
  6126. var postProcess = function() {
  6127. $.datepicker._tidyDialog(inst);
  6128. };
  6129. // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
  6130. if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) )
  6131. inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
  6132. else
  6133. inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' :
  6134. (showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess);
  6135. if (!showAnim)
  6136. postProcess();
  6137. this._datepickerShowing = false;
  6138. var onClose = this._get(inst, 'onClose');
  6139. if (onClose)
  6140. onClose.apply((inst.input ? inst.input[0] : null),
  6141. [(inst.input ? inst.input.val() : ''), inst]);
  6142. this._lastInput = null;
  6143. if (this._inDialog) {
  6144. this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
  6145. if ($.blockUI) {
  6146. $.unblockUI();
  6147. $('body').append(this.dpDiv);
  6148. }
  6149. }
  6150. this._inDialog = false;
  6151. }
  6152. },
  6153. /* Tidy up after a dialog display. */
  6154. _tidyDialog: function(inst) {
  6155. inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
  6156. },
  6157. /* Close date picker if clicked elsewhere. */
  6158. _checkExternalClick: function(event) {
  6159. if (!$.datepicker._curInst)
  6160. return;
  6161. var $target = $(event.target),
  6162. inst = $.datepicker._getInst($target[0]);
  6163. if ( ( ( $target[0].id != $.datepicker._mainDivId &&
  6164. $target.parents('#' + $.datepicker._mainDivId).length == 0 &&
  6165. !$target.hasClass($.datepicker.markerClassName) &&
  6166. !$target.closest("." + $.datepicker._triggerClass).length &&
  6167. $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
  6168. ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst != inst ) )
  6169. $.datepicker._hideDatepicker();
  6170. },
  6171. /* Adjust one of the date sub-fields. */
  6172. _adjustDate: function(id, offset, period) {
  6173. var target = $(id);
  6174. var inst = this._getInst(target[0]);
  6175. if (this._isDisabledDatepicker(target[0])) {
  6176. return;
  6177. }
  6178. this._adjustInstDate(inst, offset +
  6179. (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
  6180. period);
  6181. this._updateDatepicker(inst);
  6182. },
  6183. /* Action for current link. */
  6184. _gotoToday: function(id) {
  6185. var target = $(id);
  6186. var inst = this._getInst(target[0]);
  6187. if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
  6188. inst.selectedDay = inst.currentDay;
  6189. inst.drawMonth = inst.selectedMonth = inst.currentMonth;
  6190. inst.drawYear = inst.selectedYear = inst.currentYear;
  6191. }
  6192. else {
  6193. var date = new Date();
  6194. inst.selectedDay = date.getDate();
  6195. inst.drawMonth = inst.selectedMonth = date.getMonth();
  6196. inst.drawYear = inst.selectedYear = date.getFullYear();
  6197. }
  6198. this._notifyChange(inst);
  6199. this._adjustDate(target);
  6200. },
  6201. /* Action for selecting a new month/year. */
  6202. _selectMonthYear: function(id, select, period) {
  6203. var target = $(id);
  6204. var inst = this._getInst(target[0]);
  6205. inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
  6206. inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
  6207. parseInt(select.options[select.selectedIndex].value,10);
  6208. this._notifyChange(inst);
  6209. this._adjustDate(target);
  6210. },
  6211. /* Action for selecting a day. */
  6212. _selectDay: function(id, month, year, td) {
  6213. var target = $(id);
  6214. if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
  6215. return;
  6216. }
  6217. var inst = this._getInst(target[0]);
  6218. inst.selectedDay = inst.currentDay = $('a', td).html();
  6219. inst.selectedMonth = inst.currentMonth = month;
  6220. inst.selectedYear = inst.currentYear = year;
  6221. this._selectDate(id, this._formatDate(inst,
  6222. inst.currentDay, inst.currentMonth, inst.currentYear));
  6223. },
  6224. /* Erase the input field and hide the date picker. */
  6225. _clearDate: function(id) {
  6226. var target = $(id);
  6227. var inst = this._getInst(target[0]);
  6228. this._selectDate(target, '');
  6229. },
  6230. /* Update the input field with the selected date. */
  6231. _selectDate: function(id, dateStr) {
  6232. var target = $(id);
  6233. var inst = this._getInst(target[0]);
  6234. dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
  6235. if (inst.input)
  6236. inst.input.val(dateStr);
  6237. this._updateAlternate(inst);
  6238. var onSelect = this._get(inst, 'onSelect');
  6239. if (onSelect)
  6240. onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback
  6241. else if (inst.input)
  6242. inst.input.trigger('change'); // fire the change event
  6243. if (inst.inline)
  6244. this._updateDatepicker(inst);
  6245. else {
  6246. this._hideDatepicker();
  6247. this._lastInput = inst.input[0];
  6248. if (typeof(inst.input[0]) != 'object')
  6249. inst.input.focus(); // restore focus
  6250. this._lastInput = null;
  6251. }
  6252. },
  6253. /* Update any alternate field to synchronise with the main field. */
  6254. _updateAlternate: function(inst) {
  6255. var altField = this._get(inst, 'altField');
  6256. if (altField) { // update alternate field too
  6257. var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
  6258. var date = this._getDate(inst);
  6259. var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
  6260. $(altField).each(function() { $(this).val(dateStr); });
  6261. }
  6262. },
  6263. /* Set as beforeShowDay function to prevent selection of weekends.
  6264. @param date Date - the date to customise
  6265. @return [boolean, string] - is this date selectable?, what is its CSS class? */
  6266. noWeekends: function(date) {
  6267. var day = date.getDay();
  6268. return [(day > 0 && day < 6), ''];
  6269. },
  6270. /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
  6271. @param date Date - the date to get the week for
  6272. @return number - the number of the week within the year that contains this date */
  6273. iso8601Week: function(date) {
  6274. var checkDate = new Date(date.getTime());
  6275. // Find Thursday of this week starting on Monday
  6276. checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
  6277. var time = checkDate.getTime();
  6278. checkDate.setMonth(0); // Compare with Jan 1
  6279. checkDate.setDate(1);
  6280. return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
  6281. },
  6282. /* Parse a string value into a date object.
  6283. See formatDate below for the possible formats.
  6284. @param format string - the expected format of the date
  6285. @param value string - the date in the above format
  6286. @param settings Object - attributes include:
  6287. shortYearCutoff number - the cutoff year for determining the century (optional)
  6288. dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
  6289. dayNames string[7] - names of the days from Sunday (optional)
  6290. monthNamesShort string[12] - abbreviated names of the months (optional)
  6291. monthNames string[12] - names of the months (optional)
  6292. @return Date - the extracted date value or null if value is blank */
  6293. parseDate: function (format, value, settings) {
  6294. if (format == null || value == null)
  6295. throw 'Invalid arguments';
  6296. value = (typeof value == 'object' ? value.toString() : value + '');
  6297. if (value == '')
  6298. return null;
  6299. var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
  6300. shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
  6301. new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
  6302. var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
  6303. var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
  6304. var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
  6305. var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
  6306. var year = -1;
  6307. var month = -1;
  6308. var day = -1;
  6309. var doy = -1;
  6310. var literal = false;
  6311. // Check whether a format character is doubled
  6312. var lookAhead = function(match) {
  6313. var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
  6314. if (matches)
  6315. iFormat++;
  6316. return matches;
  6317. };
  6318. // Extract a number from the string value
  6319. var getNumber = function(match) {
  6320. var isDoubled = lookAhead(match);
  6321. var size = (match == '@' ? 14 : (match == '!' ? 20 :
  6322. (match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2))));
  6323. var digits = new RegExp('^\\d{1,' + size + '}');
  6324. var num = value.substring(iValue).match(digits);
  6325. if (!num)
  6326. throw 'Missing number at position ' + iValue;
  6327. iValue += num[0].length;
  6328. return parseInt(num[0], 10);
  6329. };
  6330. // Extract a name from the string value and convert to an index
  6331. var getName = function(match, shortNames, longNames) {
  6332. var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
  6333. return [ [k, v] ];
  6334. }).sort(function (a, b) {
  6335. return -(a[1].length - b[1].length);
  6336. });
  6337. var index = -1;
  6338. $.each(names, function (i, pair) {
  6339. var name = pair[1];
  6340. if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) {
  6341. index = pair[0];
  6342. iValue += name.length;
  6343. return false;
  6344. }
  6345. });
  6346. if (index != -1)
  6347. return index + 1;
  6348. else
  6349. throw 'Unknown name at position ' + iValue;
  6350. };
  6351. // Confirm that a literal character matches the string value
  6352. var checkLiteral = function() {
  6353. if (value.charAt(iValue) != format.charAt(iFormat))
  6354. throw 'Unexpected literal at position ' + iValue;
  6355. iValue++;
  6356. };
  6357. var iValue = 0;
  6358. for (var iFormat = 0; iFormat < format.length; iFormat++) {
  6359. if (literal)
  6360. if (format.charAt(iFormat) == "'" && !lookAhead("'"))
  6361. literal = false;
  6362. else
  6363. checkLiteral();
  6364. else
  6365. switch (format.charAt(iFormat)) {
  6366. case 'd':
  6367. day = getNumber('d');
  6368. break;
  6369. case 'D':
  6370. getName('D', dayNamesShort, dayNames);
  6371. break;
  6372. case 'o':
  6373. doy = getNumber('o');
  6374. break;
  6375. case 'm':
  6376. month = getNumber('m');
  6377. break;
  6378. case 'M':
  6379. month = getName('M', monthNamesShort, monthNames);
  6380. break;
  6381. case 'y':
  6382. year = getNumber('y');
  6383. break;
  6384. case '@':
  6385. var date = new Date(getNumber('@'));
  6386. year = date.getFullYear();
  6387. month = date.getMonth() + 1;
  6388. day = date.getDate();
  6389. break;
  6390. case '!':
  6391. var date = new Date((getNumber('!') - this._ticksTo1970) / 10000);
  6392. year = date.getFullYear();
  6393. month = date.getMonth() + 1;
  6394. day = date.getDate();
  6395. break;
  6396. case "'":
  6397. if (lookAhead("'"))
  6398. checkLiteral();
  6399. else
  6400. literal = true;
  6401. break;
  6402. default:
  6403. checkLiteral();
  6404. }
  6405. }
  6406. if (iValue < value.length){
  6407. var extra = value.substr(iValue);
  6408. if (!/^\s+/.test(extra)) {
  6409. throw "Extra/unparsed characters found in date: " + extra;
  6410. }
  6411. }
  6412. if (year == -1)
  6413. year = new Date().getFullYear();
  6414. else if (year < 100)
  6415. year += new Date().getFullYear() - new Date().getFullYear() % 100 +
  6416. (year <= shortYearCutoff ? 0 : -100);
  6417. if (doy > -1) {
  6418. month = 1;
  6419. day = doy;
  6420. do {
  6421. var dim = this._getDaysInMonth(year, month - 1);
  6422. if (day <= dim)
  6423. break;
  6424. month++;
  6425. day -= dim;
  6426. } while (true);
  6427. }
  6428. var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
  6429. if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
  6430. throw 'Invalid date'; // E.g. 31/02/00
  6431. return date;
  6432. },
  6433. /* Standard date formats. */
  6434. ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
  6435. COOKIE: 'D, dd M yy',
  6436. ISO_8601: 'yy-mm-dd',
  6437. RFC_822: 'D, d M y',
  6438. RFC_850: 'DD, dd-M-y',
  6439. RFC_1036: 'D, d M y',
  6440. RFC_1123: 'D, d M yy',
  6441. RFC_2822: 'D, d M yy',
  6442. RSS: 'D, d M y', // RFC 822
  6443. TICKS: '!',
  6444. TIMESTAMP: '@',
  6445. W3C: 'yy-mm-dd', // ISO 8601
  6446. _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
  6447. Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
  6448. /* Format a date object into a string value.
  6449. The format can be combinations of the following:
  6450. d - day of month (no leading zero)
  6451. dd - day of month (two digit)
  6452. o - day of year (no leading zeros)
  6453. oo - day of year (three digit)
  6454. D - day name short
  6455. DD - day name long
  6456. m - month of year (no leading zero)
  6457. mm - month of year (two digit)
  6458. M - month name short
  6459. MM - month name long
  6460. y - year (two digit)
  6461. yy - year (four digit)
  6462. @ - Unix timestamp (ms since 01/01/1970)
  6463. ! - Windows ticks (100ns since 01/01/0001)
  6464. '...' - literal text
  6465. '' - single quote
  6466. @param format string - the desired format of the date
  6467. @param date Date - the date value to format
  6468. @param settings Object - attributes include:
  6469. dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
  6470. dayNames string[7] - names of the days from Sunday (optional)
  6471. monthNamesShort string[12] - abbreviated names of the months (optional)
  6472. monthNames string[12] - names of the months (optional)
  6473. @return string - the date in the above format */
  6474. formatDate: function (format, date, settings) {
  6475. if (!date)
  6476. return '';
  6477. var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
  6478. var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
  6479. var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
  6480. var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
  6481. // Check whether a format character is doubled
  6482. var lookAhead = function(match) {
  6483. var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
  6484. if (matches)
  6485. iFormat++;
  6486. return matches;
  6487. };
  6488. // Format a number, with leading zero if necessary
  6489. var formatNumber = function(match, value, len) {
  6490. var num = '' + value;
  6491. if (lookAhead(match))
  6492. while (num.length < len)
  6493. num = '0' + num;
  6494. return num;
  6495. };
  6496. // Format a name, short or long as requested
  6497. var formatName = function(match, value, shortNames, longNames) {
  6498. return (lookAhead(match) ? longNames[value] : shortNames[value]);
  6499. };
  6500. var output = '';
  6501. var literal = false;
  6502. if (date)
  6503. for (var iFormat = 0; iFormat < format.length; iFormat++) {
  6504. if (literal)
  6505. if (format.charAt(iFormat) == "'" && !lookAhead("'"))
  6506. literal = false;
  6507. else
  6508. output += format.charAt(iFormat);
  6509. else
  6510. switch (format.charAt(iFormat)) {
  6511. case 'd':
  6512. output += formatNumber('d', date.getDate(), 2);
  6513. break;
  6514. case 'D':
  6515. output += formatName('D', date.getDay(), dayNamesShort, dayNames);
  6516. break;
  6517. case 'o':
  6518. output += formatNumber('o',
  6519. Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
  6520. break;
  6521. case 'm':
  6522. output += formatNumber('m', date.getMonth() + 1, 2);
  6523. break;
  6524. case 'M':
  6525. output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
  6526. break;
  6527. case 'y':
  6528. output += (lookAhead('y') ? date.getFullYear() :
  6529. (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
  6530. break;
  6531. case '@':
  6532. output += date.getTime();
  6533. break;
  6534. case '!':
  6535. output += date.getTime() * 10000 + this._ticksTo1970;
  6536. break;
  6537. case "'":
  6538. if (lookAhead("'"))
  6539. output += "'";
  6540. else
  6541. literal = true;
  6542. break;
  6543. default:
  6544. output += format.charAt(iFormat);
  6545. }
  6546. }
  6547. return output;
  6548. },
  6549. /* Extract all possible characters from the date format. */
  6550. _possibleChars: function (format) {
  6551. var chars = '';
  6552. var literal = false;
  6553. // Check whether a format character is doubled
  6554. var lookAhead = function(match) {
  6555. var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
  6556. if (matches)
  6557. iFormat++;
  6558. return matches;
  6559. };
  6560. for (var iFormat = 0; iFormat < format.length; iFormat++)
  6561. if (literal)
  6562. if (format.charAt(iFormat) == "'" && !lookAhead("'"))
  6563. literal = false;
  6564. else
  6565. chars += format.charAt(iFormat);
  6566. else
  6567. switch (format.charAt(iFormat)) {
  6568. case 'd': case 'm': case 'y': case '@':
  6569. chars += '0123456789';
  6570. break;
  6571. case 'D': case 'M':
  6572. return null; // Accept anything
  6573. case "'":
  6574. if (lookAhead("'"))
  6575. chars += "'";
  6576. else
  6577. literal = true;
  6578. break;
  6579. default:
  6580. chars += format.charAt(iFormat);
  6581. }
  6582. return chars;
  6583. },
  6584. /* Get a setting value, defaulting if necessary. */
  6585. _get: function(inst, name) {
  6586. return inst.settings[name] !== undefined ?
  6587. inst.settings[name] : this._defaults[name];
  6588. },
  6589. /* Parse existing date and initialise date picker. */
  6590. _setDateFromField: function(inst, noDefault) {
  6591. if (inst.input.val() == inst.lastVal) {
  6592. return;
  6593. }
  6594. var dateFormat = this._get(inst, 'dateFormat');
  6595. var dates = inst.lastVal = inst.input ? inst.input.val() : null;
  6596. var date, defaultDate;
  6597. date = defaultDate = this._getDefaultDate(inst);
  6598. var settings = this._getFormatConfig(inst);
  6599. try {
  6600. date = this.parseDate(dateFormat, dates, settings) || defaultDate;
  6601. } catch (event) {
  6602. this.log(event);
  6603. dates = (noDefault ? '' : dates);
  6604. }
  6605. inst.selectedDay = date.getDate();
  6606. inst.drawMonth = inst.selectedMonth = date.getMonth();
  6607. inst.drawYear = inst.selectedYear = date.getFullYear();
  6608. inst.currentDay = (dates ? date.getDate() : 0);
  6609. inst.currentMonth = (dates ? date.getMonth() : 0);
  6610. inst.currentYear = (dates ? date.getFullYear() : 0);
  6611. this._adjustInstDate(inst);
  6612. },
  6613. /* Retrieve the default date shown on opening. */
  6614. _getDefaultDate: function(inst) {
  6615. return this._restrictMinMax(inst,
  6616. this._determineDate(inst, this._get(inst, 'defaultDate'), new Date()));
  6617. },
  6618. /* A date may be specified as an exact value or a relative one. */
  6619. _determineDate: function(inst, date, defaultDate) {
  6620. var offsetNumeric = function(offset) {
  6621. var date = new Date();
  6622. date.setDate(date.getDate() + offset);
  6623. return date;
  6624. };
  6625. var offsetString = function(offset) {
  6626. try {
  6627. return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
  6628. offset, $.datepicker._getFormatConfig(inst));
  6629. }
  6630. catch (e) {
  6631. // Ignore
  6632. }
  6633. var date = (offset.toLowerCase().match(/^c/) ?
  6634. $.datepicker._getDate(inst) : null) || new Date();
  6635. var year = date.getFullYear();
  6636. var month = date.getMonth();
  6637. var day = date.getDate();
  6638. var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
  6639. var matches = pattern.exec(offset);
  6640. while (matches) {
  6641. switch (matches[2] || 'd') {
  6642. case 'd' : case 'D' :
  6643. day += parseInt(matches[1],10); break;
  6644. case 'w' : case 'W' :
  6645. day += parseInt(matches[1],10) * 7; break;
  6646. case 'm' : case 'M' :
  6647. month += parseInt(matches[1],10);
  6648. day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
  6649. break;
  6650. case 'y': case 'Y' :
  6651. year += parseInt(matches[1],10);
  6652. day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
  6653. break;
  6654. }
  6655. matches = pattern.exec(offset);
  6656. }
  6657. return new Date(year, month, day);
  6658. };
  6659. var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) :
  6660. (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
  6661. newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate);
  6662. if (newDate) {
  6663. newDate.setHours(0);
  6664. newDate.setMinutes(0);
  6665. newDate.setSeconds(0);
  6666. newDate.setMilliseconds(0);
  6667. }
  6668. return this._daylightSavingAdjust(newDate);
  6669. },
  6670. /* Handle switch to/from daylight saving.
  6671. Hours may be non-zero on daylight saving cut-over:
  6672. > 12 when midnight changeover, but then cannot generate
  6673. midnight datetime, so jump to 1AM, otherwise reset.
  6674. @param date (Date) the date to check
  6675. @return (Date) the corrected date */
  6676. _daylightSavingAdjust: function(date) {
  6677. if (!date) return null;
  6678. date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
  6679. return date;
  6680. },
  6681. /* Set the date(s) directly. */
  6682. _setDate: function(inst, date, noChange) {
  6683. var clear = !date;
  6684. var origMonth = inst.selectedMonth;
  6685. var origYear = inst.selectedYear;
  6686. var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
  6687. inst.selectedDay = inst.currentDay = newDate.getDate();
  6688. inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
  6689. inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
  6690. if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange)
  6691. this._notifyChange(inst);
  6692. this._adjustInstDate(inst);
  6693. if (inst.input) {
  6694. inst.input.val(clear ? '' : this._formatDate(inst));
  6695. }
  6696. },
  6697. /* Retrieve the date(s) directly. */
  6698. _getDate: function(inst) {
  6699. var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
  6700. this._daylightSavingAdjust(new Date(
  6701. inst.currentYear, inst.currentMonth, inst.currentDay)));
  6702. return startDate;
  6703. },
  6704. /* Attach the onxxx handlers. These are declared statically so
  6705. * they work with static code transformers like Caja.
  6706. */
  6707. _attachHandlers: function(inst) {
  6708. var stepMonths = this._get(inst, 'stepMonths');
  6709. var id = '#' + inst.id.replace( /\\\\/g, "\\" );
  6710. inst.dpDiv.find('[data-handler]').map(function () {
  6711. var handler = {
  6712. prev: function () {
  6713. window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, -stepMonths, 'M');
  6714. },
  6715. next: function () {
  6716. window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, +stepMonths, 'M');
  6717. },
  6718. hide: function () {
  6719. window['DP_jQuery_' + dpuuid].datepicker._hideDatepicker();
  6720. },
  6721. today: function () {
  6722. window['DP_jQuery_' + dpuuid].datepicker._gotoToday(id);
  6723. },
  6724. selectDay: function () {
  6725. window['DP_jQuery_' + dpuuid].datepicker._selectDay(id, +this.getAttribute('data-month'), +this.getAttribute('data-year'), this);
  6726. return false;
  6727. },
  6728. selectMonth: function () {
  6729. window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'M');
  6730. return false;
  6731. },
  6732. selectYear: function () {
  6733. window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'Y');
  6734. return false;
  6735. }
  6736. };
  6737. $(this).bind(this.getAttribute('data-event'), handler[this.getAttribute('data-handler')]);
  6738. });
  6739. },
  6740. /* Generate the HTML for the current state of the date picker. */
  6741. _generateHTML: function(inst) {
  6742. var today = new Date();
  6743. today = this._daylightSavingAdjust(
  6744. new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time
  6745. var isRTL = this._get(inst, 'isRTL');
  6746. var showButtonPanel = this._get(inst, 'showButtonPanel');
  6747. var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
  6748. var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
  6749. var numMonths = this._getNumberOfMonths(inst);
  6750. var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
  6751. var stepMonths = this._get(inst, 'stepMonths');
  6752. var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
  6753. var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
  6754. new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
  6755. var minDate = this._getMinMaxDate(inst, 'min');
  6756. var maxDate = this._getMinMaxDate(inst, 'max');
  6757. var drawMonth = inst.drawMonth - showCurrentAtPos;
  6758. var drawYear = inst.drawYear;
  6759. if (drawMonth < 0) {
  6760. drawMonth += 12;
  6761. drawYear--;
  6762. }
  6763. if (maxDate) {
  6764. var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
  6765. maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
  6766. maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
  6767. while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
  6768. drawMonth--;
  6769. if (drawMonth < 0) {
  6770. drawMonth = 11;
  6771. drawYear--;
  6772. }
  6773. }
  6774. }
  6775. inst.drawMonth = drawMonth;
  6776. inst.drawYear = drawYear;
  6777. var prevText = this._get(inst, 'prevText');
  6778. prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
  6779. this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
  6780. this._getFormatConfig(inst)));
  6781. var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
  6782. '<a class="ui-datepicker-prev ui-corner-all" data-handler="prev" data-event="click"' +
  6783. ' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' :
  6784. (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>'));
  6785. var nextText = this._get(inst, 'nextText');
  6786. nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
  6787. this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
  6788. this._getFormatConfig(inst)));
  6789. var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
  6790. '<a class="ui-datepicker-next ui-corner-all" data-handler="next" data-event="click"' +
  6791. ' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' :
  6792. (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>'));
  6793. var currentText = this._get(inst, 'currentText');
  6794. var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
  6795. currentText = (!navigationAsDateFormat ? currentText :
  6796. this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
  6797. 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">' +
  6798. this._get(inst, 'closeText') + '</button>' : '');
  6799. var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') +
  6800. (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"' +
  6801. '>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';
  6802. var firstDay = parseInt(this._get(inst, 'firstDay'),10);
  6803. firstDay = (isNaN(firstDay) ? 0 : firstDay);
  6804. var showWeek = this._get(inst, 'showWeek');
  6805. var dayNames = this._get(inst, 'dayNames');
  6806. var dayNamesShort = this._get(inst, 'dayNamesShort');
  6807. var dayNamesMin = this._get(inst, 'dayNamesMin');
  6808. var monthNames = this._get(inst, 'monthNames');
  6809. var monthNamesShort = this._get(inst, 'monthNamesShort');
  6810. var beforeShowDay = this._get(inst, 'beforeShowDay');
  6811. var showOtherMonths = this._get(inst, 'showOtherMonths');
  6812. var selectOtherMonths = this._get(inst, 'selectOtherMonths');
  6813. var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
  6814. var defaultDate = this._getDefaultDate(inst);
  6815. var html = '';
  6816. for (var row = 0; row < numMonths[0]; row++) {
  6817. var group = '';
  6818. this.maxRows = 4;
  6819. for (var col = 0; col < numMonths[1]; col++) {
  6820. var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
  6821. var cornerClass = ' ui-corner-all';
  6822. var calender = '';
  6823. if (isMultiMonth) {
  6824. calender += '<div class="ui-datepicker-group';
  6825. if (numMonths[1] > 1)
  6826. switch (col) {
  6827. case 0: calender += ' ui-datepicker-group-first';
  6828. cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break;
  6829. case numMonths[1]-1: calender += ' ui-datepicker-group-last';
  6830. cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break;
  6831. default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break;
  6832. }
  6833. calender += '">';
  6834. }
  6835. calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' +
  6836. (/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +
  6837. (/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +
  6838. this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
  6839. row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
  6840. '</div><table class="ui-datepicker-calendar"><thead>' +
  6841. '<tr>';
  6842. var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : '');
  6843. for (var dow = 0; dow < 7; dow++) { // days of the week
  6844. var day = (dow + firstDay) % 7;
  6845. thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' +
  6846. '<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>';
  6847. }
  6848. calender += thead + '</tr></thead><tbody>';
  6849. var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
  6850. if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
  6851. inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
  6852. var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
  6853. var curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
  6854. var numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
  6855. this.maxRows = numRows;
  6856. var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
  6857. for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
  6858. calender += '<tr>';
  6859. var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' +
  6860. this._get(inst, 'calculateWeek')(printDate) + '</td>');
  6861. for (var dow = 0; dow < 7; dow++) { // create date picker days
  6862. var daySettings = (beforeShowDay ?
  6863. beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
  6864. var otherMonth = (printDate.getMonth() != drawMonth);
  6865. var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
  6866. (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
  6867. tbody += '<td class="' +
  6868. ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends
  6869. (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
  6870. ((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key
  6871. (defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
  6872. // or defaultDate is current printedDate and defaultDate is selectedDate
  6873. ' ' + this._dayOverClass : '') + // highlight selected day
  6874. (unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') + // highlight unselectable days
  6875. (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
  6876. (printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day
  6877. (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
  6878. ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
  6879. (unselectable ? '' : ' data-handler="selectDay" data-event="click" data-month="' + printDate.getMonth() + '" data-year="' + printDate.getFullYear() + '"') + '>' + // actions
  6880. (otherMonth && !showOtherMonths ? '&#xa0;' : // display for other months
  6881. (unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' +
  6882. (printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') +
  6883. (printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day
  6884. (otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months
  6885. '" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date
  6886. printDate.setDate(printDate.getDate() + 1);
  6887. printDate = this._daylightSavingAdjust(printDate);
  6888. }
  6889. calender += tbody + '</tr>';
  6890. }
  6891. drawMonth++;
  6892. if (drawMonth > 11) {
  6893. drawMonth = 0;
  6894. drawYear++;
  6895. }
  6896. calender += '</tbody></table>' + (isMultiMonth ? '</div>' +
  6897. ((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
  6898. group += calender;
  6899. }
  6900. html += group;
  6901. }
  6902. html += buttonPanel + ($.ui.ie6 && !inst.inline ?
  6903. '<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
  6904. inst._keyEvent = false;
  6905. return html;
  6906. },
  6907. /* Generate the month and year header. */
  6908. _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
  6909. secondary, monthNames, monthNamesShort) {
  6910. var changeMonth = this._get(inst, 'changeMonth');
  6911. var changeYear = this._get(inst, 'changeYear');
  6912. var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
  6913. var html = '<div class="ui-datepicker-title">';
  6914. var monthHtml = '';
  6915. // month selection
  6916. if (secondary || !changeMonth)
  6917. monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>';
  6918. else {
  6919. var inMinYear = (minDate && minDate.getFullYear() == drawYear);
  6920. var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
  6921. monthHtml += '<select class="ui-datepicker-month" data-handler="selectMonth" data-event="change">';
  6922. for (var month = 0; month < 12; month++) {
  6923. if ((!inMinYear || month >= minDate.getMonth()) &&
  6924. (!inMaxYear || month <= maxDate.getMonth()))
  6925. monthHtml += '<option value="' + month + '"' +
  6926. (month == drawMonth ? ' selected="selected"' : '') +
  6927. '>' + monthNamesShort[month] + '</option>';
  6928. }
  6929. monthHtml += '</select>';
  6930. }
  6931. if (!showMonthAfterYear)
  6932. html += monthHtml + (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '');
  6933. // year selection
  6934. if ( !inst.yearshtml ) {
  6935. inst.yearshtml = '';
  6936. if (secondary || !changeYear)
  6937. html += '<span class="ui-datepicker-year">' + drawYear + '</span>';
  6938. else {
  6939. // determine range of years to display
  6940. var years = this._get(inst, 'yearRange').split(':');
  6941. var thisYear = new Date().getFullYear();
  6942. var determineYear = function(value) {
  6943. var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) :
  6944. (value.match(/[+-].*/) ? thisYear + parseInt(value, 10) :
  6945. parseInt(value, 10)));
  6946. return (isNaN(year) ? thisYear : year);
  6947. };
  6948. var year = determineYear(years[0]);
  6949. var endYear = Math.max(year, determineYear(years[1] || ''));
  6950. year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
  6951. endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
  6952. inst.yearshtml += '<select class="ui-datepicker-year" data-handler="selectYear" data-event="change">';
  6953. for (; year <= endYear; year++) {
  6954. inst.yearshtml += '<option value="' + year + '"' +
  6955. (year == drawYear ? ' selected="selected"' : '') +
  6956. '>' + year + '</option>';
  6957. }
  6958. inst.yearshtml += '</select>';
  6959. html += inst.yearshtml;
  6960. inst.yearshtml = null;
  6961. }
  6962. }
  6963. html += this._get(inst, 'yearSuffix');
  6964. if (showMonthAfterYear)
  6965. html += (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '') + monthHtml;
  6966. html += '</div>'; // Close datepicker_header
  6967. return html;
  6968. },
  6969. /* Adjust one of the date sub-fields. */
  6970. _adjustInstDate: function(inst, offset, period) {
  6971. var year = inst.drawYear + (period == 'Y' ? offset : 0);
  6972. var month = inst.drawMonth + (period == 'M' ? offset : 0);
  6973. var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
  6974. (period == 'D' ? offset : 0);
  6975. var date = this._restrictMinMax(inst,
  6976. this._daylightSavingAdjust(new Date(year, month, day)));
  6977. inst.selectedDay = date.getDate();
  6978. inst.drawMonth = inst.selectedMonth = date.getMonth();
  6979. inst.drawYear = inst.selectedYear = date.getFullYear();
  6980. if (period == 'M' || period == 'Y')
  6981. this._notifyChange(inst);
  6982. },
  6983. /* Ensure a date is within any min/max bounds. */
  6984. _restrictMinMax: function(inst, date) {
  6985. var minDate = this._getMinMaxDate(inst, 'min');
  6986. var maxDate = this._getMinMaxDate(inst, 'max');
  6987. var newDate = (minDate && date < minDate ? minDate : date);
  6988. newDate = (maxDate && newDate > maxDate ? maxDate : newDate);
  6989. return newDate;
  6990. },
  6991. /* Notify change of month/year. */
  6992. _notifyChange: function(inst) {
  6993. var onChange = this._get(inst, 'onChangeMonthYear');
  6994. if (onChange)
  6995. onChange.apply((inst.input ? inst.input[0] : null),
  6996. [inst.selectedYear, inst.selectedMonth + 1, inst]);
  6997. },
  6998. /* Determine the number of months to show. */
  6999. _getNumberOfMonths: function(inst) {
  7000. var numMonths = this._get(inst, 'numberOfMonths');
  7001. return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
  7002. },
  7003. /* Determine the current maximum date - ensure no time components are set. */
  7004. _getMinMaxDate: function(inst, minMax) {
  7005. return this._determineDate(inst, this._get(inst, minMax + 'Date'), null);
  7006. },
  7007. /* Find the number of days in a given month. */
  7008. _getDaysInMonth: function(year, month) {
  7009. return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
  7010. },
  7011. /* Find the day of the week of the first of a month. */
  7012. _getFirstDayOfMonth: function(year, month) {
  7013. return new Date(year, month, 1).getDay();
  7014. },
  7015. /* Determines if we should allow a "next/prev" month display change. */
  7016. _canAdjustMonth: function(inst, offset, curYear, curMonth) {
  7017. var numMonths = this._getNumberOfMonths(inst);
  7018. var date = this._daylightSavingAdjust(new Date(curYear,
  7019. curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
  7020. if (offset < 0)
  7021. date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
  7022. return this._isInRange(inst, date);
  7023. },
  7024. /* Is the given date in the accepted range? */
  7025. _isInRange: function(inst, date) {
  7026. var minDate = this._getMinMaxDate(inst, 'min');
  7027. var maxDate = this._getMinMaxDate(inst, 'max');
  7028. return ((!minDate || date.getTime() >= minDate.getTime()) &&
  7029. (!maxDate || date.getTime() <= maxDate.getTime()));
  7030. },
  7031. /* Provide the configuration settings for formatting/parsing. */
  7032. _getFormatConfig: function(inst) {
  7033. var shortYearCutoff = this._get(inst, 'shortYearCutoff');
  7034. shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
  7035. new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
  7036. return {shortYearCutoff: shortYearCutoff,
  7037. dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
  7038. monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
  7039. },
  7040. /* Format the given date for display. */
  7041. _formatDate: function(inst, day, month, year) {
  7042. if (!day) {
  7043. inst.currentDay = inst.selectedDay;
  7044. inst.currentMonth = inst.selectedMonth;
  7045. inst.currentYear = inst.selectedYear;
  7046. }
  7047. var date = (day ? (typeof day == 'object' ? day :
  7048. this._daylightSavingAdjust(new Date(year, month, day))) :
  7049. this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
  7050. return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
  7051. }
  7052. });
  7053. /*
  7054. * Bind hover events for datepicker elements.
  7055. * Done via delegate so the binding only occurs once in the lifetime of the parent div.
  7056. * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
  7057. */
  7058. function bindHover(dpDiv) {
  7059. var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a';
  7060. return dpDiv.delegate(selector, 'mouseout', function() {
  7061. $(this).removeClass('ui-state-hover');
  7062. if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover');
  7063. if (this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover');
  7064. })
  7065. .delegate(selector, 'mouseover', function(){
  7066. if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) {
  7067. $(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');
  7068. $(this).addClass('ui-state-hover');
  7069. if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover');
  7070. if (this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover');
  7071. }
  7072. });
  7073. }
  7074. /* jQuery extend now ignores nulls! */
  7075. function extendRemove(target, props) {
  7076. $.extend(target, props);
  7077. for (var name in props)
  7078. if (props[name] == null || props[name] == undefined)
  7079. target[name] = props[name];
  7080. return target;
  7081. };
  7082. /* Invoke the datepicker functionality.
  7083. @param options string - a command, optionally followed by additional parameters or
  7084. Object - settings for attaching new datepicker functionality
  7085. @return jQuery object */
  7086. $.fn.datepicker = function(options){
  7087. /* Verify an empty collection wasn't passed - Fixes #6976 */
  7088. if ( !this.length ) {
  7089. return this;
  7090. }
  7091. /* Initialise the date picker. */
  7092. if (!$.datepicker.initialized) {
  7093. $(document).mousedown($.datepicker._checkExternalClick).
  7094. find(document.body).append($.datepicker.dpDiv);
  7095. $.datepicker.initialized = true;
  7096. }
  7097. var otherArgs = Array.prototype.slice.call(arguments, 1);
  7098. if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget'))
  7099. return $.datepicker['_' + options + 'Datepicker'].
  7100. apply($.datepicker, [this[0]].concat(otherArgs));
  7101. if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string')
  7102. return $.datepicker['_' + options + 'Datepicker'].
  7103. apply($.datepicker, [this[0]].concat(otherArgs));
  7104. return this.each(function() {
  7105. typeof options == 'string' ?
  7106. $.datepicker['_' + options + 'Datepicker'].
  7107. apply($.datepicker, [this].concat(otherArgs)) :
  7108. $.datepicker._attachDatepicker(this, options);
  7109. });
  7110. };
  7111. $.datepicker = new Datepicker(); // singleton instance
  7112. $.datepicker.initialized = false;
  7113. $.datepicker.uuid = new Date().getTime();
  7114. $.datepicker.version = "1.9.2";
  7115. // Workaround for #4055
  7116. // Add another global to avoid noConflict issues with inline event handlers
  7117. window['DP_jQuery_' + dpuuid] = $;
  7118. })(jQuery);
  7119. (function( $, undefined ) {
  7120. var uiDialogClasses = "ui-dialog ui-widget ui-widget-content ui-corner-all ",
  7121. sizeRelatedOptions = {
  7122. buttons: true,
  7123. height: true,
  7124. maxHeight: true,
  7125. maxWidth: true,
  7126. minHeight: true,
  7127. minWidth: true,
  7128. width: true
  7129. },
  7130. resizableRelatedOptions = {
  7131. maxHeight: true,
  7132. maxWidth: true,
  7133. minHeight: true,
  7134. minWidth: true
  7135. };
  7136. $.widget("ui.dialog", {
  7137. version: "1.9.2",
  7138. options: {
  7139. autoOpen: true,
  7140. buttons: {},
  7141. closeOnEscape: true,
  7142. closeText: "close",
  7143. dialogClass: "",
  7144. draggable: true,
  7145. hide: null,
  7146. height: "auto",
  7147. maxHeight: false,
  7148. maxWidth: false,
  7149. minHeight: 150,
  7150. minWidth: 150,
  7151. modal: false,
  7152. position: {
  7153. my: "center",
  7154. at: "center",
  7155. of: window,
  7156. collision: "fit",
  7157. // ensure that the titlebar is never outside the document
  7158. using: function( pos ) {
  7159. var topOffset = $( this ).css( pos ).offset().top;
  7160. if ( topOffset < 0 ) {
  7161. $( this ).css( "top", pos.top - topOffset );
  7162. }
  7163. }
  7164. },
  7165. resizable: true,
  7166. show: null,
  7167. stack: true,
  7168. title: "",
  7169. width: 300,
  7170. zIndex: 1000
  7171. },
  7172. _create: function() {
  7173. this.originalTitle = this.element.attr( "title" );
  7174. // #5742 - .attr() might return a DOMElement
  7175. if ( typeof this.originalTitle !== "string" ) {
  7176. this.originalTitle = "";
  7177. }
  7178. this.oldPosition = {
  7179. parent: this.element.parent(),
  7180. index: this.element.parent().children().index( this.element )
  7181. };
  7182. this.options.title = this.options.title || this.originalTitle;
  7183. var that = this,
  7184. options = this.options,
  7185. title = options.title || "&#160;",
  7186. uiDialog,
  7187. uiDialogTitlebar,
  7188. uiDialogTitlebarClose,
  7189. uiDialogTitle,
  7190. uiDialogButtonPane;
  7191. uiDialog = ( this.uiDialog = $( "<div>" ) )
  7192. .addClass( uiDialogClasses + options.dialogClass )
  7193. .css({
  7194. display: "none",
  7195. outline: 0, // TODO: move to stylesheet
  7196. zIndex: options.zIndex
  7197. })
  7198. // setting tabIndex makes the div focusable
  7199. .attr( "tabIndex", -1)
  7200. .keydown(function( event ) {
  7201. if ( options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
  7202. event.keyCode === $.ui.keyCode.ESCAPE ) {
  7203. that.close( event );
  7204. event.preventDefault();
  7205. }
  7206. })
  7207. .mousedown(function( event ) {
  7208. that.moveToTop( false, event );
  7209. })
  7210. .appendTo( "body" );
  7211. this.element
  7212. .show()
  7213. .removeAttr( "title" )
  7214. .addClass( "ui-dialog-content ui-widget-content" )
  7215. .appendTo( uiDialog );
  7216. uiDialogTitlebar = ( this.uiDialogTitlebar = $( "<div>" ) )
  7217. .addClass( "ui-dialog-titlebar ui-widget-header " +
  7218. "ui-corner-all ui-helper-clearfix" )
  7219. .bind( "mousedown", function() {
  7220. // Dialog isn't getting focus when dragging (#8063)
  7221. uiDialog.focus();
  7222. })
  7223. .prependTo( uiDialog );
  7224. uiDialogTitlebarClose = $( "<a href='#'></a>" )
  7225. .addClass( "ui-dialog-titlebar-close ui-corner-all" )
  7226. .attr( "role", "button" )
  7227. .click(function( event ) {
  7228. event.preventDefault();
  7229. that.close( event );
  7230. })
  7231. .appendTo( uiDialogTitlebar );
  7232. ( this.uiDialogTitlebarCloseText = $( "<span>" ) )
  7233. .addClass( "ui-icon ui-icon-closethick" )
  7234. .text( options.closeText )
  7235. .appendTo( uiDialogTitlebarClose );
  7236. uiDialogTitle = $( "<span>" )
  7237. .uniqueId()
  7238. .addClass( "ui-dialog-title" )
  7239. .html( title )
  7240. .prependTo( uiDialogTitlebar );
  7241. uiDialogButtonPane = ( this.uiDialogButtonPane = $( "<div>" ) )
  7242. .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );
  7243. ( this.uiButtonSet = $( "<div>" ) )
  7244. .addClass( "ui-dialog-buttonset" )
  7245. .appendTo( uiDialogButtonPane );
  7246. uiDialog.attr({
  7247. role: "dialog",
  7248. "aria-labelledby": uiDialogTitle.attr( "id" )
  7249. });
  7250. uiDialogTitlebar.find( "*" ).add( uiDialogTitlebar ).disableSelection();
  7251. this._hoverable( uiDialogTitlebarClose );
  7252. this._focusable( uiDialogTitlebarClose );
  7253. if ( options.draggable && $.fn.draggable ) {
  7254. this._makeDraggable();
  7255. }
  7256. if ( options.resizable && $.fn.resizable ) {
  7257. this._makeResizable();
  7258. }
  7259. this._createButtons( options.buttons );
  7260. this._isOpen = false;
  7261. if ( $.fn.bgiframe ) {
  7262. uiDialog.bgiframe();
  7263. }
  7264. // prevent tabbing out of modal dialogs
  7265. this._on( uiDialog, { keydown: function( event ) {
  7266. if ( !options.modal || event.keyCode !== $.ui.keyCode.TAB ) {
  7267. return;
  7268. }
  7269. var tabbables = $( ":tabbable", uiDialog ),
  7270. first = tabbables.filter( ":first" ),
  7271. last = tabbables.filter( ":last" );
  7272. if ( event.target === last[0] && !event.shiftKey ) {
  7273. first.focus( 1 );
  7274. return false;
  7275. } else if ( event.target === first[0] && event.shiftKey ) {
  7276. last.focus( 1 );
  7277. return false;
  7278. }
  7279. }});
  7280. },
  7281. _init: function() {
  7282. if ( this.options.autoOpen ) {
  7283. this.open();
  7284. }
  7285. },
  7286. _destroy: function() {
  7287. var next,
  7288. oldPosition = this.oldPosition;
  7289. if ( this.overlay ) {
  7290. this.overlay.destroy();
  7291. }
  7292. this.uiDialog.hide();
  7293. this.element
  7294. .removeClass( "ui-dialog-content ui-widget-content" )
  7295. .hide()
  7296. .appendTo( "body" );
  7297. this.uiDialog.remove();
  7298. if ( this.originalTitle ) {
  7299. this.element.attr( "title", this.originalTitle );
  7300. }
  7301. next = oldPosition.parent.children().eq( oldPosition.index );
  7302. // Don't try to place the dialog next to itself (#8613)
  7303. if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
  7304. next.before( this.element );
  7305. } else {
  7306. oldPosition.parent.append( this.element );
  7307. }
  7308. },
  7309. widget: function() {
  7310. return this.uiDialog;
  7311. },
  7312. close: function( event ) {
  7313. var that = this,
  7314. maxZ, thisZ;
  7315. if ( !this._isOpen ) {
  7316. return;
  7317. }
  7318. if ( false === this._trigger( "beforeClose", event ) ) {
  7319. return;
  7320. }
  7321. this._isOpen = false;
  7322. if ( this.overlay ) {
  7323. this.overlay.destroy();
  7324. }
  7325. if ( this.options.hide ) {
  7326. this._hide( this.uiDialog, this.options.hide, function() {
  7327. that._trigger( "close", event );
  7328. });
  7329. } else {
  7330. this.uiDialog.hide();
  7331. this._trigger( "close", event );
  7332. }
  7333. $.ui.dialog.overlay.resize();
  7334. // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
  7335. if ( this.options.modal ) {
  7336. maxZ = 0;
  7337. $( ".ui-dialog" ).each(function() {
  7338. if ( this !== that.uiDialog[0] ) {
  7339. thisZ = $( this ).css( "z-index" );
  7340. if ( !isNaN( thisZ ) ) {
  7341. maxZ = Math.max( maxZ, thisZ );
  7342. }
  7343. }
  7344. });
  7345. $.ui.dialog.maxZ = maxZ;
  7346. }
  7347. return this;
  7348. },
  7349. isOpen: function() {
  7350. return this._isOpen;
  7351. },
  7352. // the force parameter allows us to move modal dialogs to their correct
  7353. // position on open
  7354. moveToTop: function( force, event ) {
  7355. var options = this.options,
  7356. saveScroll;
  7357. if ( ( options.modal && !force ) ||
  7358. ( !options.stack && !options.modal ) ) {
  7359. return this._trigger( "focus", event );
  7360. }
  7361. if ( options.zIndex > $.ui.dialog.maxZ ) {
  7362. $.ui.dialog.maxZ = options.zIndex;
  7363. }
  7364. if ( this.overlay ) {
  7365. $.ui.dialog.maxZ += 1;
  7366. $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ;
  7367. this.overlay.$el.css( "z-index", $.ui.dialog.overlay.maxZ );
  7368. }
  7369. // Save and then restore scroll
  7370. // Opera 9.5+ resets when parent z-index is changed.
  7371. // http://bugs.jqueryui.com/ticket/3193
  7372. saveScroll = {
  7373. scrollTop: this.element.scrollTop(),
  7374. scrollLeft: this.element.scrollLeft()
  7375. };
  7376. $.ui.dialog.maxZ += 1;
  7377. this.uiDialog.css( "z-index", $.ui.dialog.maxZ );
  7378. this.element.attr( saveScroll );
  7379. this._trigger( "focus", event );
  7380. return this;
  7381. },
  7382. open: function() {
  7383. if ( this._isOpen ) {
  7384. return;
  7385. }
  7386. var hasFocus,
  7387. options = this.options,
  7388. uiDialog = this.uiDialog;
  7389. this._size();
  7390. this._position( options.position );
  7391. uiDialog.show( options.show );
  7392. this.overlay = options.modal ? new $.ui.dialog.overlay( this ) : null;
  7393. this.moveToTop( true );
  7394. // set focus to the first tabbable element in the content area or the first button
  7395. // if there are no tabbable elements, set focus on the dialog itself
  7396. hasFocus = this.element.find( ":tabbable" );
  7397. if ( !hasFocus.length ) {
  7398. hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
  7399. if ( !hasFocus.length ) {
  7400. hasFocus = uiDialog;
  7401. }
  7402. }
  7403. hasFocus.eq( 0 ).focus();
  7404. this._isOpen = true;
  7405. this._trigger( "open" );
  7406. return this;
  7407. },
  7408. _createButtons: function( buttons ) {
  7409. var that = this,
  7410. hasButtons = false;
  7411. // if we already have a button pane, remove it
  7412. this.uiDialogButtonPane.remove();
  7413. this.uiButtonSet.empty();
  7414. if ( typeof buttons === "object" && buttons !== null ) {
  7415. $.each( buttons, function() {
  7416. return !(hasButtons = true);
  7417. });
  7418. }
  7419. if ( hasButtons ) {
  7420. $.each( buttons, function( name, props ) {
  7421. var button, click;
  7422. props = $.isFunction( props ) ?
  7423. { click: props, text: name } :
  7424. props;
  7425. // Default to a non-submitting button
  7426. props = $.extend( { type: "button" }, props );
  7427. // Change the context for the click callback to be the main element
  7428. click = props.click;
  7429. props.click = function() {
  7430. click.apply( that.element[0], arguments );
  7431. };
  7432. button = $( "<button></button>", props )
  7433. .appendTo( that.uiButtonSet );
  7434. if ( $.fn.button ) {
  7435. button.button();
  7436. }
  7437. });
  7438. this.uiDialog.addClass( "ui-dialog-buttons" );
  7439. this.uiDialogButtonPane.appendTo( this.uiDialog );
  7440. } else {
  7441. this.uiDialog.removeClass( "ui-dialog-buttons" );
  7442. }
  7443. },
  7444. _makeDraggable: function() {
  7445. var that = this,
  7446. options = this.options;
  7447. function filteredUi( ui ) {
  7448. return {
  7449. position: ui.position,
  7450. offset: ui.offset
  7451. };
  7452. }
  7453. this.uiDialog.draggable({
  7454. cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
  7455. handle: ".ui-dialog-titlebar",
  7456. containment: "document",
  7457. start: function( event, ui ) {
  7458. $( this )
  7459. .addClass( "ui-dialog-dragging" );
  7460. that._trigger( "dragStart", event, filteredUi( ui ) );
  7461. },
  7462. drag: function( event, ui ) {
  7463. that._trigger( "drag", event, filteredUi( ui ) );
  7464. },
  7465. stop: function( event, ui ) {
  7466. options.position = [
  7467. ui.position.left - that.document.scrollLeft(),
  7468. ui.position.top - that.document.scrollTop()
  7469. ];
  7470. $( this )
  7471. .removeClass( "ui-dialog-dragging" );
  7472. that._trigger( "dragStop", event, filteredUi( ui ) );
  7473. $.ui.dialog.overlay.resize();
  7474. }
  7475. });
  7476. },
  7477. _makeResizable: function( handles ) {
  7478. handles = (handles === undefined ? this.options.resizable : handles);
  7479. var that = this,
  7480. options = this.options,
  7481. // .ui-resizable has position: relative defined in the stylesheet
  7482. // but dialogs have to use absolute or fixed positioning
  7483. position = this.uiDialog.css( "position" ),
  7484. resizeHandles = typeof handles === 'string' ?
  7485. handles :
  7486. "n,e,s,w,se,sw,ne,nw";
  7487. function filteredUi( ui ) {
  7488. return {
  7489. originalPosition: ui.originalPosition,
  7490. originalSize: ui.originalSize,
  7491. position: ui.position,
  7492. size: ui.size
  7493. };
  7494. }
  7495. this.uiDialog.resizable({
  7496. cancel: ".ui-dialog-content",
  7497. containment: "document",
  7498. alsoResize: this.element,
  7499. maxWidth: options.maxWidth,
  7500. maxHeight: options.maxHeight,
  7501. minWidth: options.minWidth,
  7502. minHeight: this._minHeight(),
  7503. handles: resizeHandles,
  7504. start: function( event, ui ) {
  7505. $( this ).addClass( "ui-dialog-resizing" );
  7506. that._trigger( "resizeStart", event, filteredUi( ui ) );
  7507. },
  7508. resize: function( event, ui ) {
  7509. that._trigger( "resize", event, filteredUi( ui ) );
  7510. },
  7511. stop: function( event, ui ) {
  7512. $( this ).removeClass( "ui-dialog-resizing" );
  7513. options.height = $( this ).height();
  7514. options.width = $( this ).width();
  7515. that._trigger( "resizeStop", event, filteredUi( ui ) );
  7516. $.ui.dialog.overlay.resize();
  7517. }
  7518. })
  7519. .css( "position", position )
  7520. .find( ".ui-resizable-se" )
  7521. .addClass( "ui-icon ui-icon-grip-diagonal-se" );
  7522. },
  7523. _minHeight: function() {
  7524. var options = this.options;
  7525. if ( options.height === "auto" ) {
  7526. return options.minHeight;
  7527. } else {
  7528. return Math.min( options.minHeight, options.height );
  7529. }
  7530. },
  7531. _position: function( position ) {
  7532. var myAt = [],
  7533. offset = [ 0, 0 ],
  7534. isVisible;
  7535. if ( position ) {
  7536. // deep extending converts arrays to objects in jQuery <= 1.3.2 :-(
  7537. // if (typeof position == 'string' || $.isArray(position)) {
  7538. // myAt = $.isArray(position) ? position : position.split(' ');
  7539. if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) {
  7540. myAt = position.split ? position.split( " " ) : [ position[ 0 ], position[ 1 ] ];
  7541. if ( myAt.length === 1 ) {
  7542. myAt[ 1 ] = myAt[ 0 ];
  7543. }
  7544. $.each( [ "left", "top" ], function( i, offsetPosition ) {
  7545. if ( +myAt[ i ] === myAt[ i ] ) {
  7546. offset[ i ] = myAt[ i ];
  7547. myAt[ i ] = offsetPosition;
  7548. }
  7549. });
  7550. position = {
  7551. my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " +
  7552. myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]),
  7553. at: myAt.join( " " )
  7554. };
  7555. }
  7556. position = $.extend( {}, $.ui.dialog.prototype.options.position, position );
  7557. } else {
  7558. position = $.ui.dialog.prototype.options.position;
  7559. }
  7560. // need to show the dialog to get the actual offset in the position plugin
  7561. isVisible = this.uiDialog.is( ":visible" );
  7562. if ( !isVisible ) {
  7563. this.uiDialog.show();
  7564. }
  7565. this.uiDialog.position( position );
  7566. if ( !isVisible ) {
  7567. this.uiDialog.hide();
  7568. }
  7569. },
  7570. _setOptions: function( options ) {
  7571. var that = this,
  7572. resizableOptions = {},
  7573. resize = false;
  7574. $.each( options, function( key, value ) {
  7575. that._setOption( key, value );
  7576. if ( key in sizeRelatedOptions ) {
  7577. resize = true;
  7578. }
  7579. if ( key in resizableRelatedOptions ) {
  7580. resizableOptions[ key ] = value;
  7581. }
  7582. });
  7583. if ( resize ) {
  7584. this._size();
  7585. }
  7586. if ( this.uiDialog.is( ":data(resizable)" ) ) {
  7587. this.uiDialog.resizable( "option", resizableOptions );
  7588. }
  7589. },
  7590. _setOption: function( key, value ) {
  7591. var isDraggable, isResizable,
  7592. uiDialog = this.uiDialog;
  7593. switch ( key ) {
  7594. case "buttons":
  7595. this._createButtons( value );
  7596. break;
  7597. case "closeText":
  7598. // ensure that we always pass a string
  7599. this.uiDialogTitlebarCloseText.text( "" + value );
  7600. break;
  7601. case "dialogClass":
  7602. uiDialog
  7603. .removeClass( this.options.dialogClass )
  7604. .addClass( uiDialogClasses + value );
  7605. break;
  7606. case "disabled":
  7607. if ( value ) {
  7608. uiDialog.addClass( "ui-dialog-disabled" );
  7609. } else {
  7610. uiDialog.removeClass( "ui-dialog-disabled" );
  7611. }
  7612. break;
  7613. case "draggable":
  7614. isDraggable = uiDialog.is( ":data(draggable)" );
  7615. if ( isDraggable && !value ) {
  7616. uiDialog.draggable( "destroy" );
  7617. }
  7618. if ( !isDraggable && value ) {
  7619. this._makeDraggable();
  7620. }
  7621. break;
  7622. case "position":
  7623. this._position( value );
  7624. break;
  7625. case "resizable":
  7626. // currently resizable, becoming non-resizable
  7627. isResizable = uiDialog.is( ":data(resizable)" );
  7628. if ( isResizable && !value ) {
  7629. uiDialog.resizable( "destroy" );
  7630. }
  7631. // currently resizable, changing handles
  7632. if ( isResizable && typeof value === "string" ) {
  7633. uiDialog.resizable( "option", "handles", value );
  7634. }
  7635. // currently non-resizable, becoming resizable
  7636. if ( !isResizable && value !== false ) {
  7637. this._makeResizable( value );
  7638. }
  7639. break;
  7640. case "title":
  7641. // convert whatever was passed in o a string, for html() to not throw up
  7642. $( ".ui-dialog-title", this.uiDialogTitlebar )
  7643. .html( "" + ( value || "&#160;" ) );
  7644. break;
  7645. }
  7646. this._super( key, value );
  7647. },
  7648. _size: function() {
  7649. /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
  7650. * divs will both have width and height set, so we need to reset them
  7651. */
  7652. var nonContentHeight, minContentHeight, autoHeight,
  7653. options = this.options,
  7654. isVisible = this.uiDialog.is( ":visible" );
  7655. // reset content sizing
  7656. this.element.show().css({
  7657. width: "auto",
  7658. minHeight: 0,
  7659. height: 0
  7660. });
  7661. if ( options.minWidth > options.width ) {
  7662. options.width = options.minWidth;
  7663. }
  7664. // reset wrapper sizing
  7665. // determine the height of all the non-content elements
  7666. nonContentHeight = this.uiDialog.css({
  7667. height: "auto",
  7668. width: options.width
  7669. })
  7670. .outerHeight();
  7671. minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
  7672. if ( options.height === "auto" ) {
  7673. // only needed for IE6 support
  7674. if ( $.support.minHeight ) {
  7675. this.element.css({
  7676. minHeight: minContentHeight,
  7677. height: "auto"
  7678. });
  7679. } else {
  7680. this.uiDialog.show();
  7681. autoHeight = this.element.css( "height", "auto" ).height();
  7682. if ( !isVisible ) {
  7683. this.uiDialog.hide();
  7684. }
  7685. this.element.height( Math.max( autoHeight, minContentHeight ) );
  7686. }
  7687. } else {
  7688. this.element.height( Math.max( options.height - nonContentHeight, 0 ) );
  7689. }
  7690. if (this.uiDialog.is( ":data(resizable)" ) ) {
  7691. this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
  7692. }
  7693. }
  7694. });
  7695. $.extend($.ui.dialog, {
  7696. uuid: 0,
  7697. maxZ: 0,
  7698. getTitleId: function($el) {
  7699. var id = $el.attr( "id" );
  7700. if ( !id ) {
  7701. this.uuid += 1;
  7702. id = this.uuid;
  7703. }
  7704. return "ui-dialog-title-" + id;
  7705. },
  7706. overlay: function( dialog ) {
  7707. this.$el = $.ui.dialog.overlay.create( dialog );
  7708. }
  7709. });
  7710. $.extend( $.ui.dialog.overlay, {
  7711. instances: [],
  7712. // reuse old instances due to IE memory leak with alpha transparency (see #5185)
  7713. oldInstances: [],
  7714. maxZ: 0,
  7715. events: $.map(
  7716. "focus,mousedown,mouseup,keydown,keypress,click".split( "," ),
  7717. function( event ) {
  7718. return event + ".dialog-overlay";
  7719. }
  7720. ).join( " " ),
  7721. create: function( dialog ) {
  7722. if ( this.instances.length === 0 ) {
  7723. // prevent use of anchors and inputs
  7724. // we use a setTimeout in case the overlay is created from an
  7725. // event that we're going to be cancelling (see #2804)
  7726. setTimeout(function() {
  7727. // handle $(el).dialog().dialog('close') (see #4065)
  7728. if ( $.ui.dialog.overlay.instances.length ) {
  7729. $( document ).bind( $.ui.dialog.overlay.events, function( event ) {
  7730. // stop events if the z-index of the target is < the z-index of the overlay
  7731. // we cannot return true when we don't want to cancel the event (#3523)
  7732. if ( $( event.target ).zIndex() < $.ui.dialog.overlay.maxZ ) {
  7733. return false;
  7734. }
  7735. });
  7736. }
  7737. }, 1 );
  7738. // handle window resize
  7739. $( window ).bind( "resize.dialog-overlay", $.ui.dialog.overlay.resize );
  7740. }
  7741. var $el = ( this.oldInstances.pop() || $( "<div>" ).addClass( "ui-widget-overlay" ) );
  7742. // allow closing by pressing the escape key
  7743. $( document ).bind( "keydown.dialog-overlay", function( event ) {
  7744. var instances = $.ui.dialog.overlay.instances;
  7745. // only react to the event if we're the top overlay
  7746. if ( instances.length !== 0 && instances[ instances.length - 1 ] === $el &&
  7747. dialog.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
  7748. event.keyCode === $.ui.keyCode.ESCAPE ) {
  7749. dialog.close( event );
  7750. event.preventDefault();
  7751. }
  7752. });
  7753. $el.appendTo( document.body ).css({
  7754. width: this.width(),
  7755. height: this.height()
  7756. });
  7757. if ( $.fn.bgiframe ) {
  7758. $el.bgiframe();
  7759. }
  7760. this.instances.push( $el );
  7761. return $el;
  7762. },
  7763. destroy: function( $el ) {
  7764. var indexOf = $.inArray( $el, this.instances ),
  7765. maxZ = 0;
  7766. if ( indexOf !== -1 ) {
  7767. this.oldInstances.push( this.instances.splice( indexOf, 1 )[ 0 ] );
  7768. }
  7769. if ( this.instances.length === 0 ) {
  7770. $( [ document, window ] ).unbind( ".dialog-overlay" );
  7771. }
  7772. $el.height( 0 ).width( 0 ).remove();
  7773. // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
  7774. $.each( this.instances, function() {
  7775. maxZ = Math.max( maxZ, this.css( "z-index" ) );
  7776. });
  7777. this.maxZ = maxZ;
  7778. },
  7779. height: function() {
  7780. var scrollHeight,
  7781. offsetHeight;
  7782. // handle IE
  7783. if ( $.ui.ie ) {
  7784. scrollHeight = Math.max(
  7785. document.documentElement.scrollHeight,
  7786. document.body.scrollHeight
  7787. );
  7788. offsetHeight = Math.max(
  7789. document.documentElement.offsetHeight,
  7790. document.body.offsetHeight
  7791. );
  7792. if ( scrollHeight < offsetHeight ) {
  7793. return $( window ).height() + "px";
  7794. } else {
  7795. return scrollHeight + "px";
  7796. }
  7797. // handle "good" browsers
  7798. } else {
  7799. return $( document ).height() + "px";
  7800. }
  7801. },
  7802. width: function() {
  7803. var scrollWidth,
  7804. offsetWidth;
  7805. // handle IE
  7806. if ( $.ui.ie ) {
  7807. scrollWidth = Math.max(
  7808. document.documentElement.scrollWidth,
  7809. document.body.scrollWidth
  7810. );
  7811. offsetWidth = Math.max(
  7812. document.documentElement.offsetWidth,
  7813. document.body.offsetWidth
  7814. );
  7815. if ( scrollWidth < offsetWidth ) {
  7816. return $( window ).width() + "px";
  7817. } else {
  7818. return scrollWidth + "px";
  7819. }
  7820. // handle "good" browsers
  7821. } else {
  7822. return $( document ).width() + "px";
  7823. }
  7824. },
  7825. resize: function() {
  7826. /* If the dialog is draggable and the user drags it past the
  7827. * right edge of the window, the document becomes wider so we
  7828. * need to stretch the overlay. If the user then drags the
  7829. * dialog back to the left, the document will become narrower,
  7830. * so we need to shrink the overlay to the appropriate size.
  7831. * This is handled by shrinking the overlay before setting it
  7832. * to the full document size.
  7833. */
  7834. var $overlays = $( [] );
  7835. $.each( $.ui.dialog.overlay.instances, function() {
  7836. $overlays = $overlays.add( this );
  7837. });
  7838. $overlays.css({
  7839. width: 0,
  7840. height: 0
  7841. }).css({
  7842. width: $.ui.dialog.overlay.width(),
  7843. height: $.ui.dialog.overlay.height()
  7844. });
  7845. }
  7846. });
  7847. $.extend( $.ui.dialog.overlay.prototype, {
  7848. destroy: function() {
  7849. $.ui.dialog.overlay.destroy( this.$el );
  7850. }
  7851. });
  7852. }( jQuery ) );
  7853. (function( $, undefined ) {
  7854. var mouseHandled = false;
  7855. $.widget( "ui.menu", {
  7856. version: "1.9.2",
  7857. defaultElement: "<ul>",
  7858. delay: 300,
  7859. options: {
  7860. icons: {
  7861. submenu: "ui-icon-carat-1-e"
  7862. },
  7863. menus: "ul",
  7864. position: {
  7865. my: "left top",
  7866. at: "right top"
  7867. },
  7868. role: "menu",
  7869. // callbacks
  7870. blur: null,
  7871. focus: null,
  7872. select: null
  7873. },
  7874. _create: function() {
  7875. this.activeMenu = this.element;
  7876. this.element
  7877. .uniqueId()
  7878. .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
  7879. .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
  7880. .attr({
  7881. role: this.options.role,
  7882. tabIndex: 0
  7883. })
  7884. // need to catch all clicks on disabled menu
  7885. // not possible through _on
  7886. .bind( "click" + this.eventNamespace, $.proxy(function( event ) {
  7887. if ( this.options.disabled ) {
  7888. event.preventDefault();
  7889. }
  7890. }, this ));
  7891. if ( this.options.disabled ) {
  7892. this.element
  7893. .addClass( "ui-state-disabled" )
  7894. .attr( "aria-disabled", "true" );
  7895. }
  7896. this._on({
  7897. // Prevent focus from sticking to links inside menu after clicking
  7898. // them (focus should always stay on UL during navigation).
  7899. "mousedown .ui-menu-item > a": function( event ) {
  7900. event.preventDefault();
  7901. },
  7902. "click .ui-state-disabled > a": function( event ) {
  7903. event.preventDefault();
  7904. },
  7905. "click .ui-menu-item:has(a)": function( event ) {
  7906. var target = $( event.target ).closest( ".ui-menu-item" );
  7907. if ( !mouseHandled && target.not( ".ui-state-disabled" ).length ) {
  7908. mouseHandled = true;
  7909. this.select( event );
  7910. // Open submenu on click
  7911. if ( target.has( ".ui-menu" ).length ) {
  7912. this.expand( event );
  7913. } else if ( !this.element.is( ":focus" ) ) {
  7914. // Redirect focus to the menu
  7915. this.element.trigger( "focus", [ true ] );
  7916. // If the active item is on the top level, let it stay active.
  7917. // Otherwise, blur the active item since it is no longer visible.
  7918. if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
  7919. clearTimeout( this.timer );
  7920. }
  7921. }
  7922. }
  7923. },
  7924. "mouseenter .ui-menu-item": function( event ) {
  7925. var target = $( event.currentTarget );
  7926. // Remove ui-state-active class from siblings of the newly focused menu item
  7927. // to avoid a jump caused by adjacent elements both having a class with a border
  7928. target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" );
  7929. this.focus( event, target );
  7930. },
  7931. mouseleave: "collapseAll",
  7932. "mouseleave .ui-menu": "collapseAll",
  7933. focus: function( event, keepActiveItem ) {
  7934. // If there's already an active item, keep it active
  7935. // If not, activate the first item
  7936. var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 );
  7937. if ( !keepActiveItem ) {
  7938. this.focus( event, item );
  7939. }
  7940. },
  7941. blur: function( event ) {
  7942. this._delay(function() {
  7943. if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
  7944. this.collapseAll( event );
  7945. }
  7946. });
  7947. },
  7948. keydown: "_keydown"
  7949. });
  7950. this.refresh();
  7951. // Clicks outside of a menu collapse any open menus
  7952. this._on( this.document, {
  7953. click: function( event ) {
  7954. if ( !$( event.target ).closest( ".ui-menu" ).length ) {
  7955. this.collapseAll( event );
  7956. }
  7957. // Reset the mouseHandled flag
  7958. mouseHandled = false;
  7959. }
  7960. });
  7961. },
  7962. _destroy: function() {
  7963. // Destroy (sub)menus
  7964. this.element
  7965. .removeAttr( "aria-activedescendant" )
  7966. .find( ".ui-menu" ).andSelf()
  7967. .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" )
  7968. .removeAttr( "role" )
  7969. .removeAttr( "tabIndex" )
  7970. .removeAttr( "aria-labelledby" )
  7971. .removeAttr( "aria-expanded" )
  7972. .removeAttr( "aria-hidden" )
  7973. .removeAttr( "aria-disabled" )
  7974. .removeUniqueId()
  7975. .show();
  7976. // Destroy menu items
  7977. this.element.find( ".ui-menu-item" )
  7978. .removeClass( "ui-menu-item" )
  7979. .removeAttr( "role" )
  7980. .removeAttr( "aria-disabled" )
  7981. .children( "a" )
  7982. .removeUniqueId()
  7983. .removeClass( "ui-corner-all ui-state-hover" )
  7984. .removeAttr( "tabIndex" )
  7985. .removeAttr( "role" )
  7986. .removeAttr( "aria-haspopup" )
  7987. .children().each( function() {
  7988. var elem = $( this );
  7989. if ( elem.data( "ui-menu-submenu-carat" ) ) {
  7990. elem.remove();
  7991. }
  7992. });
  7993. // Destroy menu dividers
  7994. this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
  7995. },
  7996. _keydown: function( event ) {
  7997. var match, prev, character, skip, regex,
  7998. preventDefault = true;
  7999. function escape( value ) {
  8000. return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
  8001. }
  8002. switch ( event.keyCode ) {
  8003. case $.ui.keyCode.PAGE_UP:
  8004. this.previousPage( event );
  8005. break;
  8006. case $.ui.keyCode.PAGE_DOWN:
  8007. this.nextPage( event );
  8008. break;
  8009. case $.ui.keyCode.HOME:
  8010. this._move( "first", "first", event );
  8011. break;
  8012. case $.ui.keyCode.END:
  8013. this._move( "last", "last", event );
  8014. break;
  8015. case $.ui.keyCode.UP:
  8016. this.previous( event );
  8017. break;
  8018. case $.ui.keyCode.DOWN:
  8019. this.next( event );
  8020. break;
  8021. case $.ui.keyCode.LEFT:
  8022. this.collapse( event );
  8023. break;
  8024. case $.ui.keyCode.RIGHT:
  8025. if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
  8026. this.expand( event );
  8027. }
  8028. break;
  8029. case $.ui.keyCode.ENTER:
  8030. case $.ui.keyCode.SPACE:
  8031. this._activate( event );
  8032. break;
  8033. case $.ui.keyCode.ESCAPE:
  8034. this.collapse( event );
  8035. break;
  8036. default:
  8037. preventDefault = false;
  8038. prev = this.previousFilter || "";
  8039. character = String.fromCharCode( event.keyCode );
  8040. skip = false;
  8041. clearTimeout( this.filterTimer );
  8042. if ( character === prev ) {
  8043. skip = true;
  8044. } else {
  8045. character = prev + character;
  8046. }
  8047. regex = new RegExp( "^" + escape( character ), "i" );
  8048. match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
  8049. return regex.test( $( this ).children( "a" ).text() );
  8050. });
  8051. match = skip && match.index( this.active.next() ) !== -1 ?
  8052. this.active.nextAll( ".ui-menu-item" ) :
  8053. match;
  8054. // If no matches on the current filter, reset to the last character pressed
  8055. // to move down the menu to the first item that starts with that character
  8056. if ( !match.length ) {
  8057. character = String.fromCharCode( event.keyCode );
  8058. regex = new RegExp( "^" + escape( character ), "i" );
  8059. match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
  8060. return regex.test( $( this ).children( "a" ).text() );
  8061. });
  8062. }
  8063. if ( match.length ) {
  8064. this.focus( event, match );
  8065. if ( match.length > 1 ) {
  8066. this.previousFilter = character;
  8067. this.filterTimer = this._delay(function() {
  8068. delete this.previousFilter;
  8069. }, 1000 );
  8070. } else {
  8071. delete this.previousFilter;
  8072. }
  8073. } else {
  8074. delete this.previousFilter;
  8075. }
  8076. }
  8077. if ( preventDefault ) {
  8078. event.preventDefault();
  8079. }
  8080. },
  8081. _activate: function( event ) {
  8082. if ( !this.active.is( ".ui-state-disabled" ) ) {
  8083. if ( this.active.children( "a[aria-haspopup='true']" ).length ) {
  8084. this.expand( event );
  8085. } else {
  8086. this.select( event );
  8087. }
  8088. }
  8089. },
  8090. refresh: function() {
  8091. var menus,
  8092. icon = this.options.icons.submenu,
  8093. submenus = this.element.find( this.options.menus );
  8094. // Initialize nested menus
  8095. submenus.filter( ":not(.ui-menu)" )
  8096. .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
  8097. .hide()
  8098. .attr({
  8099. role: this.options.role,
  8100. "aria-hidden": "true",
  8101. "aria-expanded": "false"
  8102. })
  8103. .each(function() {
  8104. var menu = $( this ),
  8105. item = menu.prev( "a" ),
  8106. submenuCarat = $( "<span>" )
  8107. .addClass( "ui-menu-icon ui-icon " + icon )
  8108. .data( "ui-menu-submenu-carat", true );
  8109. item
  8110. .attr( "aria-haspopup", "true" )
  8111. .prepend( submenuCarat );
  8112. menu.attr( "aria-labelledby", item.attr( "id" ) );
  8113. });
  8114. menus = submenus.add( this.element );
  8115. // Don't refresh list items that are already adapted
  8116. menus.children( ":not(.ui-menu-item):has(a)" )
  8117. .addClass( "ui-menu-item" )
  8118. .attr( "role", "presentation" )
  8119. .children( "a" )
  8120. .uniqueId()
  8121. .addClass( "ui-corner-all" )
  8122. .attr({
  8123. tabIndex: -1,
  8124. role: this._itemRole()
  8125. });
  8126. // Initialize unlinked menu-items containing spaces and/or dashes only as dividers
  8127. menus.children( ":not(.ui-menu-item)" ).each(function() {
  8128. var item = $( this );
  8129. // hyphen, em dash, en dash
  8130. if ( !/[^\-—–\s]/.test( item.text() ) ) {
  8131. item.addClass( "ui-widget-content ui-menu-divider" );
  8132. }
  8133. });
  8134. // Add aria-disabled attribute to any disabled menu item
  8135. menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
  8136. // If the active item has been removed, blur the menu
  8137. if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
  8138. this.blur();
  8139. }
  8140. },
  8141. _itemRole: function() {
  8142. return {
  8143. menu: "menuitem",
  8144. listbox: "option"
  8145. }[ this.options.role ];
  8146. },
  8147. focus: function( event, item ) {
  8148. var nested, focused;
  8149. this.blur( event, event && event.type === "focus" );
  8150. this._scrollIntoView( item );
  8151. this.active = item.first();
  8152. focused = this.active.children( "a" ).addClass( "ui-state-focus" );
  8153. // Only update aria-activedescendant if there's a role
  8154. // otherwise we assume focus is managed elsewhere
  8155. if ( this.options.role ) {
  8156. this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
  8157. }
  8158. // Highlight active parent menu item, if any
  8159. this.active
  8160. .parent()
  8161. .closest( ".ui-menu-item" )
  8162. .children( "a:first" )
  8163. .addClass( "ui-state-active" );
  8164. if ( event && event.type === "keydown" ) {
  8165. this._close();
  8166. } else {
  8167. this.timer = this._delay(function() {
  8168. this._close();
  8169. }, this.delay );
  8170. }
  8171. nested = item.children( ".ui-menu" );
  8172. if ( nested.length && ( /^mouse/.test( event.type ) ) ) {
  8173. this._startOpening(nested);
  8174. }
  8175. this.activeMenu = item.parent();
  8176. this._trigger( "focus", event, { item: item } );
  8177. },
  8178. _scrollIntoView: function( item ) {
  8179. var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
  8180. if ( this._hasScroll() ) {
  8181. borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
  8182. paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
  8183. offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
  8184. scroll = this.activeMenu.scrollTop();
  8185. elementHeight = this.activeMenu.height();
  8186. itemHeight = item.height();
  8187. if ( offset < 0 ) {
  8188. this.activeMenu.scrollTop( scroll + offset );
  8189. } else if ( offset + itemHeight > elementHeight ) {
  8190. this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
  8191. }
  8192. }
  8193. },
  8194. blur: function( event, fromFocus ) {
  8195. if ( !fromFocus ) {
  8196. clearTimeout( this.timer );
  8197. }
  8198. if ( !this.active ) {
  8199. return;
  8200. }
  8201. this.active.children( "a" ).removeClass( "ui-state-focus" );
  8202. this.active = null;
  8203. this._trigger( "blur", event, { item: this.active } );
  8204. },
  8205. _startOpening: function( submenu ) {
  8206. clearTimeout( this.timer );
  8207. // Don't open if already open fixes a Firefox bug that caused a .5 pixel
  8208. // shift in the submenu position when mousing over the carat icon
  8209. if ( submenu.attr( "aria-hidden" ) !== "true" ) {
  8210. return;
  8211. }
  8212. this.timer = this._delay(function() {
  8213. this._close();
  8214. this._open( submenu );
  8215. }, this.delay );
  8216. },
  8217. _open: function( submenu ) {
  8218. var position = $.extend({
  8219. of: this.active
  8220. }, this.options.position );
  8221. clearTimeout( this.timer );
  8222. this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
  8223. .hide()
  8224. .attr( "aria-hidden", "true" );
  8225. submenu
  8226. .show()
  8227. .removeAttr( "aria-hidden" )
  8228. .attr( "aria-expanded", "true" )
  8229. .position( position );
  8230. },
  8231. collapseAll: function( event, all ) {
  8232. clearTimeout( this.timer );
  8233. this.timer = this._delay(function() {
  8234. // If we were passed an event, look for the submenu that contains the event
  8235. var currentMenu = all ? this.element :
  8236. $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
  8237. // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
  8238. if ( !currentMenu.length ) {
  8239. currentMenu = this.element;
  8240. }
  8241. this._close( currentMenu );
  8242. this.blur( event );
  8243. this.activeMenu = currentMenu;
  8244. }, this.delay );
  8245. },
  8246. // With no arguments, closes the currently active menu - if nothing is active
  8247. // it closes all menus. If passed an argument, it will search for menus BELOW
  8248. _close: function( startMenu ) {
  8249. if ( !startMenu ) {
  8250. startMenu = this.active ? this.active.parent() : this.element;
  8251. }
  8252. startMenu
  8253. .find( ".ui-menu" )
  8254. .hide()
  8255. .attr( "aria-hidden", "true" )
  8256. .attr( "aria-expanded", "false" )
  8257. .end()
  8258. .find( "a.ui-state-active" )
  8259. .removeClass( "ui-state-active" );
  8260. },
  8261. collapse: function( event ) {
  8262. var newItem = this.active &&
  8263. this.active.parent().closest( ".ui-menu-item", this.element );
  8264. if ( newItem && newItem.length ) {
  8265. this._close();
  8266. this.focus( event, newItem );
  8267. }
  8268. },
  8269. expand: function( event ) {
  8270. var newItem = this.active &&
  8271. this.active
  8272. .children( ".ui-menu " )
  8273. .children( ".ui-menu-item" )
  8274. .first();
  8275. if ( newItem && newItem.length ) {
  8276. this._open( newItem.parent() );
  8277. // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
  8278. this._delay(function() {
  8279. this.focus( event, newItem );
  8280. });
  8281. }
  8282. },
  8283. next: function( event ) {
  8284. this._move( "next", "first", event );
  8285. },
  8286. previous: function( event ) {
  8287. this._move( "prev", "last", event );
  8288. },
  8289. isFirstItem: function() {
  8290. return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
  8291. },
  8292. isLastItem: function() {
  8293. return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
  8294. },
  8295. _move: function( direction, filter, event ) {
  8296. var next;
  8297. if ( this.active ) {
  8298. if ( direction === "first" || direction === "last" ) {
  8299. next = this.active
  8300. [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
  8301. .eq( -1 );
  8302. } else {
  8303. next = this.active
  8304. [ direction + "All" ]( ".ui-menu-item" )
  8305. .eq( 0 );
  8306. }
  8307. }
  8308. if ( !next || !next.length || !this.active ) {
  8309. next = this.activeMenu.children( ".ui-menu-item" )[ filter ]();
  8310. }
  8311. this.focus( event, next );
  8312. },
  8313. nextPage: function( event ) {
  8314. var item, base, height;
  8315. if ( !this.active ) {
  8316. this.next( event );
  8317. return;
  8318. }
  8319. if ( this.isLastItem() ) {
  8320. return;
  8321. }
  8322. if ( this._hasScroll() ) {
  8323. base = this.active.offset().top;
  8324. height = this.element.height();
  8325. this.active.nextAll( ".ui-menu-item" ).each(function() {
  8326. item = $( this );
  8327. return item.offset().top - base - height < 0;
  8328. });
  8329. this.focus( event, item );
  8330. } else {
  8331. this.focus( event, this.activeMenu.children( ".ui-menu-item" )
  8332. [ !this.active ? "first" : "last" ]() );
  8333. }
  8334. },
  8335. previousPage: function( event ) {
  8336. var item, base, height;
  8337. if ( !this.active ) {
  8338. this.next( event );
  8339. return;
  8340. }
  8341. if ( this.isFirstItem() ) {
  8342. return;
  8343. }
  8344. if ( this._hasScroll() ) {
  8345. base = this.active.offset().top;
  8346. height = this.element.height();
  8347. this.active.prevAll( ".ui-menu-item" ).each(function() {
  8348. item = $( this );
  8349. return item.offset().top - base + height > 0;
  8350. });
  8351. this.focus( event, item );
  8352. } else {
  8353. this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
  8354. }
  8355. },
  8356. _hasScroll: function() {
  8357. return this.element.outerHeight() < this.element.prop( "scrollHeight" );
  8358. },
  8359. select: function( event ) {
  8360. // TODO: It should never be possible to not have an active item at this
  8361. // point, but the tests don't trigger mouseenter before click.
  8362. this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
  8363. var ui = { item: this.active };
  8364. if ( !this.active.has( ".ui-menu" ).length ) {
  8365. this.collapseAll( event, true );
  8366. }
  8367. this._trigger( "select", event, ui );
  8368. }
  8369. });
  8370. }( jQuery ));
  8371. (function( $, undefined ) {
  8372. $.widget( "ui.progressbar", {
  8373. version: "1.9.2",
  8374. options: {
  8375. value: 0,
  8376. max: 100
  8377. },
  8378. min: 0,
  8379. _create: function() {
  8380. this.element
  8381. .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
  8382. .attr({
  8383. role: "progressbar",
  8384. "aria-valuemin": this.min,
  8385. "aria-valuemax": this.options.max,
  8386. "aria-valuenow": this._value()
  8387. });
  8388. this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
  8389. .appendTo( this.element );
  8390. this.oldValue = this._value();
  8391. this._refreshValue();
  8392. },
  8393. _destroy: function() {
  8394. this.element
  8395. .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
  8396. .removeAttr( "role" )
  8397. .removeAttr( "aria-valuemin" )
  8398. .removeAttr( "aria-valuemax" )
  8399. .removeAttr( "aria-valuenow" );
  8400. this.valueDiv.remove();
  8401. },
  8402. value: function( newValue ) {
  8403. if ( newValue === undefined ) {
  8404. return this._value();
  8405. }
  8406. this._setOption( "value", newValue );
  8407. return this;
  8408. },
  8409. _setOption: function( key, value ) {
  8410. if ( key === "value" ) {
  8411. this.options.value = value;
  8412. this._refreshValue();
  8413. if ( this._value() === this.options.max ) {
  8414. this._trigger( "complete" );
  8415. }
  8416. }
  8417. this._super( key, value );
  8418. },
  8419. _value: function() {
  8420. var val = this.options.value;
  8421. // normalize invalid value
  8422. if ( typeof val !== "number" ) {
  8423. val = 0;
  8424. }
  8425. return Math.min( this.options.max, Math.max( this.min, val ) );
  8426. },
  8427. _percentage: function() {
  8428. return 100 * this._value() / this.options.max;
  8429. },
  8430. _refreshValue: function() {
  8431. var value = this.value(),
  8432. percentage = this._percentage();
  8433. if ( this.oldValue !== value ) {
  8434. this.oldValue = value;
  8435. this._trigger( "change" );
  8436. }
  8437. this.valueDiv
  8438. .toggle( value > this.min )
  8439. .toggleClass( "ui-corner-right", value === this.options.max )
  8440. .width( percentage.toFixed(0) + "%" );
  8441. this.element.attr( "aria-valuenow", value );
  8442. }
  8443. });
  8444. })( jQuery );
  8445. (function( $, undefined ) {
  8446. // number of pages in a slider
  8447. // (how many times can you page up/down to go through the whole range)
  8448. var numPages = 5;
  8449. $.widget( "ui.slider", $.ui.mouse, {
  8450. version: "1.9.2",
  8451. widgetEventPrefix: "slide",
  8452. options: {
  8453. animate: false,
  8454. distance: 0,
  8455. max: 100,
  8456. min: 0,
  8457. orientation: "horizontal",
  8458. range: false,
  8459. step: 1,
  8460. value: 0,
  8461. values: null
  8462. },
  8463. _create: function() {
  8464. var i, handleCount,
  8465. o = this.options,
  8466. existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
  8467. handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
  8468. handles = [];
  8469. this._keySliding = false;
  8470. this._mouseSliding = false;
  8471. this._animateOff = true;
  8472. this._handleIndex = null;
  8473. this._detectOrientation();
  8474. this._mouseInit();
  8475. this.element
  8476. .addClass( "ui-slider" +
  8477. " ui-slider-" + this.orientation +
  8478. " ui-widget" +
  8479. " ui-widget-content" +
  8480. " ui-corner-all" +
  8481. ( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) );
  8482. this.range = $([]);
  8483. if ( o.range ) {
  8484. if ( o.range === true ) {
  8485. if ( !o.values ) {
  8486. o.values = [ this._valueMin(), this._valueMin() ];
  8487. }
  8488. if ( o.values.length && o.values.length !== 2 ) {
  8489. o.values = [ o.values[0], o.values[0] ];
  8490. }
  8491. }
  8492. this.range = $( "<div></div>" )
  8493. .appendTo( this.element )
  8494. .addClass( "ui-slider-range" +
  8495. // note: this isn't the most fittingly semantic framework class for this element,
  8496. // but worked best visually with a variety of themes
  8497. " ui-widget-header" +
  8498. ( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) );
  8499. }
  8500. handleCount = ( o.values && o.values.length ) || 1;
  8501. for ( i = existingHandles.length; i < handleCount; i++ ) {
  8502. handles.push( handle );
  8503. }
  8504. this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
  8505. this.handle = this.handles.eq( 0 );
  8506. this.handles.add( this.range ).filter( "a" )
  8507. .click(function( event ) {
  8508. event.preventDefault();
  8509. })
  8510. .mouseenter(function() {
  8511. if ( !o.disabled ) {
  8512. $( this ).addClass( "ui-state-hover" );
  8513. }
  8514. })
  8515. .mouseleave(function() {
  8516. $( this ).removeClass( "ui-state-hover" );
  8517. })
  8518. .focus(function() {
  8519. if ( !o.disabled ) {
  8520. $( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" );
  8521. $( this ).addClass( "ui-state-focus" );
  8522. } else {
  8523. $( this ).blur();
  8524. }
  8525. })
  8526. .blur(function() {
  8527. $( this ).removeClass( "ui-state-focus" );
  8528. });
  8529. this.handles.each(function( i ) {
  8530. $( this ).data( "ui-slider-handle-index", i );
  8531. });
  8532. this._on( this.handles, {
  8533. keydown: function( event ) {
  8534. var allowed, curVal, newVal, step,
  8535. index = $( event.target ).data( "ui-slider-handle-index" );
  8536. switch ( event.keyCode ) {
  8537. case $.ui.keyCode.HOME:
  8538. case $.ui.keyCode.END:
  8539. case $.ui.keyCode.PAGE_UP:
  8540. case $.ui.keyCode.PAGE_DOWN:
  8541. case $.ui.keyCode.UP:
  8542. case $.ui.keyCode.RIGHT:
  8543. case $.ui.keyCode.DOWN:
  8544. case $.ui.keyCode.LEFT:
  8545. event.preventDefault();
  8546. if ( !this._keySliding ) {
  8547. this._keySliding = true;
  8548. $( event.target ).addClass( "ui-state-active" );
  8549. allowed = this._start( event, index );
  8550. if ( allowed === false ) {
  8551. return;
  8552. }
  8553. }
  8554. break;
  8555. }
  8556. step = this.options.step;
  8557. if ( this.options.values && this.options.values.length ) {
  8558. curVal = newVal = this.values( index );
  8559. } else {
  8560. curVal = newVal = this.value();
  8561. }
  8562. switch ( event.keyCode ) {
  8563. case $.ui.keyCode.HOME:
  8564. newVal = this._valueMin();
  8565. break;
  8566. case $.ui.keyCode.END:
  8567. newVal = this._valueMax();
  8568. break;
  8569. case $.ui.keyCode.PAGE_UP:
  8570. newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );
  8571. break;
  8572. case $.ui.keyCode.PAGE_DOWN:
  8573. newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );
  8574. break;
  8575. case $.ui.keyCode.UP:
  8576. case $.ui.keyCode.RIGHT:
  8577. if ( curVal === this._valueMax() ) {
  8578. return;
  8579. }
  8580. newVal = this._trimAlignValue( curVal + step );
  8581. break;
  8582. case $.ui.keyCode.DOWN:
  8583. case $.ui.keyCode.LEFT:
  8584. if ( curVal === this._valueMin() ) {
  8585. return;
  8586. }
  8587. newVal = this._trimAlignValue( curVal - step );
  8588. break;
  8589. }
  8590. this._slide( event, index, newVal );
  8591. },
  8592. keyup: function( event ) {
  8593. var index = $( event.target ).data( "ui-slider-handle-index" );
  8594. if ( this._keySliding ) {
  8595. this._keySliding = false;
  8596. this._stop( event, index );
  8597. this._change( event, index );
  8598. $( event.target ).removeClass( "ui-state-active" );
  8599. }
  8600. }
  8601. });
  8602. this._refreshValue();
  8603. this._animateOff = false;
  8604. },
  8605. _destroy: function() {
  8606. this.handles.remove();
  8607. this.range.remove();
  8608. this.element
  8609. .removeClass( "ui-slider" +
  8610. " ui-slider-horizontal" +
  8611. " ui-slider-vertical" +
  8612. " ui-slider-disabled" +
  8613. " ui-widget" +
  8614. " ui-widget-content" +
  8615. " ui-corner-all" );
  8616. this._mouseDestroy();
  8617. },
  8618. _mouseCapture: function( event ) {
  8619. var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
  8620. that = this,
  8621. o = this.options;
  8622. if ( o.disabled ) {
  8623. return false;
  8624. }
  8625. this.elementSize = {
  8626. width: this.element.outerWidth(),
  8627. height: this.element.outerHeight()
  8628. };
  8629. this.elementOffset = this.element.offset();
  8630. position = { x: event.pageX, y: event.pageY };
  8631. normValue = this._normValueFromMouse( position );
  8632. distance = this._valueMax() - this._valueMin() + 1;
  8633. this.handles.each(function( i ) {
  8634. var thisDistance = Math.abs( normValue - that.values(i) );
  8635. if ( distance > thisDistance ) {
  8636. distance = thisDistance;
  8637. closestHandle = $( this );
  8638. index = i;
  8639. }
  8640. });
  8641. // workaround for bug #3736 (if both handles of a range are at 0,
  8642. // the first is always used as the one with least distance,
  8643. // and moving it is obviously prevented by preventing negative ranges)
  8644. if( o.range === true && this.values(1) === o.min ) {
  8645. index += 1;
  8646. closestHandle = $( this.handles[index] );
  8647. }
  8648. allowed = this._start( event, index );
  8649. if ( allowed === false ) {
  8650. return false;
  8651. }
  8652. this._mouseSliding = true;
  8653. this._handleIndex = index;
  8654. closestHandle
  8655. .addClass( "ui-state-active" )
  8656. .focus();
  8657. offset = closestHandle.offset();
  8658. mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" );
  8659. this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
  8660. left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
  8661. top: event.pageY - offset.top -
  8662. ( closestHandle.height() / 2 ) -
  8663. ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
  8664. ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
  8665. ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
  8666. };
  8667. if ( !this.handles.hasClass( "ui-state-hover" ) ) {
  8668. this._slide( event, index, normValue );
  8669. }
  8670. this._animateOff = true;
  8671. return true;
  8672. },
  8673. _mouseStart: function() {
  8674. return true;
  8675. },
  8676. _mouseDrag: function( event ) {
  8677. var position = { x: event.pageX, y: event.pageY },
  8678. normValue = this._normValueFromMouse( position );
  8679. this._slide( event, this._handleIndex, normValue );
  8680. return false;
  8681. },
  8682. _mouseStop: function( event ) {
  8683. this.handles.removeClass( "ui-state-active" );
  8684. this._mouseSliding = false;
  8685. this._stop( event, this._handleIndex );
  8686. this._change( event, this._handleIndex );
  8687. this._handleIndex = null;
  8688. this._clickOffset = null;
  8689. this._animateOff = false;
  8690. return false;
  8691. },
  8692. _detectOrientation: function() {
  8693. this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
  8694. },
  8695. _normValueFromMouse: function( position ) {
  8696. var pixelTotal,
  8697. pixelMouse,
  8698. percentMouse,
  8699. valueTotal,
  8700. valueMouse;
  8701. if ( this.orientation === "horizontal" ) {
  8702. pixelTotal = this.elementSize.width;
  8703. pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
  8704. } else {
  8705. pixelTotal = this.elementSize.height;
  8706. pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
  8707. }
  8708. percentMouse = ( pixelMouse / pixelTotal );
  8709. if ( percentMouse > 1 ) {
  8710. percentMouse = 1;
  8711. }
  8712. if ( percentMouse < 0 ) {
  8713. percentMouse = 0;
  8714. }
  8715. if ( this.orientation === "vertical" ) {
  8716. percentMouse = 1 - percentMouse;
  8717. }
  8718. valueTotal = this._valueMax() - this._valueMin();
  8719. valueMouse = this._valueMin() + percentMouse * valueTotal;
  8720. return this._trimAlignValue( valueMouse );
  8721. },
  8722. _start: function( event, index ) {
  8723. var uiHash = {
  8724. handle: this.handles[ index ],
  8725. value: this.value()
  8726. };
  8727. if ( this.options.values && this.options.values.length ) {
  8728. uiHash.value = this.values( index );
  8729. uiHash.values = this.values();
  8730. }
  8731. return this._trigger( "start", event, uiHash );
  8732. },
  8733. _slide: function( event, index, newVal ) {
  8734. var otherVal,
  8735. newValues,
  8736. allowed;
  8737. if ( this.options.values && this.options.values.length ) {
  8738. otherVal = this.values( index ? 0 : 1 );
  8739. if ( ( this.options.values.length === 2 && this.options.range === true ) &&
  8740. ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
  8741. ) {
  8742. newVal = otherVal;
  8743. }
  8744. if ( newVal !== this.values( index ) ) {
  8745. newValues = this.values();
  8746. newValues[ index ] = newVal;
  8747. // A slide can be canceled by returning false from the slide callback
  8748. allowed = this._trigger( "slide", event, {
  8749. handle: this.handles[ index ],
  8750. value: newVal,
  8751. values: newValues
  8752. } );
  8753. otherVal = this.values( index ? 0 : 1 );
  8754. if ( allowed !== false ) {
  8755. this.values( index, newVal, true );
  8756. }
  8757. }
  8758. } else {
  8759. if ( newVal !== this.value() ) {
  8760. // A slide can be canceled by returning false from the slide callback
  8761. allowed = this._trigger( "slide", event, {
  8762. handle: this.handles[ index ],
  8763. value: newVal
  8764. } );
  8765. if ( allowed !== false ) {
  8766. this.value( newVal );
  8767. }
  8768. }
  8769. }
  8770. },
  8771. _stop: function( event, index ) {
  8772. var uiHash = {
  8773. handle: this.handles[ index ],
  8774. value: this.value()
  8775. };
  8776. if ( this.options.values && this.options.values.length ) {
  8777. uiHash.value = this.values( index );
  8778. uiHash.values = this.values();
  8779. }
  8780. this._trigger( "stop", event, uiHash );
  8781. },
  8782. _change: function( event, index ) {
  8783. if ( !this._keySliding && !this._mouseSliding ) {
  8784. var uiHash = {
  8785. handle: this.handles[ index ],
  8786. value: this.value()
  8787. };
  8788. if ( this.options.values && this.options.values.length ) {
  8789. uiHash.value = this.values( index );
  8790. uiHash.values = this.values();
  8791. }
  8792. this._trigger( "change", event, uiHash );
  8793. }
  8794. },
  8795. value: function( newValue ) {
  8796. if ( arguments.length ) {
  8797. this.options.value = this._trimAlignValue( newValue );
  8798. this._refreshValue();
  8799. this._change( null, 0 );
  8800. return;
  8801. }
  8802. return this._value();
  8803. },
  8804. values: function( index, newValue ) {
  8805. var vals,
  8806. newValues,
  8807. i;
  8808. if ( arguments.length > 1 ) {
  8809. this.options.values[ index ] = this._trimAlignValue( newValue );
  8810. this._refreshValue();
  8811. this._change( null, index );
  8812. return;
  8813. }
  8814. if ( arguments.length ) {
  8815. if ( $.isArray( arguments[ 0 ] ) ) {
  8816. vals = this.options.values;
  8817. newValues = arguments[ 0 ];
  8818. for ( i = 0; i < vals.length; i += 1 ) {
  8819. vals[ i ] = this._trimAlignValue( newValues[ i ] );
  8820. this._change( null, i );
  8821. }
  8822. this._refreshValue();
  8823. } else {
  8824. if ( this.options.values && this.options.values.length ) {
  8825. return this._values( index );
  8826. } else {
  8827. return this.value();
  8828. }
  8829. }
  8830. } else {
  8831. return this._values();
  8832. }
  8833. },
  8834. _setOption: function( key, value ) {
  8835. var i,
  8836. valsLength = 0;
  8837. if ( $.isArray( this.options.values ) ) {
  8838. valsLength = this.options.values.length;
  8839. }
  8840. $.Widget.prototype._setOption.apply( this, arguments );
  8841. switch ( key ) {
  8842. case "disabled":
  8843. if ( value ) {
  8844. this.handles.filter( ".ui-state-focus" ).blur();
  8845. this.handles.removeClass( "ui-state-hover" );
  8846. this.handles.prop( "disabled", true );
  8847. this.element.addClass( "ui-disabled" );
  8848. } else {
  8849. this.handles.prop( "disabled", false );
  8850. this.element.removeClass( "ui-disabled" );
  8851. }
  8852. break;
  8853. case "orientation":
  8854. this._detectOrientation();
  8855. this.element
  8856. .removeClass( "ui-slider-horizontal ui-slider-vertical" )
  8857. .addClass( "ui-slider-" + this.orientation );
  8858. this._refreshValue();
  8859. break;
  8860. case "value":
  8861. this._animateOff = true;
  8862. this._refreshValue();
  8863. this._change( null, 0 );
  8864. this._animateOff = false;
  8865. break;
  8866. case "values":
  8867. this._animateOff = true;
  8868. this._refreshValue();
  8869. for ( i = 0; i < valsLength; i += 1 ) {
  8870. this._change( null, i );
  8871. }
  8872. this._animateOff = false;
  8873. break;
  8874. case "min":
  8875. case "max":
  8876. this._animateOff = true;
  8877. this._refreshValue();
  8878. this._animateOff = false;
  8879. break;
  8880. }
  8881. },
  8882. //internal value getter
  8883. // _value() returns value trimmed by min and max, aligned by step
  8884. _value: function() {
  8885. var val = this.options.value;
  8886. val = this._trimAlignValue( val );
  8887. return val;
  8888. },
  8889. //internal values getter
  8890. // _values() returns array of values trimmed by min and max, aligned by step
  8891. // _values( index ) returns single value trimmed by min and max, aligned by step
  8892. _values: function( index ) {
  8893. var val,
  8894. vals,
  8895. i;
  8896. if ( arguments.length ) {
  8897. val = this.options.values[ index ];
  8898. val = this._trimAlignValue( val );
  8899. return val;
  8900. } else {
  8901. // .slice() creates a copy of the array
  8902. // this copy gets trimmed by min and max and then returned
  8903. vals = this.options.values.slice();
  8904. for ( i = 0; i < vals.length; i+= 1) {
  8905. vals[ i ] = this._trimAlignValue( vals[ i ] );
  8906. }
  8907. return vals;
  8908. }
  8909. },
  8910. // returns the step-aligned value that val is closest to, between (inclusive) min and max
  8911. _trimAlignValue: function( val ) {
  8912. if ( val <= this._valueMin() ) {
  8913. return this._valueMin();
  8914. }
  8915. if ( val >= this._valueMax() ) {
  8916. return this._valueMax();
  8917. }
  8918. var step = ( this.options.step > 0 ) ? this.options.step : 1,
  8919. valModStep = (val - this._valueMin()) % step,
  8920. alignValue = val - valModStep;
  8921. if ( Math.abs(valModStep) * 2 >= step ) {
  8922. alignValue += ( valModStep > 0 ) ? step : ( -step );
  8923. }
  8924. // Since JavaScript has problems with large floats, round
  8925. // the final value to 5 digits after the decimal point (see #4124)
  8926. return parseFloat( alignValue.toFixed(5) );
  8927. },
  8928. _valueMin: function() {
  8929. return this.options.min;
  8930. },
  8931. _valueMax: function() {
  8932. return this.options.max;
  8933. },
  8934. _refreshValue: function() {
  8935. var lastValPercent, valPercent, value, valueMin, valueMax,
  8936. oRange = this.options.range,
  8937. o = this.options,
  8938. that = this,
  8939. animate = ( !this._animateOff ) ? o.animate : false,
  8940. _set = {};
  8941. if ( this.options.values && this.options.values.length ) {
  8942. this.handles.each(function( i ) {
  8943. valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
  8944. _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
  8945. $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
  8946. if ( that.options.range === true ) {
  8947. if ( that.orientation === "horizontal" ) {
  8948. if ( i === 0 ) {
  8949. that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
  8950. }
  8951. if ( i === 1 ) {
  8952. that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
  8953. }
  8954. } else {
  8955. if ( i === 0 ) {
  8956. that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
  8957. }
  8958. if ( i === 1 ) {
  8959. that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
  8960. }
  8961. }
  8962. }
  8963. lastValPercent = valPercent;
  8964. });
  8965. } else {
  8966. value = this.value();
  8967. valueMin = this._valueMin();
  8968. valueMax = this._valueMax();
  8969. valPercent = ( valueMax !== valueMin ) ?
  8970. ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
  8971. 0;
  8972. _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
  8973. this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
  8974. if ( oRange === "min" && this.orientation === "horizontal" ) {
  8975. this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
  8976. }
  8977. if ( oRange === "max" && this.orientation === "horizontal" ) {
  8978. this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
  8979. }
  8980. if ( oRange === "min" && this.orientation === "vertical" ) {
  8981. this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
  8982. }
  8983. if ( oRange === "max" && this.orientation === "vertical" ) {
  8984. this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
  8985. }
  8986. }
  8987. }
  8988. });
  8989. }(jQuery));
  8990. (function( $ ) {
  8991. function modifier( fn ) {
  8992. return function() {
  8993. var previous = this.element.val();
  8994. fn.apply( this, arguments );
  8995. this._refresh();
  8996. if ( previous !== this.element.val() ) {
  8997. this._trigger( "change" );
  8998. }
  8999. };
  9000. }
  9001. $.widget( "ui.spinner", {
  9002. version: "1.9.2",
  9003. defaultElement: "<input>",
  9004. widgetEventPrefix: "spin",
  9005. options: {
  9006. culture: null,
  9007. icons: {
  9008. down: "ui-icon-triangle-1-s",
  9009. up: "ui-icon-triangle-1-n"
  9010. },
  9011. incremental: true,
  9012. max: null,
  9013. min: null,
  9014. numberFormat: null,
  9015. page: 10,
  9016. step: 1,
  9017. change: null,
  9018. spin: null,
  9019. start: null,
  9020. stop: null
  9021. },
  9022. _create: function() {
  9023. // handle string values that need to be parsed
  9024. this._setOption( "max", this.options.max );
  9025. this._setOption( "min", this.options.min );
  9026. this._setOption( "step", this.options.step );
  9027. // format the value, but don't constrain
  9028. this._value( this.element.val(), true );
  9029. this._draw();
  9030. this._on( this._events );
  9031. this._refresh();
  9032. // turning off autocomplete prevents the browser from remembering the
  9033. // value when navigating through history, so we re-enable autocomplete
  9034. // if the page is unloaded before the widget is destroyed. #7790
  9035. this._on( this.window, {
  9036. beforeunload: function() {
  9037. this.element.removeAttr( "autocomplete" );
  9038. }
  9039. });
  9040. },
  9041. _getCreateOptions: function() {
  9042. var options = {},
  9043. element = this.element;
  9044. $.each( [ "min", "max", "step" ], function( i, option ) {
  9045. var value = element.attr( option );
  9046. if ( value !== undefined && value.length ) {
  9047. options[ option ] = value;
  9048. }
  9049. });
  9050. return options;
  9051. },
  9052. _events: {
  9053. keydown: function( event ) {
  9054. if ( this._start( event ) && this._keydown( event ) ) {
  9055. event.preventDefault();
  9056. }
  9057. },
  9058. keyup: "_stop",
  9059. focus: function() {
  9060. this.previous = this.element.val();
  9061. },
  9062. blur: function( event ) {
  9063. if ( this.cancelBlur ) {
  9064. delete this.cancelBlur;
  9065. return;
  9066. }
  9067. this._refresh();
  9068. if ( this.previous !== this.element.val() ) {
  9069. this._trigger( "change", event );
  9070. }
  9071. },
  9072. mousewheel: function( event, delta ) {
  9073. if ( !delta ) {
  9074. return;
  9075. }
  9076. if ( !this.spinning && !this._start( event ) ) {
  9077. return false;
  9078. }
  9079. this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
  9080. clearTimeout( this.mousewheelTimer );
  9081. this.mousewheelTimer = this._delay(function() {
  9082. if ( this.spinning ) {
  9083. this._stop( event );
  9084. }
  9085. }, 100 );
  9086. event.preventDefault();
  9087. },
  9088. "mousedown .ui-spinner-button": function( event ) {
  9089. var previous;
  9090. // We never want the buttons to have focus; whenever the user is
  9091. // interacting with the spinner, the focus should be on the input.
  9092. // If the input is focused then this.previous is properly set from
  9093. // when the input first received focus. If the input is not focused
  9094. // then we need to set this.previous based on the value before spinning.
  9095. previous = this.element[0] === this.document[0].activeElement ?
  9096. this.previous : this.element.val();
  9097. function checkFocus() {
  9098. var isActive = this.element[0] === this.document[0].activeElement;
  9099. if ( !isActive ) {
  9100. this.element.focus();
  9101. this.previous = previous;
  9102. // support: IE
  9103. // IE sets focus asynchronously, so we need to check if focus
  9104. // moved off of the input because the user clicked on the button.
  9105. this._delay(function() {
  9106. this.previous = previous;
  9107. });
  9108. }
  9109. }
  9110. // ensure focus is on (or stays on) the text field
  9111. event.preventDefault();
  9112. checkFocus.call( this );
  9113. // support: IE
  9114. // IE doesn't prevent moving focus even with event.preventDefault()
  9115. // so we set a flag to know when we should ignore the blur event
  9116. // and check (again) if focus moved off of the input.
  9117. this.cancelBlur = true;
  9118. this._delay(function() {
  9119. delete this.cancelBlur;
  9120. checkFocus.call( this );
  9121. });
  9122. if ( this._start( event ) === false ) {
  9123. return;
  9124. }
  9125. this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
  9126. },
  9127. "mouseup .ui-spinner-button": "_stop",
  9128. "mouseenter .ui-spinner-button": function( event ) {
  9129. // button will add ui-state-active if mouse was down while mouseleave and kept down
  9130. if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
  9131. return;
  9132. }
  9133. if ( this._start( event ) === false ) {
  9134. return false;
  9135. }
  9136. this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
  9137. },
  9138. // TODO: do we really want to consider this a stop?
  9139. // shouldn't we just stop the repeater and wait until mouseup before
  9140. // we trigger the stop event?
  9141. "mouseleave .ui-spinner-button": "_stop"
  9142. },
  9143. _draw: function() {
  9144. var uiSpinner = this.uiSpinner = this.element
  9145. .addClass( "ui-spinner-input" )
  9146. .attr( "autocomplete", "off" )
  9147. .wrap( this._uiSpinnerHtml() )
  9148. .parent()
  9149. // add buttons
  9150. .append( this._buttonHtml() );
  9151. this.element.attr( "role", "spinbutton" );
  9152. // button bindings
  9153. this.buttons = uiSpinner.find( ".ui-spinner-button" )
  9154. .attr( "tabIndex", -1 )
  9155. .button()
  9156. .removeClass( "ui-corner-all" );
  9157. // IE 6 doesn't understand height: 50% for the buttons
  9158. // unless the wrapper has an explicit height
  9159. if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
  9160. uiSpinner.height() > 0 ) {
  9161. uiSpinner.height( uiSpinner.height() );
  9162. }
  9163. // disable spinner if element was already disabled
  9164. if ( this.options.disabled ) {
  9165. this.disable();
  9166. }
  9167. },
  9168. _keydown: function( event ) {
  9169. var options = this.options,
  9170. keyCode = $.ui.keyCode;
  9171. switch ( event.keyCode ) {
  9172. case keyCode.UP:
  9173. this._repeat( null, 1, event );
  9174. return true;
  9175. case keyCode.DOWN:
  9176. this._repeat( null, -1, event );
  9177. return true;
  9178. case keyCode.PAGE_UP:
  9179. this._repeat( null, options.page, event );
  9180. return true;
  9181. case keyCode.PAGE_DOWN:
  9182. this._repeat( null, -options.page, event );
  9183. return true;
  9184. }
  9185. return false;
  9186. },
  9187. _uiSpinnerHtml: function() {
  9188. return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
  9189. },
  9190. _buttonHtml: function() {
  9191. return "" +
  9192. "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
  9193. "<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
  9194. "</a>" +
  9195. "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
  9196. "<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
  9197. "</a>";
  9198. },
  9199. _start: function( event ) {
  9200. if ( !this.spinning && this._trigger( "start", event ) === false ) {
  9201. return false;
  9202. }
  9203. if ( !this.counter ) {
  9204. this.counter = 1;
  9205. }
  9206. this.spinning = true;
  9207. return true;
  9208. },
  9209. _repeat: function( i, steps, event ) {
  9210. i = i || 500;
  9211. clearTimeout( this.timer );
  9212. this.timer = this._delay(function() {
  9213. this._repeat( 40, steps, event );
  9214. }, i );
  9215. this._spin( steps * this.options.step, event );
  9216. },
  9217. _spin: function( step, event ) {
  9218. var value = this.value() || 0;
  9219. if ( !this.counter ) {
  9220. this.counter = 1;
  9221. }
  9222. value = this._adjustValue( value + step * this._increment( this.counter ) );
  9223. if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
  9224. this._value( value );
  9225. this.counter++;
  9226. }
  9227. },
  9228. _increment: function( i ) {
  9229. var incremental = this.options.incremental;
  9230. if ( incremental ) {
  9231. return $.isFunction( incremental ) ?
  9232. incremental( i ) :
  9233. Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );
  9234. }
  9235. return 1;
  9236. },
  9237. _precision: function() {
  9238. var precision = this._precisionOf( this.options.step );
  9239. if ( this.options.min !== null ) {
  9240. precision = Math.max( precision, this._precisionOf( this.options.min ) );
  9241. }
  9242. return precision;
  9243. },
  9244. _precisionOf: function( num ) {
  9245. var str = num.toString(),
  9246. decimal = str.indexOf( "." );
  9247. return decimal === -1 ? 0 : str.length - decimal - 1;
  9248. },
  9249. _adjustValue: function( value ) {
  9250. var base, aboveMin,
  9251. options = this.options;
  9252. // make sure we're at a valid step
  9253. // - find out where we are relative to the base (min or 0)
  9254. base = options.min !== null ? options.min : 0;
  9255. aboveMin = value - base;
  9256. // - round to the nearest step
  9257. aboveMin = Math.round(aboveMin / options.step) * options.step;
  9258. // - rounding is based on 0, so adjust back to our base
  9259. value = base + aboveMin;
  9260. // fix precision from bad JS floating point math
  9261. value = parseFloat( value.toFixed( this._precision() ) );
  9262. // clamp the value
  9263. if ( options.max !== null && value > options.max) {
  9264. return options.max;
  9265. }
  9266. if ( options.min !== null && value < options.min ) {
  9267. return options.min;
  9268. }
  9269. return value;
  9270. },
  9271. _stop: function( event ) {
  9272. if ( !this.spinning ) {
  9273. return;
  9274. }
  9275. clearTimeout( this.timer );
  9276. clearTimeout( this.mousewheelTimer );
  9277. this.counter = 0;
  9278. this.spinning = false;
  9279. this._trigger( "stop", event );
  9280. },
  9281. _setOption: function( key, value ) {
  9282. if ( key === "culture" || key === "numberFormat" ) {
  9283. var prevValue = this._parse( this.element.val() );
  9284. this.options[ key ] = value;
  9285. this.element.val( this._format( prevValue ) );
  9286. return;
  9287. }
  9288. if ( key === "max" || key === "min" || key === "step" ) {
  9289. if ( typeof value === "string" ) {
  9290. value = this._parse( value );
  9291. }
  9292. }
  9293. this._super( key, value );
  9294. if ( key === "disabled" ) {
  9295. if ( value ) {
  9296. this.element.prop( "disabled", true );
  9297. this.buttons.button( "disable" );
  9298. } else {
  9299. this.element.prop( "disabled", false );
  9300. this.buttons.button( "enable" );
  9301. }
  9302. }
  9303. },
  9304. _setOptions: modifier(function( options ) {
  9305. this._super( options );
  9306. this._value( this.element.val() );
  9307. }),
  9308. _parse: function( val ) {
  9309. if ( typeof val === "string" && val !== "" ) {
  9310. val = window.Globalize && this.options.numberFormat ?
  9311. Globalize.parseFloat( val, 10, this.options.culture ) : +val;
  9312. }
  9313. return val === "" || isNaN( val ) ? null : val;
  9314. },
  9315. _format: function( value ) {
  9316. if ( value === "" ) {
  9317. return "";
  9318. }
  9319. return window.Globalize && this.options.numberFormat ?
  9320. Globalize.format( value, this.options.numberFormat, this.options.culture ) :
  9321. value;
  9322. },
  9323. _refresh: function() {
  9324. this.element.attr({
  9325. "aria-valuemin": this.options.min,
  9326. "aria-valuemax": this.options.max,
  9327. // TODO: what should we do with values that can't be parsed?
  9328. "aria-valuenow": this._parse( this.element.val() )
  9329. });
  9330. },
  9331. // update the value without triggering change
  9332. _value: function( value, allowAny ) {
  9333. var parsed;
  9334. if ( value !== "" ) {
  9335. parsed = this._parse( value );
  9336. if ( parsed !== null ) {
  9337. if ( !allowAny ) {
  9338. parsed = this._adjustValue( parsed );
  9339. }
  9340. value = this._format( parsed );
  9341. }
  9342. }
  9343. this.element.val( value );
  9344. this._refresh();
  9345. },
  9346. _destroy: function() {
  9347. this.element
  9348. .removeClass( "ui-spinner-input" )
  9349. .prop( "disabled", false )
  9350. .removeAttr( "autocomplete" )
  9351. .removeAttr( "role" )
  9352. .removeAttr( "aria-valuemin" )
  9353. .removeAttr( "aria-valuemax" )
  9354. .removeAttr( "aria-valuenow" );
  9355. this.uiSpinner.replaceWith( this.element );
  9356. },
  9357. stepUp: modifier(function( steps ) {
  9358. this._stepUp( steps );
  9359. }),
  9360. _stepUp: function( steps ) {
  9361. this._spin( (steps || 1) * this.options.step );
  9362. },
  9363. stepDown: modifier(function( steps ) {
  9364. this._stepDown( steps );
  9365. }),
  9366. _stepDown: function( steps ) {
  9367. this._spin( (steps || 1) * -this.options.step );
  9368. },
  9369. pageUp: modifier(function( pages ) {
  9370. this._stepUp( (pages || 1) * this.options.page );
  9371. }),
  9372. pageDown: modifier(function( pages ) {
  9373. this._stepDown( (pages || 1) * this.options.page );
  9374. }),
  9375. value: function( newVal ) {
  9376. if ( !arguments.length ) {
  9377. return this._parse( this.element.val() );
  9378. }
  9379. modifier( this._value ).call( this, newVal );
  9380. },
  9381. widget: function() {
  9382. return this.uiSpinner;
  9383. }
  9384. });
  9385. }( jQuery ) );
  9386. (function( $, undefined ) {
  9387. var tabId = 0,
  9388. rhash = /#.*$/;
  9389. function getNextTabId() {
  9390. return ++tabId;
  9391. }
  9392. function isLocal( anchor ) {
  9393. return anchor.hash.length > 1 &&
  9394. anchor.href.replace( rhash, "" ) ===
  9395. location.href.replace( rhash, "" )
  9396. // support: Safari 5.1
  9397. // Safari 5.1 doesn't encode spaces in window.location
  9398. // but it does encode spaces from anchors (#8777)
  9399. .replace( /\s/g, "%20" );
  9400. }
  9401. $.widget( "ui.tabs", {
  9402. version: "1.9.2",
  9403. delay: 300,
  9404. options: {
  9405. active: null,
  9406. collapsible: false,
  9407. event: "click",
  9408. heightStyle: "content",
  9409. hide: null,
  9410. show: null,
  9411. // callbacks
  9412. activate: null,
  9413. beforeActivate: null,
  9414. beforeLoad: null,
  9415. load: null
  9416. },
  9417. _create: function() {
  9418. var that = this,
  9419. options = this.options,
  9420. active = options.active,
  9421. locationHash = location.hash.substring( 1 );
  9422. this.running = false;
  9423. this.element
  9424. .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
  9425. .toggleClass( "ui-tabs-collapsible", options.collapsible )
  9426. // Prevent users from focusing disabled tabs via click
  9427. .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) {
  9428. if ( $( this ).is( ".ui-state-disabled" ) ) {
  9429. event.preventDefault();
  9430. }
  9431. })
  9432. // support: IE <9
  9433. // Preventing the default action in mousedown doesn't prevent IE
  9434. // from focusing the element, so if the anchor gets focused, blur.
  9435. // We don't have to worry about focusing the previously focused
  9436. // element since clicking on a non-focusable element should focus
  9437. // the body anyway.
  9438. .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
  9439. if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
  9440. this.blur();
  9441. }
  9442. });
  9443. this._processTabs();
  9444. if ( active === null ) {
  9445. // check the fragment identifier in the URL
  9446. if ( locationHash ) {
  9447. this.tabs.each(function( i, tab ) {
  9448. if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
  9449. active = i;
  9450. return false;
  9451. }
  9452. });
  9453. }
  9454. // check for a tab marked active via a class
  9455. if ( active === null ) {
  9456. active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
  9457. }
  9458. // no active tab, set to false
  9459. if ( active === null || active === -1 ) {
  9460. active = this.tabs.length ? 0 : false;
  9461. }
  9462. }
  9463. // handle numbers: negative, out of range
  9464. if ( active !== false ) {
  9465. active = this.tabs.index( this.tabs.eq( active ) );
  9466. if ( active === -1 ) {
  9467. active = options.collapsible ? false : 0;
  9468. }
  9469. }
  9470. options.active = active;
  9471. // don't allow collapsible: false and active: false
  9472. if ( !options.collapsible && options.active === false && this.anchors.length ) {
  9473. options.active = 0;
  9474. }
  9475. // Take disabling tabs via class attribute from HTML
  9476. // into account and update option properly.
  9477. if ( $.isArray( options.disabled ) ) {
  9478. options.disabled = $.unique( options.disabled.concat(
  9479. $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
  9480. return that.tabs.index( li );
  9481. })
  9482. ) ).sort();
  9483. }
  9484. // check for length avoids error when initializing empty list
  9485. if ( this.options.active !== false && this.anchors.length ) {
  9486. this.active = this._findActive( this.options.active );
  9487. } else {
  9488. this.active = $();
  9489. }
  9490. this._refresh();
  9491. if ( this.active.length ) {
  9492. this.load( options.active );
  9493. }
  9494. },
  9495. _getCreateEventData: function() {
  9496. return {
  9497. tab: this.active,
  9498. panel: !this.active.length ? $() : this._getPanelForTab( this.active )
  9499. };
  9500. },
  9501. _tabKeydown: function( event ) {
  9502. var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
  9503. selectedIndex = this.tabs.index( focusedTab ),
  9504. goingForward = true;
  9505. if ( this._handlePageNav( event ) ) {
  9506. return;
  9507. }
  9508. switch ( event.keyCode ) {
  9509. case $.ui.keyCode.RIGHT:
  9510. case $.ui.keyCode.DOWN:
  9511. selectedIndex++;
  9512. break;
  9513. case $.ui.keyCode.UP:
  9514. case $.ui.keyCode.LEFT:
  9515. goingForward = false;
  9516. selectedIndex--;
  9517. break;
  9518. case $.ui.keyCode.END:
  9519. selectedIndex = this.anchors.length - 1;
  9520. break;
  9521. case $.ui.keyCode.HOME:
  9522. selectedIndex = 0;
  9523. break;
  9524. case $.ui.keyCode.SPACE:
  9525. // Activate only, no collapsing
  9526. event.preventDefault();
  9527. clearTimeout( this.activating );
  9528. this._activate( selectedIndex );
  9529. return;
  9530. case $.ui.keyCode.ENTER:
  9531. // Toggle (cancel delayed activation, allow collapsing)
  9532. event.preventDefault();
  9533. clearTimeout( this.activating );
  9534. // Determine if we should collapse or activate
  9535. this._activate( selectedIndex === this.options.active ? false : selectedIndex );
  9536. return;
  9537. default:
  9538. return;
  9539. }
  9540. // Focus the appropriate tab, based on which key was pressed
  9541. event.preventDefault();
  9542. clearTimeout( this.activating );
  9543. selectedIndex = this._focusNextTab( selectedIndex, goingForward );
  9544. // Navigating with control key will prevent automatic activation
  9545. if ( !event.ctrlKey ) {
  9546. // Update aria-selected immediately so that AT think the tab is already selected.
  9547. // Otherwise AT may confuse the user by stating that they need to activate the tab,
  9548. // but the tab will already be activated by the time the announcement finishes.
  9549. focusedTab.attr( "aria-selected", "false" );
  9550. this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
  9551. this.activating = this._delay(function() {
  9552. this.option( "active", selectedIndex );
  9553. }, this.delay );
  9554. }
  9555. },
  9556. _panelKeydown: function( event ) {
  9557. if ( this._handlePageNav( event ) ) {
  9558. return;
  9559. }
  9560. // Ctrl+up moves focus to the current tab
  9561. if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
  9562. event.preventDefault();
  9563. this.active.focus();
  9564. }
  9565. },
  9566. // Alt+page up/down moves focus to the previous/next tab (and activates)
  9567. _handlePageNav: function( event ) {
  9568. if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
  9569. this._activate( this._focusNextTab( this.options.active - 1, false ) );
  9570. return true;
  9571. }
  9572. if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
  9573. this._activate( this._focusNextTab( this.options.active + 1, true ) );
  9574. return true;
  9575. }
  9576. },
  9577. _findNextTab: function( index, goingForward ) {
  9578. var lastTabIndex = this.tabs.length - 1;
  9579. function constrain() {
  9580. if ( index > lastTabIndex ) {
  9581. index = 0;
  9582. }
  9583. if ( index < 0 ) {
  9584. index = lastTabIndex;
  9585. }
  9586. return index;
  9587. }
  9588. while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
  9589. index = goingForward ? index + 1 : index - 1;
  9590. }
  9591. return index;
  9592. },
  9593. _focusNextTab: function( index, goingForward ) {
  9594. index = this._findNextTab( index, goingForward );
  9595. this.tabs.eq( index ).focus();
  9596. return index;
  9597. },
  9598. _setOption: function( key, value ) {
  9599. if ( key === "active" ) {
  9600. // _activate() will handle invalid values and update this.options
  9601. this._activate( value );
  9602. return;
  9603. }
  9604. if ( key === "disabled" ) {
  9605. // don't use the widget factory's disabled handling
  9606. this._setupDisabled( value );
  9607. return;
  9608. }
  9609. this._super( key, value);
  9610. if ( key === "collapsible" ) {
  9611. this.element.toggleClass( "ui-tabs-collapsible", value );
  9612. // Setting collapsible: false while collapsed; open first panel
  9613. if ( !value && this.options.active === false ) {
  9614. this._activate( 0 );
  9615. }
  9616. }
  9617. if ( key === "event" ) {
  9618. this._setupEvents( value );
  9619. }
  9620. if ( key === "heightStyle" ) {
  9621. this._setupHeightStyle( value );
  9622. }
  9623. },
  9624. _tabId: function( tab ) {
  9625. return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId();
  9626. },
  9627. _sanitizeSelector: function( hash ) {
  9628. return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
  9629. },
  9630. refresh: function() {
  9631. var options = this.options,
  9632. lis = this.tablist.children( ":has(a[href])" );
  9633. // get disabled tabs from class attribute from HTML
  9634. // this will get converted to a boolean if needed in _refresh()
  9635. options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
  9636. return lis.index( tab );
  9637. });
  9638. this._processTabs();
  9639. // was collapsed or no tabs
  9640. if ( options.active === false || !this.anchors.length ) {
  9641. options.active = false;
  9642. this.active = $();
  9643. // was active, but active tab is gone
  9644. } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
  9645. // all remaining tabs are disabled
  9646. if ( this.tabs.length === options.disabled.length ) {
  9647. options.active = false;
  9648. this.active = $();
  9649. // activate previous tab
  9650. } else {
  9651. this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
  9652. }
  9653. // was active, active tab still exists
  9654. } else {
  9655. // make sure active index is correct
  9656. options.active = this.tabs.index( this.active );
  9657. }
  9658. this._refresh();
  9659. },
  9660. _refresh: function() {
  9661. this._setupDisabled( this.options.disabled );
  9662. this._setupEvents( this.options.event );
  9663. this._setupHeightStyle( this.options.heightStyle );
  9664. this.tabs.not( this.active ).attr({
  9665. "aria-selected": "false",
  9666. tabIndex: -1
  9667. });
  9668. this.panels.not( this._getPanelForTab( this.active ) )
  9669. .hide()
  9670. .attr({
  9671. "aria-expanded": "false",
  9672. "aria-hidden": "true"
  9673. });
  9674. // Make sure one tab is in the tab order
  9675. if ( !this.active.length ) {
  9676. this.tabs.eq( 0 ).attr( "tabIndex", 0 );
  9677. } else {
  9678. this.active
  9679. .addClass( "ui-tabs-active ui-state-active" )
  9680. .attr({
  9681. "aria-selected": "true",
  9682. tabIndex: 0
  9683. });
  9684. this._getPanelForTab( this.active )
  9685. .show()
  9686. .attr({
  9687. "aria-expanded": "true",
  9688. "aria-hidden": "false"
  9689. });
  9690. }
  9691. },
  9692. _processTabs: function() {
  9693. var that = this;
  9694. this.tablist = this._getList()
  9695. .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
  9696. .attr( "role", "tablist" );
  9697. this.tabs = this.tablist.find( "> li:has(a[href])" )
  9698. .addClass( "ui-state-default ui-corner-top" )
  9699. .attr({
  9700. role: "tab",
  9701. tabIndex: -1
  9702. });
  9703. this.anchors = this.tabs.map(function() {
  9704. return $( "a", this )[ 0 ];
  9705. })
  9706. .addClass( "ui-tabs-anchor" )
  9707. .attr({
  9708. role: "presentation",
  9709. tabIndex: -1
  9710. });
  9711. this.panels = $();
  9712. this.anchors.each(function( i, anchor ) {
  9713. var selector, panel, panelId,
  9714. anchorId = $( anchor ).uniqueId().attr( "id" ),
  9715. tab = $( anchor ).closest( "li" ),
  9716. originalAriaControls = tab.attr( "aria-controls" );
  9717. // inline tab
  9718. if ( isLocal( anchor ) ) {
  9719. selector = anchor.hash;
  9720. panel = that.element.find( that._sanitizeSelector( selector ) );
  9721. // remote tab
  9722. } else {
  9723. panelId = that._tabId( tab );
  9724. selector = "#" + panelId;
  9725. panel = that.element.find( selector );
  9726. if ( !panel.length ) {
  9727. panel = that._createPanel( panelId );
  9728. panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
  9729. }
  9730. panel.attr( "aria-live", "polite" );
  9731. }
  9732. if ( panel.length) {
  9733. that.panels = that.panels.add( panel );
  9734. }
  9735. if ( originalAriaControls ) {
  9736. tab.data( "ui-tabs-aria-controls", originalAriaControls );
  9737. }
  9738. tab.attr({
  9739. "aria-controls": selector.substring( 1 ),
  9740. "aria-labelledby": anchorId
  9741. });
  9742. panel.attr( "aria-labelledby", anchorId );
  9743. });
  9744. this.panels
  9745. .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
  9746. .attr( "role", "tabpanel" );
  9747. },
  9748. // allow overriding how to find the list for rare usage scenarios (#7715)
  9749. _getList: function() {
  9750. return this.element.find( "ol,ul" ).eq( 0 );
  9751. },
  9752. _createPanel: function( id ) {
  9753. return $( "<div>" )
  9754. .attr( "id", id )
  9755. .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
  9756. .data( "ui-tabs-destroy", true );
  9757. },
  9758. _setupDisabled: function( disabled ) {
  9759. if ( $.isArray( disabled ) ) {
  9760. if ( !disabled.length ) {
  9761. disabled = false;
  9762. } else if ( disabled.length === this.anchors.length ) {
  9763. disabled = true;
  9764. }
  9765. }
  9766. // disable tabs
  9767. for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
  9768. if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
  9769. $( li )
  9770. .addClass( "ui-state-disabled" )
  9771. .attr( "aria-disabled", "true" );
  9772. } else {
  9773. $( li )
  9774. .removeClass( "ui-state-disabled" )
  9775. .removeAttr( "aria-disabled" );
  9776. }
  9777. }
  9778. this.options.disabled = disabled;
  9779. },
  9780. _setupEvents: function( event ) {
  9781. var events = {
  9782. click: function( event ) {
  9783. event.preventDefault();
  9784. }
  9785. };
  9786. if ( event ) {
  9787. $.each( event.split(" "), function( index, eventName ) {
  9788. events[ eventName ] = "_eventHandler";
  9789. });
  9790. }
  9791. this._off( this.anchors.add( this.tabs ).add( this.panels ) );
  9792. this._on( this.anchors, events );
  9793. this._on( this.tabs, { keydown: "_tabKeydown" } );
  9794. this._on( this.panels, { keydown: "_panelKeydown" } );
  9795. this._focusable( this.tabs );
  9796. this._hoverable( this.tabs );
  9797. },
  9798. _setupHeightStyle: function( heightStyle ) {
  9799. var maxHeight, overflow,
  9800. parent = this.element.parent();
  9801. if ( heightStyle === "fill" ) {
  9802. // IE 6 treats height like minHeight, so we need to turn off overflow
  9803. // in order to get a reliable height
  9804. // we use the minHeight support test because we assume that only
  9805. // browsers that don't support minHeight will treat height as minHeight
  9806. if ( !$.support.minHeight ) {
  9807. overflow = parent.css( "overflow" );
  9808. parent.css( "overflow", "hidden");
  9809. }
  9810. maxHeight = parent.height();
  9811. this.element.siblings( ":visible" ).each(function() {
  9812. var elem = $( this ),
  9813. position = elem.css( "position" );
  9814. if ( position === "absolute" || position === "fixed" ) {
  9815. return;
  9816. }
  9817. maxHeight -= elem.outerHeight( true );
  9818. });
  9819. if ( overflow ) {
  9820. parent.css( "overflow", overflow );
  9821. }
  9822. this.element.children().not( this.panels ).each(function() {
  9823. maxHeight -= $( this ).outerHeight( true );
  9824. });
  9825. this.panels.each(function() {
  9826. $( this ).height( Math.max( 0, maxHeight -
  9827. $( this ).innerHeight() + $( this ).height() ) );
  9828. })
  9829. .css( "overflow", "auto" );
  9830. } else if ( heightStyle === "auto" ) {
  9831. maxHeight = 0;
  9832. this.panels.each(function() {
  9833. maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
  9834. }).height( maxHeight );
  9835. }
  9836. },
  9837. _eventHandler: function( event ) {
  9838. var options = this.options,
  9839. active = this.active,
  9840. anchor = $( event.currentTarget ),
  9841. tab = anchor.closest( "li" ),
  9842. clickedIsActive = tab[ 0 ] === active[ 0 ],
  9843. collapsing = clickedIsActive && options.collapsible,
  9844. toShow = collapsing ? $() : this._getPanelForTab( tab ),
  9845. toHide = !active.length ? $() : this._getPanelForTab( active ),
  9846. eventData = {
  9847. oldTab: active,
  9848. oldPanel: toHide,
  9849. newTab: collapsing ? $() : tab,
  9850. newPanel: toShow
  9851. };
  9852. event.preventDefault();
  9853. if ( tab.hasClass( "ui-state-disabled" ) ||
  9854. // tab is already loading
  9855. tab.hasClass( "ui-tabs-loading" ) ||
  9856. // can't switch durning an animation
  9857. this.running ||
  9858. // click on active header, but not collapsible
  9859. ( clickedIsActive && !options.collapsible ) ||
  9860. // allow canceling activation
  9861. ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
  9862. return;
  9863. }
  9864. options.active = collapsing ? false : this.tabs.index( tab );
  9865. this.active = clickedIsActive ? $() : tab;
  9866. if ( this.xhr ) {
  9867. this.xhr.abort();
  9868. }
  9869. if ( !toHide.length && !toShow.length ) {
  9870. $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
  9871. }
  9872. if ( toShow.length ) {
  9873. this.load( this.tabs.index( tab ), event );
  9874. }
  9875. this._toggle( event, eventData );
  9876. },
  9877. // handles show/hide for selecting tabs
  9878. _toggle: function( event, eventData ) {
  9879. var that = this,
  9880. toShow = eventData.newPanel,
  9881. toHide = eventData.oldPanel;
  9882. this.running = true;
  9883. function complete() {
  9884. that.running = false;
  9885. that._trigger( "activate", event, eventData );
  9886. }
  9887. function show() {
  9888. eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
  9889. if ( toShow.length && that.options.show ) {
  9890. that._show( toShow, that.options.show, complete );
  9891. } else {
  9892. toShow.show();
  9893. complete();
  9894. }
  9895. }
  9896. // start out by hiding, then showing, then completing
  9897. if ( toHide.length && this.options.hide ) {
  9898. this._hide( toHide, this.options.hide, function() {
  9899. eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
  9900. show();
  9901. });
  9902. } else {
  9903. eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
  9904. toHide.hide();
  9905. show();
  9906. }
  9907. toHide.attr({
  9908. "aria-expanded": "false",
  9909. "aria-hidden": "true"
  9910. });
  9911. eventData.oldTab.attr( "aria-selected", "false" );
  9912. // If we're switching tabs, remove the old tab from the tab order.
  9913. // If we're opening from collapsed state, remove the previous tab from the tab order.
  9914. // If we're collapsing, then keep the collapsing tab in the tab order.
  9915. if ( toShow.length && toHide.length ) {
  9916. eventData.oldTab.attr( "tabIndex", -1 );
  9917. } else if ( toShow.length ) {
  9918. this.tabs.filter(function() {
  9919. return $( this ).attr( "tabIndex" ) === 0;
  9920. })
  9921. .attr( "tabIndex", -1 );
  9922. }
  9923. toShow.attr({
  9924. "aria-expanded": "true",
  9925. "aria-hidden": "false"
  9926. });
  9927. eventData.newTab.attr({
  9928. "aria-selected": "true",
  9929. tabIndex: 0
  9930. });
  9931. },
  9932. _activate: function( index ) {
  9933. var anchor,
  9934. active = this._findActive( index );
  9935. // trying to activate the already active panel
  9936. if ( active[ 0 ] === this.active[ 0 ] ) {
  9937. return;
  9938. }
  9939. // trying to collapse, simulate a click on the current active header
  9940. if ( !active.length ) {
  9941. active = this.active;
  9942. }
  9943. anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
  9944. this._eventHandler({
  9945. target: anchor,
  9946. currentTarget: anchor,
  9947. preventDefault: $.noop
  9948. });
  9949. },
  9950. _findActive: function( index ) {
  9951. return index === false ? $() : this.tabs.eq( index );
  9952. },
  9953. _getIndex: function( index ) {
  9954. // meta-function to give users option to provide a href string instead of a numerical index.
  9955. if ( typeof index === "string" ) {
  9956. index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
  9957. }
  9958. return index;
  9959. },
  9960. _destroy: function() {
  9961. if ( this.xhr ) {
  9962. this.xhr.abort();
  9963. }
  9964. this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
  9965. this.tablist
  9966. .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
  9967. .removeAttr( "role" );
  9968. this.anchors
  9969. .removeClass( "ui-tabs-anchor" )
  9970. .removeAttr( "role" )
  9971. .removeAttr( "tabIndex" )
  9972. .removeData( "href.tabs" )
  9973. .removeData( "load.tabs" )
  9974. .removeUniqueId();
  9975. this.tabs.add( this.panels ).each(function() {
  9976. if ( $.data( this, "ui-tabs-destroy" ) ) {
  9977. $( this ).remove();
  9978. } else {
  9979. $( this )
  9980. .removeClass( "ui-state-default ui-state-active ui-state-disabled " +
  9981. "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
  9982. .removeAttr( "tabIndex" )
  9983. .removeAttr( "aria-live" )
  9984. .removeAttr( "aria-busy" )
  9985. .removeAttr( "aria-selected" )
  9986. .removeAttr( "aria-labelledby" )
  9987. .removeAttr( "aria-hidden" )
  9988. .removeAttr( "aria-expanded" )
  9989. .removeAttr( "role" );
  9990. }
  9991. });
  9992. this.tabs.each(function() {
  9993. var li = $( this ),
  9994. prev = li.data( "ui-tabs-aria-controls" );
  9995. if ( prev ) {
  9996. li.attr( "aria-controls", prev );
  9997. } else {
  9998. li.removeAttr( "aria-controls" );
  9999. }
  10000. });
  10001. this.panels.show();
  10002. if ( this.options.heightStyle !== "content" ) {
  10003. this.panels.css( "height", "" );
  10004. }
  10005. },
  10006. enable: function( index ) {
  10007. var disabled = this.options.disabled;
  10008. if ( disabled === false ) {
  10009. return;
  10010. }
  10011. if ( index === undefined ) {
  10012. disabled = false;
  10013. } else {
  10014. index = this._getIndex( index );
  10015. if ( $.isArray( disabled ) ) {
  10016. disabled = $.map( disabled, function( num ) {
  10017. return num !== index ? num : null;
  10018. });
  10019. } else {
  10020. disabled = $.map( this.tabs, function( li, num ) {
  10021. return num !== index ? num : null;
  10022. });
  10023. }
  10024. }
  10025. this._setupDisabled( disabled );
  10026. },
  10027. disable: function( index ) {
  10028. var disabled = this.options.disabled;
  10029. if ( disabled === true ) {
  10030. return;
  10031. }
  10032. if ( index === undefined ) {
  10033. disabled = true;
  10034. } else {
  10035. index = this._getIndex( index );
  10036. if ( $.inArray( index, disabled ) !== -1 ) {
  10037. return;
  10038. }
  10039. if ( $.isArray( disabled ) ) {
  10040. disabled = $.merge( [ index ], disabled ).sort();
  10041. } else {
  10042. disabled = [ index ];
  10043. }
  10044. }
  10045. this._setupDisabled( disabled );
  10046. },
  10047. load: function( index, event ) {
  10048. index = this._getIndex( index );
  10049. var that = this,
  10050. tab = this.tabs.eq( index ),
  10051. anchor = tab.find( ".ui-tabs-anchor" ),
  10052. panel = this._getPanelForTab( tab ),
  10053. eventData = {
  10054. tab: tab,
  10055. panel: panel
  10056. };
  10057. // not remote
  10058. if ( isLocal( anchor[ 0 ] ) ) {
  10059. return;
  10060. }
  10061. this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
  10062. // support: jQuery <1.8
  10063. // jQuery <1.8 returns false if the request is canceled in beforeSend,
  10064. // but as of 1.8, $.ajax() always returns a jqXHR object.
  10065. if ( this.xhr && this.xhr.statusText !== "canceled" ) {
  10066. tab.addClass( "ui-tabs-loading" );
  10067. panel.attr( "aria-busy", "true" );
  10068. this.xhr
  10069. .success(function( response ) {
  10070. // support: jQuery <1.8
  10071. // http://bugs.jquery.com/ticket/11778
  10072. setTimeout(function() {
  10073. panel.html( response );
  10074. that._trigger( "load", event, eventData );
  10075. }, 1 );
  10076. })
  10077. .complete(function( jqXHR, status ) {
  10078. // support: jQuery <1.8
  10079. // http://bugs.jquery.com/ticket/11778
  10080. setTimeout(function() {
  10081. if ( status === "abort" ) {
  10082. that.panels.stop( false, true );
  10083. }
  10084. tab.removeClass( "ui-tabs-loading" );
  10085. panel.removeAttr( "aria-busy" );
  10086. if ( jqXHR === that.xhr ) {
  10087. delete that.xhr;
  10088. }
  10089. }, 1 );
  10090. });
  10091. }
  10092. },
  10093. // TODO: Remove this function in 1.10 when ajaxOptions is removed
  10094. _ajaxSettings: function( anchor, event, eventData ) {
  10095. var that = this;
  10096. return {
  10097. url: anchor.attr( "href" ),
  10098. beforeSend: function( jqXHR, settings ) {
  10099. return that._trigger( "beforeLoad", event,
  10100. $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) );
  10101. }
  10102. };
  10103. },
  10104. _getPanelForTab: function( tab ) {
  10105. var id = $( tab ).attr( "aria-controls" );
  10106. return this.element.find( this._sanitizeSelector( "#" + id ) );
  10107. }
  10108. });
  10109. // DEPRECATED
  10110. if ( $.uiBackCompat !== false ) {
  10111. // helper method for a lot of the back compat extensions
  10112. $.ui.tabs.prototype._ui = function( tab, panel ) {
  10113. return {
  10114. tab: tab,
  10115. panel: panel,
  10116. index: this.anchors.index( tab )
  10117. };
  10118. };
  10119. // url method
  10120. $.widget( "ui.tabs", $.ui.tabs, {
  10121. url: function( index, url ) {
  10122. this.anchors.eq( index ).attr( "href", url );
  10123. }
  10124. });
  10125. // TODO: Remove _ajaxSettings() method when removing this extension
  10126. // ajaxOptions and cache options
  10127. $.widget( "ui.tabs", $.ui.tabs, {
  10128. options: {
  10129. ajaxOptions: null,
  10130. cache: false
  10131. },
  10132. _create: function() {
  10133. this._super();
  10134. var that = this;
  10135. this._on({ tabsbeforeload: function( event, ui ) {
  10136. // tab is already cached
  10137. if ( $.data( ui.tab[ 0 ], "cache.tabs" ) ) {
  10138. event.preventDefault();
  10139. return;
  10140. }
  10141. ui.jqXHR.success(function() {
  10142. if ( that.options.cache ) {
  10143. $.data( ui.tab[ 0 ], "cache.tabs", true );
  10144. }
  10145. });
  10146. }});
  10147. },
  10148. _ajaxSettings: function( anchor, event, ui ) {
  10149. var ajaxOptions = this.options.ajaxOptions;
  10150. return $.extend( {}, ajaxOptions, {
  10151. error: function( xhr, status ) {
  10152. try {
  10153. // Passing index avoid a race condition when this method is
  10154. // called after the user has selected another tab.
  10155. // Pass the anchor that initiated this request allows
  10156. // loadError to manipulate the tab content panel via $(a.hash)
  10157. ajaxOptions.error(
  10158. xhr, status, ui.tab.closest( "li" ).index(), ui.tab[ 0 ] );
  10159. }
  10160. catch ( error ) {}
  10161. }
  10162. }, this._superApply( arguments ) );
  10163. },
  10164. _setOption: function( key, value ) {
  10165. // reset cache if switching from cached to not cached
  10166. if ( key === "cache" && value === false ) {
  10167. this.anchors.removeData( "cache.tabs" );
  10168. }
  10169. this._super( key, value );
  10170. },
  10171. _destroy: function() {
  10172. this.anchors.removeData( "cache.tabs" );
  10173. this._super();
  10174. },
  10175. url: function( index ){
  10176. this.anchors.eq( index ).removeData( "cache.tabs" );
  10177. this._superApply( arguments );
  10178. }
  10179. });
  10180. // abort method
  10181. $.widget( "ui.tabs", $.ui.tabs, {
  10182. abort: function() {
  10183. if ( this.xhr ) {
  10184. this.xhr.abort();
  10185. }
  10186. }
  10187. });
  10188. // spinner
  10189. $.widget( "ui.tabs", $.ui.tabs, {
  10190. options: {
  10191. spinner: "<em>Loading&#8230;</em>"
  10192. },
  10193. _create: function() {
  10194. this._super();
  10195. this._on({
  10196. tabsbeforeload: function( event, ui ) {
  10197. // Don't react to nested tabs or tabs that don't use a spinner
  10198. if ( event.target !== this.element[ 0 ] ||
  10199. !this.options.spinner ) {
  10200. return;
  10201. }
  10202. var span = ui.tab.find( "span" ),
  10203. html = span.html();
  10204. span.html( this.options.spinner );
  10205. ui.jqXHR.complete(function() {
  10206. span.html( html );
  10207. });
  10208. }
  10209. });
  10210. }
  10211. });
  10212. // enable/disable events
  10213. $.widget( "ui.tabs", $.ui.tabs, {
  10214. options: {
  10215. enable: null,
  10216. disable: null
  10217. },
  10218. enable: function( index ) {
  10219. var options = this.options,
  10220. trigger;
  10221. if ( index && options.disabled === true ||
  10222. ( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) !== -1 ) ) {
  10223. trigger = true;
  10224. }
  10225. this._superApply( arguments );
  10226. if ( trigger ) {
  10227. this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
  10228. }
  10229. },
  10230. disable: function( index ) {
  10231. var options = this.options,
  10232. trigger;
  10233. if ( index && options.disabled === false ||
  10234. ( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) === -1 ) ) {
  10235. trigger = true;
  10236. }
  10237. this._superApply( arguments );
  10238. if ( trigger ) {
  10239. this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
  10240. }
  10241. }
  10242. });
  10243. // add/remove methods and events
  10244. $.widget( "ui.tabs", $.ui.tabs, {
  10245. options: {
  10246. add: null,
  10247. remove: null,
  10248. tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>"
  10249. },
  10250. add: function( url, label, index ) {
  10251. if ( index === undefined ) {
  10252. index = this.anchors.length;
  10253. }
  10254. var doInsertAfter, panel,
  10255. options = this.options,
  10256. li = $( options.tabTemplate
  10257. .replace( /#\{href\}/g, url )
  10258. .replace( /#\{label\}/g, label ) ),
  10259. id = !url.indexOf( "#" ) ?
  10260. url.replace( "#", "" ) :
  10261. this._tabId( li );
  10262. li.addClass( "ui-state-default ui-corner-top" ).data( "ui-tabs-destroy", true );
  10263. li.attr( "aria-controls", id );
  10264. doInsertAfter = index >= this.tabs.length;
  10265. // try to find an existing element before creating a new one
  10266. panel = this.element.find( "#" + id );
  10267. if ( !panel.length ) {
  10268. panel = this._createPanel( id );
  10269. if ( doInsertAfter ) {
  10270. if ( index > 0 ) {
  10271. panel.insertAfter( this.panels.eq( -1 ) );
  10272. } else {
  10273. panel.appendTo( this.element );
  10274. }
  10275. } else {
  10276. panel.insertBefore( this.panels[ index ] );
  10277. }
  10278. }
  10279. panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ).hide();
  10280. if ( doInsertAfter ) {
  10281. li.appendTo( this.tablist );
  10282. } else {
  10283. li.insertBefore( this.tabs[ index ] );
  10284. }
  10285. options.disabled = $.map( options.disabled, function( n ) {
  10286. return n >= index ? ++n : n;
  10287. });
  10288. this.refresh();
  10289. if ( this.tabs.length === 1 && options.active === false ) {
  10290. this.option( "active", 0 );
  10291. }
  10292. this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
  10293. return this;
  10294. },
  10295. remove: function( index ) {
  10296. index = this._getIndex( index );
  10297. var options = this.options,
  10298. tab = this.tabs.eq( index ).remove(),
  10299. panel = this._getPanelForTab( tab ).remove();
  10300. // If selected tab was removed focus tab to the right or
  10301. // in case the last tab was removed the tab to the left.
  10302. // We check for more than 2 tabs, because if there are only 2,
  10303. // then when we remove this tab, there will only be one tab left
  10304. // so we don't need to detect which tab to activate.
  10305. if ( tab.hasClass( "ui-tabs-active" ) && this.anchors.length > 2 ) {
  10306. this._activate( index + ( index + 1 < this.anchors.length ? 1 : -1 ) );
  10307. }
  10308. options.disabled = $.map(
  10309. $.grep( options.disabled, function( n ) {
  10310. return n !== index;
  10311. }),
  10312. function( n ) {
  10313. return n >= index ? --n : n;
  10314. });
  10315. this.refresh();
  10316. this._trigger( "remove", null, this._ui( tab.find( "a" )[ 0 ], panel[ 0 ] ) );
  10317. return this;
  10318. }
  10319. });
  10320. // length method
  10321. $.widget( "ui.tabs", $.ui.tabs, {
  10322. length: function() {
  10323. return this.anchors.length;
  10324. }
  10325. });
  10326. // panel ids (idPrefix option + title attribute)
  10327. $.widget( "ui.tabs", $.ui.tabs, {
  10328. options: {
  10329. idPrefix: "ui-tabs-"
  10330. },
  10331. _tabId: function( tab ) {
  10332. var a = tab.is( "li" ) ? tab.find( "a[href]" ) : tab;
  10333. a = a[0];
  10334. return $( a ).closest( "li" ).attr( "aria-controls" ) ||
  10335. a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF\-]/g, "" ) ||
  10336. this.options.idPrefix + getNextTabId();
  10337. }
  10338. });
  10339. // _createPanel method
  10340. $.widget( "ui.tabs", $.ui.tabs, {
  10341. options: {
  10342. panelTemplate: "<div></div>"
  10343. },
  10344. _createPanel: function( id ) {
  10345. return $( this.options.panelTemplate )
  10346. .attr( "id", id )
  10347. .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
  10348. .data( "ui-tabs-destroy", true );
  10349. }
  10350. });
  10351. // selected option
  10352. $.widget( "ui.tabs", $.ui.tabs, {
  10353. _create: function() {
  10354. var options = this.options;
  10355. if ( options.active === null && options.selected !== undefined ) {
  10356. options.active = options.selected === -1 ? false : options.selected;
  10357. }
  10358. this._super();
  10359. options.selected = options.active;
  10360. if ( options.selected === false ) {
  10361. options.selected = -1;
  10362. }
  10363. },
  10364. _setOption: function( key, value ) {
  10365. if ( key !== "selected" ) {
  10366. return this._super( key, value );
  10367. }
  10368. var options = this.options;
  10369. this._super( "active", value === -1 ? false : value );
  10370. options.selected = options.active;
  10371. if ( options.selected === false ) {
  10372. options.selected = -1;
  10373. }
  10374. },
  10375. _eventHandler: function() {
  10376. this._superApply( arguments );
  10377. this.options.selected = this.options.active;
  10378. if ( this.options.selected === false ) {
  10379. this.options.selected = -1;
  10380. }
  10381. }
  10382. });
  10383. // show and select event
  10384. $.widget( "ui.tabs", $.ui.tabs, {
  10385. options: {
  10386. show: null,
  10387. select: null
  10388. },
  10389. _create: function() {
  10390. this._super();
  10391. if ( this.options.active !== false ) {
  10392. this._trigger( "show", null, this._ui(
  10393. this.active.find( ".ui-tabs-anchor" )[ 0 ],
  10394. this._getPanelForTab( this.active )[ 0 ] ) );
  10395. }
  10396. },
  10397. _trigger: function( type, event, data ) {
  10398. var tab, panel,
  10399. ret = this._superApply( arguments );
  10400. if ( !ret ) {
  10401. return false;
  10402. }
  10403. if ( type === "beforeActivate" ) {
  10404. tab = data.newTab.length ? data.newTab : data.oldTab;
  10405. panel = data.newPanel.length ? data.newPanel : data.oldPanel;
  10406. ret = this._super( "select", event, {
  10407. tab: tab.find( ".ui-tabs-anchor" )[ 0],
  10408. panel: panel[ 0 ],
  10409. index: tab.closest( "li" ).index()
  10410. });
  10411. } else if ( type === "activate" && data.newTab.length ) {
  10412. ret = this._super( "show", event, {
  10413. tab: data.newTab.find( ".ui-tabs-anchor" )[ 0 ],
  10414. panel: data.newPanel[ 0 ],
  10415. index: data.newTab.closest( "li" ).index()
  10416. });
  10417. }
  10418. return ret;
  10419. }
  10420. });
  10421. // select method
  10422. $.widget( "ui.tabs", $.ui.tabs, {
  10423. select: function( index ) {
  10424. index = this._getIndex( index );
  10425. if ( index === -1 ) {
  10426. if ( this.options.collapsible && this.options.selected !== -1 ) {
  10427. index = this.options.selected;
  10428. } else {
  10429. return;
  10430. }
  10431. }
  10432. this.anchors.eq( index ).trigger( this.options.event + this.eventNamespace );
  10433. }
  10434. });
  10435. // cookie option
  10436. (function() {
  10437. var listId = 0;
  10438. $.widget( "ui.tabs", $.ui.tabs, {
  10439. options: {
  10440. cookie: null // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
  10441. },
  10442. _create: function() {
  10443. var options = this.options,
  10444. active;
  10445. if ( options.active == null && options.cookie ) {
  10446. active = parseInt( this._cookie(), 10 );
  10447. if ( active === -1 ) {
  10448. active = false;
  10449. }
  10450. options.active = active;
  10451. }
  10452. this._super();
  10453. },
  10454. _cookie: function( active ) {
  10455. var cookie = [ this.cookie ||
  10456. ( this.cookie = this.options.cookie.name || "ui-tabs-" + (++listId) ) ];
  10457. if ( arguments.length ) {
  10458. cookie.push( active === false ? -1 : active );
  10459. cookie.push( this.options.cookie );
  10460. }
  10461. return $.cookie.apply( null, cookie );
  10462. },
  10463. _refresh: function() {
  10464. this._super();
  10465. if ( this.options.cookie ) {
  10466. this._cookie( this.options.active, this.options.cookie );
  10467. }
  10468. },
  10469. _eventHandler: function() {
  10470. this._superApply( arguments );
  10471. if ( this.options.cookie ) {
  10472. this._cookie( this.options.active, this.options.cookie );
  10473. }
  10474. },
  10475. _destroy: function() {
  10476. this._super();
  10477. if ( this.options.cookie ) {
  10478. this._cookie( null, this.options.cookie );
  10479. }
  10480. }
  10481. });
  10482. })();
  10483. // load event
  10484. $.widget( "ui.tabs", $.ui.tabs, {
  10485. _trigger: function( type, event, data ) {
  10486. var _data = $.extend( {}, data );
  10487. if ( type === "load" ) {
  10488. _data.panel = _data.panel[ 0 ];
  10489. _data.tab = _data.tab.find( ".ui-tabs-anchor" )[ 0 ];
  10490. }
  10491. return this._super( type, event, _data );
  10492. }
  10493. });
  10494. // fx option
  10495. // The new animation options (show, hide) conflict with the old show callback.
  10496. // The old fx option wins over show/hide anyway (always favor back-compat).
  10497. // If a user wants to use the new animation API, they must give up the old API.
  10498. $.widget( "ui.tabs", $.ui.tabs, {
  10499. options: {
  10500. fx: null // e.g. { height: "toggle", opacity: "toggle", duration: 200 }
  10501. },
  10502. _getFx: function() {
  10503. var hide, show,
  10504. fx = this.options.fx;
  10505. if ( fx ) {
  10506. if ( $.isArray( fx ) ) {
  10507. hide = fx[ 0 ];
  10508. show = fx[ 1 ];
  10509. } else {
  10510. hide = show = fx;
  10511. }
  10512. }
  10513. return fx ? { show: show, hide: hide } : null;
  10514. },
  10515. _toggle: function( event, eventData ) {
  10516. var that = this,
  10517. toShow = eventData.newPanel,
  10518. toHide = eventData.oldPanel,
  10519. fx = this._getFx();
  10520. if ( !fx ) {
  10521. return this._super( event, eventData );
  10522. }
  10523. that.running = true;
  10524. function complete() {
  10525. that.running = false;
  10526. that._trigger( "activate", event, eventData );
  10527. }
  10528. function show() {
  10529. eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
  10530. if ( toShow.length && fx.show ) {
  10531. toShow
  10532. .animate( fx.show, fx.show.duration, function() {
  10533. complete();
  10534. });
  10535. } else {
  10536. toShow.show();
  10537. complete();
  10538. }
  10539. }
  10540. // start out by hiding, then showing, then completing
  10541. if ( toHide.length && fx.hide ) {
  10542. toHide.animate( fx.hide, fx.hide.duration, function() {
  10543. eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
  10544. show();
  10545. });
  10546. } else {
  10547. eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
  10548. toHide.hide();
  10549. show();
  10550. }
  10551. }
  10552. });
  10553. }
  10554. })( jQuery );
  10555. (function( $ ) {
  10556. var increments = 0;
  10557. function addDescribedBy( elem, id ) {
  10558. var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
  10559. describedby.push( id );
  10560. elem
  10561. .data( "ui-tooltip-id", id )
  10562. .attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
  10563. }
  10564. function removeDescribedBy( elem ) {
  10565. var id = elem.data( "ui-tooltip-id" ),
  10566. describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
  10567. index = $.inArray( id, describedby );
  10568. if ( index !== -1 ) {
  10569. describedby.splice( index, 1 );
  10570. }
  10571. elem.removeData( "ui-tooltip-id" );
  10572. describedby = $.trim( describedby.join( " " ) );
  10573. if ( describedby ) {
  10574. elem.attr( "aria-describedby", describedby );
  10575. } else {
  10576. elem.removeAttr( "aria-describedby" );
  10577. }
  10578. }
  10579. $.widget( "ui.tooltip", {
  10580. version: "1.9.2",
  10581. options: {
  10582. content: function() {
  10583. return $( this ).attr( "title" );
  10584. },
  10585. hide: true,
  10586. // Disabled elements have inconsistent behavior across browsers (#8661)
  10587. items: "[title]:not([disabled])",
  10588. position: {
  10589. my: "left top+15",
  10590. at: "left bottom",
  10591. collision: "flipfit flip"
  10592. },
  10593. show: true,
  10594. tooltipClass: null,
  10595. track: false,
  10596. // callbacks
  10597. close: null,
  10598. open: null
  10599. },
  10600. _create: function() {
  10601. this._on({
  10602. mouseover: "open",
  10603. focusin: "open"
  10604. });
  10605. // IDs of generated tooltips, needed for destroy
  10606. this.tooltips = {};
  10607. // IDs of parent tooltips where we removed the title attribute
  10608. this.parents = {};
  10609. if ( this.options.disabled ) {
  10610. this._disable();
  10611. }
  10612. },
  10613. _setOption: function( key, value ) {
  10614. var that = this;
  10615. if ( key === "disabled" ) {
  10616. this[ value ? "_disable" : "_enable" ]();
  10617. this.options[ key ] = value;
  10618. // disable element style changes
  10619. return;
  10620. }
  10621. this._super( key, value );
  10622. if ( key === "content" ) {
  10623. $.each( this.tooltips, function( id, element ) {
  10624. that._updateContent( element );
  10625. });
  10626. }
  10627. },
  10628. _disable: function() {
  10629. var that = this;
  10630. // close open tooltips
  10631. $.each( this.tooltips, function( id, element ) {
  10632. var event = $.Event( "blur" );
  10633. event.target = event.currentTarget = element[0];
  10634. that.close( event, true );
  10635. });
  10636. // remove title attributes to prevent native tooltips
  10637. this.element.find( this.options.items ).andSelf().each(function() {
  10638. var element = $( this );
  10639. if ( element.is( "[title]" ) ) {
  10640. element
  10641. .data( "ui-tooltip-title", element.attr( "title" ) )
  10642. .attr( "title", "" );
  10643. }
  10644. });
  10645. },
  10646. _enable: function() {
  10647. // restore title attributes
  10648. this.element.find( this.options.items ).andSelf().each(function() {
  10649. var element = $( this );
  10650. if ( element.data( "ui-tooltip-title" ) ) {
  10651. element.attr( "title", element.data( "ui-tooltip-title" ) );
  10652. }
  10653. });
  10654. },
  10655. open: function( event ) {
  10656. var that = this,
  10657. target = $( event ? event.target : this.element )
  10658. // we need closest here due to mouseover bubbling,
  10659. // but always pointing at the same event target
  10660. .closest( this.options.items );
  10661. // No element to show a tooltip for or the tooltip is already open
  10662. if ( !target.length || target.data( "ui-tooltip-id" ) ) {
  10663. return;
  10664. }
  10665. if ( target.attr( "title" ) ) {
  10666. target.data( "ui-tooltip-title", target.attr( "title" ) );
  10667. }
  10668. target.data( "ui-tooltip-open", true );
  10669. // kill parent tooltips, custom or native, for hover
  10670. if ( event && event.type === "mouseover" ) {
  10671. target.parents().each(function() {
  10672. var parent = $( this ),
  10673. blurEvent;
  10674. if ( parent.data( "ui-tooltip-open" ) ) {
  10675. blurEvent = $.Event( "blur" );
  10676. blurEvent.target = blurEvent.currentTarget = this;
  10677. that.close( blurEvent, true );
  10678. }
  10679. if ( parent.attr( "title" ) ) {
  10680. parent.uniqueId();
  10681. that.parents[ this.id ] = {
  10682. element: this,
  10683. title: parent.attr( "title" )
  10684. };
  10685. parent.attr( "title", "" );
  10686. }
  10687. });
  10688. }
  10689. this._updateContent( target, event );
  10690. },
  10691. _updateContent: function( target, event ) {
  10692. var content,
  10693. contentOption = this.options.content,
  10694. that = this,
  10695. eventType = event ? event.type : null;
  10696. if ( typeof contentOption === "string" ) {
  10697. return this._open( event, target, contentOption );
  10698. }
  10699. content = contentOption.call( target[0], function( response ) {
  10700. // ignore async response if tooltip was closed already
  10701. if ( !target.data( "ui-tooltip-open" ) ) {
  10702. return;
  10703. }
  10704. // IE may instantly serve a cached response for ajax requests
  10705. // delay this call to _open so the other call to _open runs first
  10706. that._delay(function() {
  10707. // jQuery creates a special event for focusin when it doesn't
  10708. // exist natively. To improve performance, the native event
  10709. // object is reused and the type is changed. Therefore, we can't
  10710. // rely on the type being correct after the event finished
  10711. // bubbling, so we set it back to the previous value. (#8740)
  10712. if ( event ) {
  10713. event.type = eventType;
  10714. }
  10715. this._open( event, target, response );
  10716. });
  10717. });
  10718. if ( content ) {
  10719. this._open( event, target, content );
  10720. }
  10721. },
  10722. _open: function( event, target, content ) {
  10723. var tooltip, events, delayedShow,
  10724. positionOption = $.extend( {}, this.options.position );
  10725. if ( !content ) {
  10726. return;
  10727. }
  10728. // Content can be updated multiple times. If the tooltip already
  10729. // exists, then just update the content and bail.
  10730. tooltip = this._find( target );
  10731. if ( tooltip.length ) {
  10732. tooltip.find( ".ui-tooltip-content" ).html( content );
  10733. return;
  10734. }
  10735. // if we have a title, clear it to prevent the native tooltip
  10736. // we have to check first to avoid defining a title if none exists
  10737. // (we don't want to cause an element to start matching [title])
  10738. //
  10739. // We use removeAttr only for key events, to allow IE to export the correct
  10740. // accessible attributes. For mouse events, set to empty string to avoid
  10741. // native tooltip showing up (happens only when removing inside mouseover).
  10742. if ( target.is( "[title]" ) ) {
  10743. if ( event && event.type === "mouseover" ) {
  10744. target.attr( "title", "" );
  10745. } else {
  10746. target.removeAttr( "title" );
  10747. }
  10748. }
  10749. tooltip = this._tooltip( target );
  10750. addDescribedBy( target, tooltip.attr( "id" ) );
  10751. tooltip.find( ".ui-tooltip-content" ).html( content );
  10752. function position( event ) {
  10753. positionOption.of = event;
  10754. if ( tooltip.is( ":hidden" ) ) {
  10755. return;
  10756. }
  10757. tooltip.position( positionOption );
  10758. }
  10759. if ( this.options.track && event && /^mouse/.test( event.type ) ) {
  10760. this._on( this.document, {
  10761. mousemove: position
  10762. });
  10763. // trigger once to override element-relative positioning
  10764. position( event );
  10765. } else {
  10766. tooltip.position( $.extend({
  10767. of: target
  10768. }, this.options.position ) );
  10769. }
  10770. tooltip.hide();
  10771. this._show( tooltip, this.options.show );
  10772. // Handle tracking tooltips that are shown with a delay (#8644). As soon
  10773. // as the tooltip is visible, position the tooltip using the most recent
  10774. // event.
  10775. if ( this.options.show && this.options.show.delay ) {
  10776. delayedShow = setInterval(function() {
  10777. if ( tooltip.is( ":visible" ) ) {
  10778. position( positionOption.of );
  10779. clearInterval( delayedShow );
  10780. }
  10781. }, $.fx.interval );
  10782. }
  10783. this._trigger( "open", event, { tooltip: tooltip } );
  10784. events = {
  10785. keyup: function( event ) {
  10786. if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
  10787. var fakeEvent = $.Event(event);
  10788. fakeEvent.currentTarget = target[0];
  10789. this.close( fakeEvent, true );
  10790. }
  10791. },
  10792. remove: function() {
  10793. this._removeTooltip( tooltip );
  10794. }
  10795. };
  10796. if ( !event || event.type === "mouseover" ) {
  10797. events.mouseleave = "close";
  10798. }
  10799. if ( !event || event.type === "focusin" ) {
  10800. events.focusout = "close";
  10801. }
  10802. this._on( true, target, events );
  10803. },
  10804. close: function( event ) {
  10805. var that = this,
  10806. target = $( event ? event.currentTarget : this.element ),
  10807. tooltip = this._find( target );
  10808. // disabling closes the tooltip, so we need to track when we're closing
  10809. // to avoid an infinite loop in case the tooltip becomes disabled on close
  10810. if ( this.closing ) {
  10811. return;
  10812. }
  10813. // only set title if we had one before (see comment in _open())
  10814. if ( target.data( "ui-tooltip-title" ) ) {
  10815. target.attr( "title", target.data( "ui-tooltip-title" ) );
  10816. }
  10817. removeDescribedBy( target );
  10818. tooltip.stop( true );
  10819. this._hide( tooltip, this.options.hide, function() {
  10820. that._removeTooltip( $( this ) );
  10821. });
  10822. target.removeData( "ui-tooltip-open" );
  10823. this._off( target, "mouseleave focusout keyup" );
  10824. // Remove 'remove' binding only on delegated targets
  10825. if ( target[0] !== this.element[0] ) {
  10826. this._off( target, "remove" );
  10827. }
  10828. this._off( this.document, "mousemove" );
  10829. if ( event && event.type === "mouseleave" ) {
  10830. $.each( this.parents, function( id, parent ) {
  10831. $( parent.element ).attr( "title", parent.title );
  10832. delete that.parents[ id ];
  10833. });
  10834. }
  10835. this.closing = true;
  10836. this._trigger( "close", event, { tooltip: tooltip } );
  10837. this.closing = false;
  10838. },
  10839. _tooltip: function( element ) {
  10840. var id = "ui-tooltip-" + increments++,
  10841. tooltip = $( "<div>" )
  10842. .attr({
  10843. id: id,
  10844. role: "tooltip"
  10845. })
  10846. .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
  10847. ( this.options.tooltipClass || "" ) );
  10848. $( "<div>" )
  10849. .addClass( "ui-tooltip-content" )
  10850. .appendTo( tooltip );
  10851. tooltip.appendTo( this.document[0].body );
  10852. if ( $.fn.bgiframe ) {
  10853. tooltip.bgiframe();
  10854. }
  10855. this.tooltips[ id ] = element;
  10856. return tooltip;
  10857. },
  10858. _find: function( target ) {
  10859. var id = target.data( "ui-tooltip-id" );
  10860. return id ? $( "#" + id ) : $();
  10861. },
  10862. _removeTooltip: function( tooltip ) {
  10863. tooltip.remove();
  10864. delete this.tooltips[ tooltip.attr( "id" ) ];
  10865. },
  10866. _destroy: function() {
  10867. var that = this;
  10868. // close open tooltips
  10869. $.each( this.tooltips, function( id, element ) {
  10870. // Delegate to close method to handle common cleanup
  10871. var event = $.Event( "blur" );
  10872. event.target = event.currentTarget = element[0];
  10873. that.close( event, true );
  10874. // Remove immediately; destroying an open tooltip doesn't use the
  10875. // hide animation
  10876. $( "#" + id ).remove();
  10877. // Restore the title
  10878. if ( element.data( "ui-tooltip-title" ) ) {
  10879. element.attr( "title", element.data( "ui-tooltip-title" ) );
  10880. element.removeData( "ui-tooltip-title" );
  10881. }
  10882. });
  10883. }
  10884. });
  10885. }( jQuery ) );
  10886. ;(jQuery.effects || (function($, undefined) {
  10887. var backCompat = $.uiBackCompat !== false,
  10888. // prefix used for storing data on .data()
  10889. dataSpace = "ui-effects-";
  10890. $.effects = {
  10891. effect: {}
  10892. };
  10893. /*!
  10894. * jQuery Color Animations v2.0.0
  10895. * http://jquery.com/
  10896. *
  10897. * Copyright 2012 jQuery Foundation and other contributors
  10898. * Released under the MIT license.
  10899. * http://jquery.org/license
  10900. *
  10901. * Date: Mon Aug 13 13:41:02 2012 -0500
  10902. */
  10903. (function( jQuery, undefined ) {
  10904. var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor".split(" "),
  10905. // plusequals test for += 100 -= 100
  10906. rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
  10907. // a set of RE's that can match strings and generate color tuples.
  10908. stringParsers = [{
  10909. re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
  10910. parse: function( execResult ) {
  10911. return [
  10912. execResult[ 1 ],
  10913. execResult[ 2 ],
  10914. execResult[ 3 ],
  10915. execResult[ 4 ]
  10916. ];
  10917. }
  10918. }, {
  10919. re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
  10920. parse: function( execResult ) {
  10921. return [
  10922. execResult[ 1 ] * 2.55,
  10923. execResult[ 2 ] * 2.55,
  10924. execResult[ 3 ] * 2.55,
  10925. execResult[ 4 ]
  10926. ];
  10927. }
  10928. }, {
  10929. // this regex ignores A-F because it's compared against an already lowercased string
  10930. re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
  10931. parse: function( execResult ) {
  10932. return [
  10933. parseInt( execResult[ 1 ], 16 ),
  10934. parseInt( execResult[ 2 ], 16 ),
  10935. parseInt( execResult[ 3 ], 16 )
  10936. ];
  10937. }
  10938. }, {
  10939. // this regex ignores A-F because it's compared against an already lowercased string
  10940. re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
  10941. parse: function( execResult ) {
  10942. return [
  10943. parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
  10944. parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
  10945. parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
  10946. ];
  10947. }
  10948. }, {
  10949. re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
  10950. space: "hsla",
  10951. parse: function( execResult ) {
  10952. return [
  10953. execResult[ 1 ],
  10954. execResult[ 2 ] / 100,
  10955. execResult[ 3 ] / 100,
  10956. execResult[ 4 ]
  10957. ];
  10958. }
  10959. }],
  10960. // jQuery.Color( )
  10961. color = jQuery.Color = function( color, green, blue, alpha ) {
  10962. return new jQuery.Color.fn.parse( color, green, blue, alpha );
  10963. },
  10964. spaces = {
  10965. rgba: {
  10966. props: {
  10967. red: {
  10968. idx: 0,
  10969. type: "byte"
  10970. },
  10971. green: {
  10972. idx: 1,
  10973. type: "byte"
  10974. },
  10975. blue: {
  10976. idx: 2,
  10977. type: "byte"
  10978. }
  10979. }
  10980. },
  10981. hsla: {
  10982. props: {
  10983. hue: {
  10984. idx: 0,
  10985. type: "degrees"
  10986. },
  10987. saturation: {
  10988. idx: 1,
  10989. type: "percent"
  10990. },
  10991. lightness: {
  10992. idx: 2,
  10993. type: "percent"
  10994. }
  10995. }
  10996. }
  10997. },
  10998. propTypes = {
  10999. "byte": {
  11000. floor: true,
  11001. max: 255
  11002. },
  11003. "percent": {
  11004. max: 1
  11005. },
  11006. "degrees": {
  11007. mod: 360,
  11008. floor: true
  11009. }
  11010. },
  11011. support = color.support = {},
  11012. // element for support tests
  11013. supportElem = jQuery( "<p>" )[ 0 ],
  11014. // colors = jQuery.Color.names
  11015. colors,
  11016. // local aliases of functions called often
  11017. each = jQuery.each;
  11018. // determine rgba support immediately
  11019. supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
  11020. support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
  11021. // define cache name and alpha properties
  11022. // for rgba and hsla spaces
  11023. each( spaces, function( spaceName, space ) {
  11024. space.cache = "_" + spaceName;
  11025. space.props.alpha = {
  11026. idx: 3,
  11027. type: "percent",
  11028. def: 1
  11029. };
  11030. });
  11031. function clamp( value, prop, allowEmpty ) {
  11032. var type = propTypes[ prop.type ] || {};
  11033. if ( value == null ) {
  11034. return (allowEmpty || !prop.def) ? null : prop.def;
  11035. }
  11036. // ~~ is an short way of doing floor for positive numbers
  11037. value = type.floor ? ~~value : parseFloat( value );
  11038. // IE will pass in empty strings as value for alpha,
  11039. // which will hit this case
  11040. if ( isNaN( value ) ) {
  11041. return prop.def;
  11042. }
  11043. if ( type.mod ) {
  11044. // we add mod before modding to make sure that negatives values
  11045. // get converted properly: -10 -> 350
  11046. return (value + type.mod) % type.mod;
  11047. }
  11048. // for now all property types without mod have min and max
  11049. return 0 > value ? 0 : type.max < value ? type.max : value;
  11050. }
  11051. function stringParse( string ) {
  11052. var inst = color(),
  11053. rgba = inst._rgba = [];
  11054. string = string.toLowerCase();
  11055. each( stringParsers, function( i, parser ) {
  11056. var parsed,
  11057. match = parser.re.exec( string ),
  11058. values = match && parser.parse( match ),
  11059. spaceName = parser.space || "rgba";
  11060. if ( values ) {
  11061. parsed = inst[ spaceName ]( values );
  11062. // if this was an rgba parse the assignment might happen twice
  11063. // oh well....
  11064. inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
  11065. rgba = inst._rgba = parsed._rgba;
  11066. // exit each( stringParsers ) here because we matched
  11067. return false;
  11068. }
  11069. });
  11070. // Found a stringParser that handled it
  11071. if ( rgba.length ) {
  11072. // if this came from a parsed string, force "transparent" when alpha is 0
  11073. // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
  11074. if ( rgba.join() === "0,0,0,0" ) {
  11075. jQuery.extend( rgba, colors.transparent );
  11076. }
  11077. return inst;
  11078. }
  11079. // named colors
  11080. return colors[ string ];
  11081. }
  11082. color.fn = jQuery.extend( color.prototype, {
  11083. parse: function( red, green, blue, alpha ) {
  11084. if ( red === undefined ) {
  11085. this._rgba = [ null, null, null, null ];
  11086. return this;
  11087. }
  11088. if ( red.jquery || red.nodeType ) {
  11089. red = jQuery( red ).css( green );
  11090. green = undefined;
  11091. }
  11092. var inst = this,
  11093. type = jQuery.type( red ),
  11094. rgba = this._rgba = [];
  11095. // more than 1 argument specified - assume ( red, green, blue, alpha )
  11096. if ( green !== undefined ) {
  11097. red = [ red, green, blue, alpha ];
  11098. type = "array";
  11099. }
  11100. if ( type === "string" ) {
  11101. return this.parse( stringParse( red ) || colors._default );
  11102. }
  11103. if ( type === "array" ) {
  11104. each( spaces.rgba.props, function( key, prop ) {
  11105. rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
  11106. });
  11107. return this;
  11108. }
  11109. if ( type === "object" ) {
  11110. if ( red instanceof color ) {
  11111. each( spaces, function( spaceName, space ) {
  11112. if ( red[ space.cache ] ) {
  11113. inst[ space.cache ] = red[ space.cache ].slice();
  11114. }
  11115. });
  11116. } else {
  11117. each( spaces, function( spaceName, space ) {
  11118. var cache = space.cache;
  11119. each( space.props, function( key, prop ) {
  11120. // if the cache doesn't exist, and we know how to convert
  11121. if ( !inst[ cache ] && space.to ) {
  11122. // if the value was null, we don't need to copy it
  11123. // if the key was alpha, we don't need to copy it either
  11124. if ( key === "alpha" || red[ key ] == null ) {
  11125. return;
  11126. }
  11127. inst[ cache ] = space.to( inst._rgba );
  11128. }
  11129. // this is the only case where we allow nulls for ALL properties.
  11130. // call clamp with alwaysAllowEmpty
  11131. inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
  11132. });
  11133. // everything defined but alpha?
  11134. if ( inst[ cache ] && $.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
  11135. // use the default of 1
  11136. inst[ cache ][ 3 ] = 1;
  11137. if ( space.from ) {
  11138. inst._rgba = space.from( inst[ cache ] );
  11139. }
  11140. }
  11141. });
  11142. }
  11143. return this;
  11144. }
  11145. },
  11146. is: function( compare ) {
  11147. var is = color( compare ),
  11148. same = true,
  11149. inst = this;
  11150. each( spaces, function( _, space ) {
  11151. var localCache,
  11152. isCache = is[ space.cache ];
  11153. if (isCache) {
  11154. localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
  11155. each( space.props, function( _, prop ) {
  11156. if ( isCache[ prop.idx ] != null ) {
  11157. same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
  11158. return same;
  11159. }
  11160. });
  11161. }
  11162. return same;
  11163. });
  11164. return same;
  11165. },
  11166. _space: function() {
  11167. var used = [],
  11168. inst = this;
  11169. each( spaces, function( spaceName, space ) {
  11170. if ( inst[ space.cache ] ) {
  11171. used.push( spaceName );
  11172. }
  11173. });
  11174. return used.pop();
  11175. },
  11176. transition: function( other, distance ) {
  11177. var end = color( other ),
  11178. spaceName = end._space(),
  11179. space = spaces[ spaceName ],
  11180. startColor = this.alpha() === 0 ? color( "transparent" ) : this,
  11181. start = startColor[ space.cache ] || space.to( startColor._rgba ),
  11182. result = start.slice();
  11183. end = end[ space.cache ];
  11184. each( space.props, function( key, prop ) {
  11185. var index = prop.idx,
  11186. startValue = start[ index ],
  11187. endValue = end[ index ],
  11188. type = propTypes[ prop.type ] || {};
  11189. // if null, don't override start value
  11190. if ( endValue === null ) {
  11191. return;
  11192. }
  11193. // if null - use end
  11194. if ( startValue === null ) {
  11195. result[ index ] = endValue;
  11196. } else {
  11197. if ( type.mod ) {
  11198. if ( endValue - startValue > type.mod / 2 ) {
  11199. startValue += type.mod;
  11200. } else if ( startValue - endValue > type.mod / 2 ) {
  11201. startValue -= type.mod;
  11202. }
  11203. }
  11204. result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
  11205. }
  11206. });
  11207. return this[ spaceName ]( result );
  11208. },
  11209. blend: function( opaque ) {
  11210. // if we are already opaque - return ourself
  11211. if ( this._rgba[ 3 ] === 1 ) {
  11212. return this;
  11213. }
  11214. var rgb = this._rgba.slice(),
  11215. a = rgb.pop(),
  11216. blend = color( opaque )._rgba;
  11217. return color( jQuery.map( rgb, function( v, i ) {
  11218. return ( 1 - a ) * blend[ i ] + a * v;
  11219. }));
  11220. },
  11221. toRgbaString: function() {
  11222. var prefix = "rgba(",
  11223. rgba = jQuery.map( this._rgba, function( v, i ) {
  11224. return v == null ? ( i > 2 ? 1 : 0 ) : v;
  11225. });
  11226. if ( rgba[ 3 ] === 1 ) {
  11227. rgba.pop();
  11228. prefix = "rgb(";
  11229. }
  11230. return prefix + rgba.join() + ")";
  11231. },
  11232. toHslaString: function() {
  11233. var prefix = "hsla(",
  11234. hsla = jQuery.map( this.hsla(), function( v, i ) {
  11235. if ( v == null ) {
  11236. v = i > 2 ? 1 : 0;
  11237. }
  11238. // catch 1 and 2
  11239. if ( i && i < 3 ) {
  11240. v = Math.round( v * 100 ) + "%";
  11241. }
  11242. return v;
  11243. });
  11244. if ( hsla[ 3 ] === 1 ) {
  11245. hsla.pop();
  11246. prefix = "hsl(";
  11247. }
  11248. return prefix + hsla.join() + ")";
  11249. },
  11250. toHexString: function( includeAlpha ) {
  11251. var rgba = this._rgba.slice(),
  11252. alpha = rgba.pop();
  11253. if ( includeAlpha ) {
  11254. rgba.push( ~~( alpha * 255 ) );
  11255. }
  11256. return "#" + jQuery.map( rgba, function( v ) {
  11257. // default to 0 when nulls exist
  11258. v = ( v || 0 ).toString( 16 );
  11259. return v.length === 1 ? "0" + v : v;
  11260. }).join("");
  11261. },
  11262. toString: function() {
  11263. return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
  11264. }
  11265. });
  11266. color.fn.parse.prototype = color.fn;
  11267. // hsla conversions adapted from:
  11268. // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
  11269. function hue2rgb( p, q, h ) {
  11270. h = ( h + 1 ) % 1;
  11271. if ( h * 6 < 1 ) {
  11272. return p + (q - p) * h * 6;
  11273. }
  11274. if ( h * 2 < 1) {
  11275. return q;
  11276. }
  11277. if ( h * 3 < 2 ) {
  11278. return p + (q - p) * ((2/3) - h) * 6;
  11279. }
  11280. return p;
  11281. }
  11282. spaces.hsla.to = function ( rgba ) {
  11283. if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
  11284. return [ null, null, null, rgba[ 3 ] ];
  11285. }
  11286. var r = rgba[ 0 ] / 255,
  11287. g = rgba[ 1 ] / 255,
  11288. b = rgba[ 2 ] / 255,
  11289. a = rgba[ 3 ],
  11290. max = Math.max( r, g, b ),
  11291. min = Math.min( r, g, b ),
  11292. diff = max - min,
  11293. add = max + min,
  11294. l = add * 0.5,
  11295. h, s;
  11296. if ( min === max ) {
  11297. h = 0;
  11298. } else if ( r === max ) {
  11299. h = ( 60 * ( g - b ) / diff ) + 360;
  11300. } else if ( g === max ) {
  11301. h = ( 60 * ( b - r ) / diff ) + 120;
  11302. } else {
  11303. h = ( 60 * ( r - g ) / diff ) + 240;
  11304. }
  11305. if ( l === 0 || l === 1 ) {
  11306. s = l;
  11307. } else if ( l <= 0.5 ) {
  11308. s = diff / add;
  11309. } else {
  11310. s = diff / ( 2 - add );
  11311. }
  11312. return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
  11313. };
  11314. spaces.hsla.from = function ( hsla ) {
  11315. if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
  11316. return [ null, null, null, hsla[ 3 ] ];
  11317. }
  11318. var h = hsla[ 0 ] / 360,
  11319. s = hsla[ 1 ],
  11320. l = hsla[ 2 ],
  11321. a = hsla[ 3 ],
  11322. q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
  11323. p = 2 * l - q;
  11324. return [
  11325. Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
  11326. Math.round( hue2rgb( p, q, h ) * 255 ),
  11327. Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
  11328. a
  11329. ];
  11330. };
  11331. each( spaces, function( spaceName, space ) {
  11332. var props = space.props,
  11333. cache = space.cache,
  11334. to = space.to,
  11335. from = space.from;
  11336. // makes rgba() and hsla()
  11337. color.fn[ spaceName ] = function( value ) {
  11338. // generate a cache for this space if it doesn't exist
  11339. if ( to && !this[ cache ] ) {
  11340. this[ cache ] = to( this._rgba );
  11341. }
  11342. if ( value === undefined ) {
  11343. return this[ cache ].slice();
  11344. }
  11345. var ret,
  11346. type = jQuery.type( value ),
  11347. arr = ( type === "array" || type === "object" ) ? value : arguments,
  11348. local = this[ cache ].slice();
  11349. each( props, function( key, prop ) {
  11350. var val = arr[ type === "object" ? key : prop.idx ];
  11351. if ( val == null ) {
  11352. val = local[ prop.idx ];
  11353. }
  11354. local[ prop.idx ] = clamp( val, prop );
  11355. });
  11356. if ( from ) {
  11357. ret = color( from( local ) );
  11358. ret[ cache ] = local;
  11359. return ret;
  11360. } else {
  11361. return color( local );
  11362. }
  11363. };
  11364. // makes red() green() blue() alpha() hue() saturation() lightness()
  11365. each( props, function( key, prop ) {
  11366. // alpha is included in more than one space
  11367. if ( color.fn[ key ] ) {
  11368. return;
  11369. }
  11370. color.fn[ key ] = function( value ) {
  11371. var vtype = jQuery.type( value ),
  11372. fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
  11373. local = this[ fn ](),
  11374. cur = local[ prop.idx ],
  11375. match;
  11376. if ( vtype === "undefined" ) {
  11377. return cur;
  11378. }
  11379. if ( vtype === "function" ) {
  11380. value = value.call( this, cur );
  11381. vtype = jQuery.type( value );
  11382. }
  11383. if ( value == null && prop.empty ) {
  11384. return this;
  11385. }
  11386. if ( vtype === "string" ) {
  11387. match = rplusequals.exec( value );
  11388. if ( match ) {
  11389. value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
  11390. }
  11391. }
  11392. local[ prop.idx ] = value;
  11393. return this[ fn ]( local );
  11394. };
  11395. });
  11396. });
  11397. // add .fx.step functions
  11398. each( stepHooks, function( i, hook ) {
  11399. jQuery.cssHooks[ hook ] = {
  11400. set: function( elem, value ) {
  11401. var parsed, curElem,
  11402. backgroundColor = "";
  11403. if ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) {
  11404. value = color( parsed || value );
  11405. if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
  11406. curElem = hook === "backgroundColor" ? elem.parentNode : elem;
  11407. while (
  11408. (backgroundColor === "" || backgroundColor === "transparent") &&
  11409. curElem && curElem.style
  11410. ) {
  11411. try {
  11412. backgroundColor = jQuery.css( curElem, "backgroundColor" );
  11413. curElem = curElem.parentNode;
  11414. } catch ( e ) {
  11415. }
  11416. }
  11417. value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
  11418. backgroundColor :
  11419. "_default" );
  11420. }
  11421. value = value.toRgbaString();
  11422. }
  11423. try {
  11424. elem.style[ hook ] = value;
  11425. } catch( error ) {
  11426. // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
  11427. }
  11428. }
  11429. };
  11430. jQuery.fx.step[ hook ] = function( fx ) {
  11431. if ( !fx.colorInit ) {
  11432. fx.start = color( fx.elem, hook );
  11433. fx.end = color( fx.end );
  11434. fx.colorInit = true;
  11435. }
  11436. jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
  11437. };
  11438. });
  11439. jQuery.cssHooks.borderColor = {
  11440. expand: function( value ) {
  11441. var expanded = {};
  11442. each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
  11443. expanded[ "border" + part + "Color" ] = value;
  11444. });
  11445. return expanded;
  11446. }
  11447. };
  11448. // Basic color names only.
  11449. // Usage of any of the other color names requires adding yourself or including
  11450. // jquery.color.svg-names.js.
  11451. colors = jQuery.Color.names = {
  11452. // 4.1. Basic color keywords
  11453. aqua: "#00ffff",
  11454. black: "#000000",
  11455. blue: "#0000ff",
  11456. fuchsia: "#ff00ff",
  11457. gray: "#808080",
  11458. green: "#008000",
  11459. lime: "#00ff00",
  11460. maroon: "#800000",
  11461. navy: "#000080",
  11462. olive: "#808000",
  11463. purple: "#800080",
  11464. red: "#ff0000",
  11465. silver: "#c0c0c0",
  11466. teal: "#008080",
  11467. white: "#ffffff",
  11468. yellow: "#ffff00",
  11469. // 4.2.3. "transparent" color keyword
  11470. transparent: [ null, null, null, 0 ],
  11471. _default: "#ffffff"
  11472. };
  11473. })( jQuery );
  11474. /******************************************************************************/
  11475. /****************************** CLASS ANIMATIONS ******************************/
  11476. /******************************************************************************/
  11477. (function() {
  11478. var classAnimationActions = [ "add", "remove", "toggle" ],
  11479. shorthandStyles = {
  11480. border: 1,
  11481. borderBottom: 1,
  11482. borderColor: 1,
  11483. borderLeft: 1,
  11484. borderRight: 1,
  11485. borderTop: 1,
  11486. borderWidth: 1,
  11487. margin: 1,
  11488. padding: 1
  11489. };
  11490. $.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
  11491. $.fx.step[ prop ] = function( fx ) {
  11492. if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
  11493. jQuery.style( fx.elem, prop, fx.end );
  11494. fx.setAttr = true;
  11495. }
  11496. };
  11497. });
  11498. function getElementStyles() {
  11499. var style = this.ownerDocument.defaultView ?
  11500. this.ownerDocument.defaultView.getComputedStyle( this, null ) :
  11501. this.currentStyle,
  11502. newStyle = {},
  11503. key,
  11504. len;
  11505. // webkit enumerates style porperties
  11506. if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
  11507. len = style.length;
  11508. while ( len-- ) {
  11509. key = style[ len ];
  11510. if ( typeof style[ key ] === "string" ) {
  11511. newStyle[ $.camelCase( key ) ] = style[ key ];
  11512. }
  11513. }
  11514. } else {
  11515. for ( key in style ) {
  11516. if ( typeof style[ key ] === "string" ) {
  11517. newStyle[ key ] = style[ key ];
  11518. }
  11519. }
  11520. }
  11521. return newStyle;
  11522. }
  11523. function styleDifference( oldStyle, newStyle ) {
  11524. var diff = {},
  11525. name, value;
  11526. for ( name in newStyle ) {
  11527. value = newStyle[ name ];
  11528. if ( oldStyle[ name ] !== value ) {
  11529. if ( !shorthandStyles[ name ] ) {
  11530. if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
  11531. diff[ name ] = value;
  11532. }
  11533. }
  11534. }
  11535. }
  11536. return diff;
  11537. }
  11538. $.effects.animateClass = function( value, duration, easing, callback ) {
  11539. var o = $.speed( duration, easing, callback );
  11540. return this.queue( function() {
  11541. var animated = $( this ),
  11542. baseClass = animated.attr( "class" ) || "",
  11543. applyClassChange,
  11544. allAnimations = o.children ? animated.find( "*" ).andSelf() : animated;
  11545. // map the animated objects to store the original styles.
  11546. allAnimations = allAnimations.map(function() {
  11547. var el = $( this );
  11548. return {
  11549. el: el,
  11550. start: getElementStyles.call( this )
  11551. };
  11552. });
  11553. // apply class change
  11554. applyClassChange = function() {
  11555. $.each( classAnimationActions, function(i, action) {
  11556. if ( value[ action ] ) {
  11557. animated[ action + "Class" ]( value[ action ] );
  11558. }
  11559. });
  11560. };
  11561. applyClassChange();
  11562. // map all animated objects again - calculate new styles and diff
  11563. allAnimations = allAnimations.map(function() {
  11564. this.end = getElementStyles.call( this.el[ 0 ] );
  11565. this.diff = styleDifference( this.start, this.end );
  11566. return this;
  11567. });
  11568. // apply original class
  11569. animated.attr( "class", baseClass );
  11570. // map all animated objects again - this time collecting a promise
  11571. allAnimations = allAnimations.map(function() {
  11572. var styleInfo = this,
  11573. dfd = $.Deferred(),
  11574. opts = jQuery.extend({}, o, {
  11575. queue: false,
  11576. complete: function() {
  11577. dfd.resolve( styleInfo );
  11578. }
  11579. });
  11580. this.el.animate( this.diff, opts );
  11581. return dfd.promise();
  11582. });
  11583. // once all animations have completed:
  11584. $.when.apply( $, allAnimations.get() ).done(function() {
  11585. // set the final class
  11586. applyClassChange();
  11587. // for each animated element,
  11588. // clear all css properties that were animated
  11589. $.each( arguments, function() {
  11590. var el = this.el;
  11591. $.each( this.diff, function(key) {
  11592. el.css( key, '' );
  11593. });
  11594. });
  11595. // this is guarnteed to be there if you use jQuery.speed()
  11596. // it also handles dequeuing the next anim...
  11597. o.complete.call( animated[ 0 ] );
  11598. });
  11599. });
  11600. };
  11601. $.fn.extend({
  11602. _addClass: $.fn.addClass,
  11603. addClass: function( classNames, speed, easing, callback ) {
  11604. return speed ?
  11605. $.effects.animateClass.call( this,
  11606. { add: classNames }, speed, easing, callback ) :
  11607. this._addClass( classNames );
  11608. },
  11609. _removeClass: $.fn.removeClass,
  11610. removeClass: function( classNames, speed, easing, callback ) {
  11611. return speed ?
  11612. $.effects.animateClass.call( this,
  11613. { remove: classNames }, speed, easing, callback ) :
  11614. this._removeClass( classNames );
  11615. },
  11616. _toggleClass: $.fn.toggleClass,
  11617. toggleClass: function( classNames, force, speed, easing, callback ) {
  11618. if ( typeof force === "boolean" || force === undefined ) {
  11619. if ( !speed ) {
  11620. // without speed parameter
  11621. return this._toggleClass( classNames, force );
  11622. } else {
  11623. return $.effects.animateClass.call( this,
  11624. (force ? { add: classNames } : { remove: classNames }),
  11625. speed, easing, callback );
  11626. }
  11627. } else {
  11628. // without force parameter
  11629. return $.effects.animateClass.call( this,
  11630. { toggle: classNames }, force, speed, easing );
  11631. }
  11632. },
  11633. switchClass: function( remove, add, speed, easing, callback) {
  11634. return $.effects.animateClass.call( this, {
  11635. add: add,
  11636. remove: remove
  11637. }, speed, easing, callback );
  11638. }
  11639. });
  11640. })();
  11641. /******************************************************************************/
  11642. /*********************************** EFFECTS **********************************/
  11643. /******************************************************************************/
  11644. (function() {
  11645. $.extend( $.effects, {
  11646. version: "1.9.2",
  11647. // Saves a set of properties in a data storage
  11648. save: function( element, set ) {
  11649. for( var i=0; i < set.length; i++ ) {
  11650. if ( set[ i ] !== null ) {
  11651. element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
  11652. }
  11653. }
  11654. },
  11655. // Restores a set of previously saved properties from a data storage
  11656. restore: function( element, set ) {
  11657. var val, i;
  11658. for( i=0; i < set.length; i++ ) {
  11659. if ( set[ i ] !== null ) {
  11660. val = element.data( dataSpace + set[ i ] );
  11661. // support: jQuery 1.6.2
  11662. // http://bugs.jquery.com/ticket/9917
  11663. // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
  11664. // We can't differentiate between "" and 0 here, so we just assume
  11665. // empty string since it's likely to be a more common value...
  11666. if ( val === undefined ) {
  11667. val = "";
  11668. }
  11669. element.css( set[ i ], val );
  11670. }
  11671. }
  11672. },
  11673. setMode: function( el, mode ) {
  11674. if (mode === "toggle") {
  11675. mode = el.is( ":hidden" ) ? "show" : "hide";
  11676. }
  11677. return mode;
  11678. },
  11679. // Translates a [top,left] array into a baseline value
  11680. // this should be a little more flexible in the future to handle a string & hash
  11681. getBaseline: function( origin, original ) {
  11682. var y, x;
  11683. switch ( origin[ 0 ] ) {
  11684. case "top": y = 0; break;
  11685. case "middle": y = 0.5; break;
  11686. case "bottom": y = 1; break;
  11687. default: y = origin[ 0 ] / original.height;
  11688. }
  11689. switch ( origin[ 1 ] ) {
  11690. case "left": x = 0; break;
  11691. case "center": x = 0.5; break;
  11692. case "right": x = 1; break;
  11693. default: x = origin[ 1 ] / original.width;
  11694. }
  11695. return {
  11696. x: x,
  11697. y: y
  11698. };
  11699. },
  11700. // Wraps the element around a wrapper that copies position properties
  11701. createWrapper: function( element ) {
  11702. // if the element is already wrapped, return it
  11703. if ( element.parent().is( ".ui-effects-wrapper" )) {
  11704. return element.parent();
  11705. }
  11706. // wrap the element
  11707. var props = {
  11708. width: element.outerWidth(true),
  11709. height: element.outerHeight(true),
  11710. "float": element.css( "float" )
  11711. },
  11712. wrapper = $( "<div></div>" )
  11713. .addClass( "ui-effects-wrapper" )
  11714. .css({
  11715. fontSize: "100%",
  11716. background: "transparent",
  11717. border: "none",
  11718. margin: 0,
  11719. padding: 0
  11720. }),
  11721. // Store the size in case width/height are defined in % - Fixes #5245
  11722. size = {
  11723. width: element.width(),
  11724. height: element.height()
  11725. },
  11726. active = document.activeElement;
  11727. // support: Firefox
  11728. // Firefox incorrectly exposes anonymous content
  11729. // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
  11730. try {
  11731. active.id;
  11732. } catch( e ) {
  11733. active = document.body;
  11734. }
  11735. element.wrap( wrapper );
  11736. // Fixes #7595 - Elements lose focus when wrapped.
  11737. if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
  11738. $( active ).focus();
  11739. }
  11740. wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
  11741. // transfer positioning properties to the wrapper
  11742. if ( element.css( "position" ) === "static" ) {
  11743. wrapper.css({ position: "relative" });
  11744. element.css({ position: "relative" });
  11745. } else {
  11746. $.extend( props, {
  11747. position: element.css( "position" ),
  11748. zIndex: element.css( "z-index" )
  11749. });
  11750. $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
  11751. props[ pos ] = element.css( pos );
  11752. if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
  11753. props[ pos ] = "auto";
  11754. }
  11755. });
  11756. element.css({
  11757. position: "relative",
  11758. top: 0,
  11759. left: 0,
  11760. right: "auto",
  11761. bottom: "auto"
  11762. });
  11763. }
  11764. element.css(size);
  11765. return wrapper.css( props ).show();
  11766. },
  11767. removeWrapper: function( element ) {
  11768. var active = document.activeElement;
  11769. if ( element.parent().is( ".ui-effects-wrapper" ) ) {
  11770. element.parent().replaceWith( element );
  11771. // Fixes #7595 - Elements lose focus when wrapped.
  11772. if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
  11773. $( active ).focus();
  11774. }
  11775. }
  11776. return element;
  11777. },
  11778. setTransition: function( element, list, factor, value ) {
  11779. value = value || {};
  11780. $.each( list, function( i, x ) {
  11781. var unit = element.cssUnit( x );
  11782. if ( unit[ 0 ] > 0 ) {
  11783. value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
  11784. }
  11785. });
  11786. return value;
  11787. }
  11788. });
  11789. // return an effect options object for the given parameters:
  11790. function _normalizeArguments( effect, options, speed, callback ) {
  11791. // allow passing all options as the first parameter
  11792. if ( $.isPlainObject( effect ) ) {
  11793. options = effect;
  11794. effect = effect.effect;
  11795. }
  11796. // convert to an object
  11797. effect = { effect: effect };
  11798. // catch (effect, null, ...)
  11799. if ( options == null ) {
  11800. options = {};
  11801. }
  11802. // catch (effect, callback)
  11803. if ( $.isFunction( options ) ) {
  11804. callback = options;
  11805. speed = null;
  11806. options = {};
  11807. }
  11808. // catch (effect, speed, ?)
  11809. if ( typeof options === "number" || $.fx.speeds[ options ] ) {
  11810. callback = speed;
  11811. speed = options;
  11812. options = {};
  11813. }
  11814. // catch (effect, options, callback)
  11815. if ( $.isFunction( speed ) ) {
  11816. callback = speed;
  11817. speed = null;
  11818. }
  11819. // add options to effect
  11820. if ( options ) {
  11821. $.extend( effect, options );
  11822. }
  11823. speed = speed || options.duration;
  11824. effect.duration = $.fx.off ? 0 :
  11825. typeof speed === "number" ? speed :
  11826. speed in $.fx.speeds ? $.fx.speeds[ speed ] :
  11827. $.fx.speeds._default;
  11828. effect.complete = callback || options.complete;
  11829. return effect;
  11830. }
  11831. function standardSpeed( speed ) {
  11832. // valid standard speeds
  11833. if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
  11834. return true;
  11835. }
  11836. // invalid strings - treat as "normal" speed
  11837. if ( typeof speed === "string" && !$.effects.effect[ speed ] ) {
  11838. // TODO: remove in 2.0 (#7115)
  11839. if ( backCompat && $.effects[ speed ] ) {
  11840. return false;
  11841. }
  11842. return true;
  11843. }
  11844. return false;
  11845. }
  11846. $.fn.extend({
  11847. effect: function( /* effect, options, speed, callback */ ) {
  11848. var args = _normalizeArguments.apply( this, arguments ),
  11849. mode = args.mode,
  11850. queue = args.queue,
  11851. effectMethod = $.effects.effect[ args.effect ],
  11852. // DEPRECATED: remove in 2.0 (#7115)
  11853. oldEffectMethod = !effectMethod && backCompat && $.effects[ args.effect ];
  11854. if ( $.fx.off || !( effectMethod || oldEffectMethod ) ) {
  11855. // delegate to the original method (e.g., .show()) if possible
  11856. if ( mode ) {
  11857. return this[ mode ]( args.duration, args.complete );
  11858. } else {
  11859. return this.each( function() {
  11860. if ( args.complete ) {
  11861. args.complete.call( this );
  11862. }
  11863. });
  11864. }
  11865. }
  11866. function run( next ) {
  11867. var elem = $( this ),
  11868. complete = args.complete,
  11869. mode = args.mode;
  11870. function done() {
  11871. if ( $.isFunction( complete ) ) {
  11872. complete.call( elem[0] );
  11873. }
  11874. if ( $.isFunction( next ) ) {
  11875. next();
  11876. }
  11877. }
  11878. // if the element is hiddden and mode is hide,
  11879. // or element is visible and mode is show
  11880. if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
  11881. done();
  11882. } else {
  11883. effectMethod.call( elem[0], args, done );
  11884. }
  11885. }
  11886. // TODO: remove this check in 2.0, effectMethod will always be true
  11887. if ( effectMethod ) {
  11888. return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
  11889. } else {
  11890. // DEPRECATED: remove in 2.0 (#7115)
  11891. return oldEffectMethod.call(this, {
  11892. options: args,
  11893. duration: args.duration,
  11894. callback: args.complete,
  11895. mode: args.mode
  11896. });
  11897. }
  11898. },
  11899. _show: $.fn.show,
  11900. show: function( speed ) {
  11901. if ( standardSpeed( speed ) ) {
  11902. return this._show.apply( this, arguments );
  11903. } else {
  11904. var args = _normalizeArguments.apply( this, arguments );
  11905. args.mode = "show";
  11906. return this.effect.call( this, args );
  11907. }
  11908. },
  11909. _hide: $.fn.hide,
  11910. hide: function( speed ) {
  11911. if ( standardSpeed( speed ) ) {
  11912. return this._hide.apply( this, arguments );
  11913. } else {
  11914. var args = _normalizeArguments.apply( this, arguments );
  11915. args.mode = "hide";
  11916. return this.effect.call( this, args );
  11917. }
  11918. },
  11919. // jQuery core overloads toggle and creates _toggle
  11920. __toggle: $.fn.toggle,
  11921. toggle: function( speed ) {
  11922. if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) {
  11923. return this.__toggle.apply( this, arguments );
  11924. } else {
  11925. var args = _normalizeArguments.apply( this, arguments );
  11926. args.mode = "toggle";
  11927. return this.effect.call( this, args );
  11928. }
  11929. },
  11930. // helper functions
  11931. cssUnit: function(key) {
  11932. var style = this.css( key ),
  11933. val = [];
  11934. $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
  11935. if ( style.indexOf( unit ) > 0 ) {
  11936. val = [ parseFloat( style ), unit ];
  11937. }
  11938. });
  11939. return val;
  11940. }
  11941. });
  11942. })();
  11943. /******************************************************************************/
  11944. /*********************************** EASING ***********************************/
  11945. /******************************************************************************/
  11946. (function() {
  11947. // based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
  11948. var baseEasings = {};
  11949. $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
  11950. baseEasings[ name ] = function( p ) {
  11951. return Math.pow( p, i + 2 );
  11952. };
  11953. });
  11954. $.extend( baseEasings, {
  11955. Sine: function ( p ) {
  11956. return 1 - Math.cos( p * Math.PI / 2 );
  11957. },
  11958. Circ: function ( p ) {
  11959. return 1 - Math.sqrt( 1 - p * p );
  11960. },
  11961. Elastic: function( p ) {
  11962. return p === 0 || p === 1 ? p :
  11963. -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
  11964. },
  11965. Back: function( p ) {
  11966. return p * p * ( 3 * p - 2 );
  11967. },
  11968. Bounce: function ( p ) {
  11969. var pow2,
  11970. bounce = 4;
  11971. while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
  11972. return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
  11973. }
  11974. });
  11975. $.each( baseEasings, function( name, easeIn ) {
  11976. $.easing[ "easeIn" + name ] = easeIn;
  11977. $.easing[ "easeOut" + name ] = function( p ) {
  11978. return 1 - easeIn( 1 - p );
  11979. };
  11980. $.easing[ "easeInOut" + name ] = function( p ) {
  11981. return p < 0.5 ?
  11982. easeIn( p * 2 ) / 2 :
  11983. 1 - easeIn( p * -2 + 2 ) / 2;
  11984. };
  11985. });
  11986. })();
  11987. })(jQuery));
  11988. (function( $, undefined ) {
  11989. var rvertical = /up|down|vertical/,
  11990. rpositivemotion = /up|left|vertical|horizontal/;
  11991. $.effects.effect.blind = function( o, done ) {
  11992. // Create element
  11993. var el = $( this ),
  11994. props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
  11995. mode = $.effects.setMode( el, o.mode || "hide" ),
  11996. direction = o.direction || "up",
  11997. vertical = rvertical.test( direction ),
  11998. ref = vertical ? "height" : "width",
  11999. ref2 = vertical ? "top" : "left",
  12000. motion = rpositivemotion.test( direction ),
  12001. animation = {},
  12002. show = mode === "show",
  12003. wrapper, distance, margin;
  12004. // if already wrapped, the wrapper's properties are my property. #6245
  12005. if ( el.parent().is( ".ui-effects-wrapper" ) ) {
  12006. $.effects.save( el.parent(), props );
  12007. } else {
  12008. $.effects.save( el, props );
  12009. }
  12010. el.show();
  12011. wrapper = $.effects.createWrapper( el ).css({
  12012. overflow: "hidden"
  12013. });
  12014. distance = wrapper[ ref ]();
  12015. margin = parseFloat( wrapper.css( ref2 ) ) || 0;
  12016. animation[ ref ] = show ? distance : 0;
  12017. if ( !motion ) {
  12018. el
  12019. .css( vertical ? "bottom" : "right", 0 )
  12020. .css( vertical ? "top" : "left", "auto" )
  12021. .css({ position: "absolute" });
  12022. animation[ ref2 ] = show ? margin : distance + margin;
  12023. }
  12024. // start at 0 if we are showing
  12025. if ( show ) {
  12026. wrapper.css( ref, 0 );
  12027. if ( ! motion ) {
  12028. wrapper.css( ref2, margin + distance );
  12029. }
  12030. }
  12031. // Animate
  12032. wrapper.animate( animation, {
  12033. duration: o.duration,
  12034. easing: o.easing,
  12035. queue: false,
  12036. complete: function() {
  12037. if ( mode === "hide" ) {
  12038. el.hide();
  12039. }
  12040. $.effects.restore( el, props );
  12041. $.effects.removeWrapper( el );
  12042. done();
  12043. }
  12044. });
  12045. };
  12046. })(jQuery);
  12047. (function( $, undefined ) {
  12048. $.effects.effect.bounce = function( o, done ) {
  12049. var el = $( this ),
  12050. props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
  12051. // defaults:
  12052. mode = $.effects.setMode( el, o.mode || "effect" ),
  12053. hide = mode === "hide",
  12054. show = mode === "show",
  12055. direction = o.direction || "up",
  12056. distance = o.distance,
  12057. times = o.times || 5,
  12058. // number of internal animations
  12059. anims = times * 2 + ( show || hide ? 1 : 0 ),
  12060. speed = o.duration / anims,
  12061. easing = o.easing,
  12062. // utility:
  12063. ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
  12064. motion = ( direction === "up" || direction === "left" ),
  12065. i,
  12066. upAnim,
  12067. downAnim,
  12068. // we will need to re-assemble the queue to stack our animations in place
  12069. queue = el.queue(),
  12070. queuelen = queue.length;
  12071. // Avoid touching opacity to prevent clearType and PNG issues in IE
  12072. if ( show || hide ) {
  12073. props.push( "opacity" );
  12074. }
  12075. $.effects.save( el, props );
  12076. el.show();
  12077. $.effects.createWrapper( el ); // Create Wrapper
  12078. // default distance for the BIGGEST bounce is the outer Distance / 3
  12079. if ( !distance ) {
  12080. distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
  12081. }
  12082. if ( show ) {
  12083. downAnim = { opacity: 1 };
  12084. downAnim[ ref ] = 0;
  12085. // if we are showing, force opacity 0 and set the initial position
  12086. // then do the "first" animation
  12087. el.css( "opacity", 0 )
  12088. .css( ref, motion ? -distance * 2 : distance * 2 )
  12089. .animate( downAnim, speed, easing );
  12090. }
  12091. // start at the smallest distance if we are hiding
  12092. if ( hide ) {
  12093. distance = distance / Math.pow( 2, times - 1 );
  12094. }
  12095. downAnim = {};
  12096. downAnim[ ref ] = 0;
  12097. // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
  12098. for ( i = 0; i < times; i++ ) {
  12099. upAnim = {};
  12100. upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
  12101. el.animate( upAnim, speed, easing )
  12102. .animate( downAnim, speed, easing );
  12103. distance = hide ? distance * 2 : distance / 2;
  12104. }
  12105. // Last Bounce when Hiding
  12106. if ( hide ) {
  12107. upAnim = { opacity: 0 };
  12108. upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
  12109. el.animate( upAnim, speed, easing );
  12110. }
  12111. el.queue(function() {
  12112. if ( hide ) {
  12113. el.hide();
  12114. }
  12115. $.effects.restore( el, props );
  12116. $.effects.removeWrapper( el );
  12117. done();
  12118. });
  12119. // inject all the animations we just queued to be first in line (after "inprogress")
  12120. if ( queuelen > 1) {
  12121. queue.splice.apply( queue,
  12122. [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
  12123. }
  12124. el.dequeue();
  12125. };
  12126. })(jQuery);
  12127. (function( $, undefined ) {
  12128. $.effects.effect.clip = function( o, done ) {
  12129. // Create element
  12130. var el = $( this ),
  12131. props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
  12132. mode = $.effects.setMode( el, o.mode || "hide" ),
  12133. show = mode === "show",
  12134. direction = o.direction || "vertical",
  12135. vert = direction === "vertical",
  12136. size = vert ? "height" : "width",
  12137. position = vert ? "top" : "left",
  12138. animation = {},
  12139. wrapper, animate, distance;
  12140. // Save & Show
  12141. $.effects.save( el, props );
  12142. el.show();
  12143. // Create Wrapper
  12144. wrapper = $.effects.createWrapper( el ).css({
  12145. overflow: "hidden"
  12146. });
  12147. animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
  12148. distance = animate[ size ]();
  12149. // Shift
  12150. if ( show ) {
  12151. animate.css( size, 0 );
  12152. animate.css( position, distance / 2 );
  12153. }
  12154. // Create Animation Object:
  12155. animation[ size ] = show ? distance : 0;
  12156. animation[ position ] = show ? 0 : distance / 2;
  12157. // Animate
  12158. animate.animate( animation, {
  12159. queue: false,
  12160. duration: o.duration,
  12161. easing: o.easing,
  12162. complete: function() {
  12163. if ( !show ) {
  12164. el.hide();
  12165. }
  12166. $.effects.restore( el, props );
  12167. $.effects.removeWrapper( el );
  12168. done();
  12169. }
  12170. });
  12171. };
  12172. })(jQuery);
  12173. (function( $, undefined ) {
  12174. $.effects.effect.drop = function( o, done ) {
  12175. var el = $( this ),
  12176. props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
  12177. mode = $.effects.setMode( el, o.mode || "hide" ),
  12178. show = mode === "show",
  12179. direction = o.direction || "left",
  12180. ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
  12181. motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
  12182. animation = {
  12183. opacity: show ? 1 : 0
  12184. },
  12185. distance;
  12186. // Adjust
  12187. $.effects.save( el, props );
  12188. el.show();
  12189. $.effects.createWrapper( el );
  12190. distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2;
  12191. if ( show ) {
  12192. el
  12193. .css( "opacity", 0 )
  12194. .css( ref, motion === "pos" ? -distance : distance );
  12195. }
  12196. // Animation
  12197. animation[ ref ] = ( show ?
  12198. ( motion === "pos" ? "+=" : "-=" ) :
  12199. ( motion === "pos" ? "-=" : "+=" ) ) +
  12200. distance;
  12201. // Animate
  12202. el.animate( animation, {
  12203. queue: false,
  12204. duration: o.duration,
  12205. easing: o.easing,
  12206. complete: function() {
  12207. if ( mode === "hide" ) {
  12208. el.hide();
  12209. }
  12210. $.effects.restore( el, props );
  12211. $.effects.removeWrapper( el );
  12212. done();
  12213. }
  12214. });
  12215. };
  12216. })(jQuery);
  12217. (function( $, undefined ) {
  12218. $.effects.effect.explode = function( o, done ) {
  12219. var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
  12220. cells = rows,
  12221. el = $( this ),
  12222. mode = $.effects.setMode( el, o.mode || "hide" ),
  12223. show = mode === "show",
  12224. // show and then visibility:hidden the element before calculating offset
  12225. offset = el.show().css( "visibility", "hidden" ).offset(),
  12226. // width and height of a piece
  12227. width = Math.ceil( el.outerWidth() / cells ),
  12228. height = Math.ceil( el.outerHeight() / rows ),
  12229. pieces = [],
  12230. // loop
  12231. i, j, left, top, mx, my;
  12232. // children animate complete:
  12233. function childComplete() {
  12234. pieces.push( this );
  12235. if ( pieces.length === rows * cells ) {
  12236. animComplete();
  12237. }
  12238. }
  12239. // clone the element for each row and cell.
  12240. for( i = 0; i < rows ; i++ ) { // ===>
  12241. top = offset.top + i * height;
  12242. my = i - ( rows - 1 ) / 2 ;
  12243. for( j = 0; j < cells ; j++ ) { // |||
  12244. left = offset.left + j * width;
  12245. mx = j - ( cells - 1 ) / 2 ;
  12246. // Create a clone of the now hidden main element that will be absolute positioned
  12247. // within a wrapper div off the -left and -top equal to size of our pieces
  12248. el
  12249. .clone()
  12250. .appendTo( "body" )
  12251. .wrap( "<div></div>" )
  12252. .css({
  12253. position: "absolute",
  12254. visibility: "visible",
  12255. left: -j * width,
  12256. top: -i * height
  12257. })
  12258. // select the wrapper - make it overflow: hidden and absolute positioned based on
  12259. // where the original was located +left and +top equal to the size of pieces
  12260. .parent()
  12261. .addClass( "ui-effects-explode" )
  12262. .css({
  12263. position: "absolute",
  12264. overflow: "hidden",
  12265. width: width,
  12266. height: height,
  12267. left: left + ( show ? mx * width : 0 ),
  12268. top: top + ( show ? my * height : 0 ),
  12269. opacity: show ? 0 : 1
  12270. }).animate({
  12271. left: left + ( show ? 0 : mx * width ),
  12272. top: top + ( show ? 0 : my * height ),
  12273. opacity: show ? 1 : 0
  12274. }, o.duration || 500, o.easing, childComplete );
  12275. }
  12276. }
  12277. function animComplete() {
  12278. el.css({
  12279. visibility: "visible"
  12280. });
  12281. $( pieces ).remove();
  12282. if ( !show ) {
  12283. el.hide();
  12284. }
  12285. done();
  12286. }
  12287. };
  12288. })(jQuery);
  12289. (function( $, undefined ) {
  12290. $.effects.effect.fade = function( o, done ) {
  12291. var el = $( this ),
  12292. mode = $.effects.setMode( el, o.mode || "toggle" );
  12293. el.animate({
  12294. opacity: mode
  12295. }, {
  12296. queue: false,
  12297. duration: o.duration,
  12298. easing: o.easing,
  12299. complete: done
  12300. });
  12301. };
  12302. })( jQuery );
  12303. (function( $, undefined ) {
  12304. $.effects.effect.fold = function( o, done ) {
  12305. // Create element
  12306. var el = $( this ),
  12307. props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
  12308. mode = $.effects.setMode( el, o.mode || "hide" ),
  12309. show = mode === "show",
  12310. hide = mode === "hide",
  12311. size = o.size || 15,
  12312. percent = /([0-9]+)%/.exec( size ),
  12313. horizFirst = !!o.horizFirst,
  12314. widthFirst = show !== horizFirst,
  12315. ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
  12316. duration = o.duration / 2,
  12317. wrapper, distance,
  12318. animation1 = {},
  12319. animation2 = {};
  12320. $.effects.save( el, props );
  12321. el.show();
  12322. // Create Wrapper
  12323. wrapper = $.effects.createWrapper( el ).css({
  12324. overflow: "hidden"
  12325. });
  12326. distance = widthFirst ?
  12327. [ wrapper.width(), wrapper.height() ] :
  12328. [ wrapper.height(), wrapper.width() ];
  12329. if ( percent ) {
  12330. size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
  12331. }
  12332. if ( show ) {
  12333. wrapper.css( horizFirst ? {
  12334. height: 0,
  12335. width: size
  12336. } : {
  12337. height: size,
  12338. width: 0
  12339. });
  12340. }
  12341. // Animation
  12342. animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
  12343. animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
  12344. // Animate
  12345. wrapper
  12346. .animate( animation1, duration, o.easing )
  12347. .animate( animation2, duration, o.easing, function() {
  12348. if ( hide ) {
  12349. el.hide();
  12350. }
  12351. $.effects.restore( el, props );
  12352. $.effects.removeWrapper( el );
  12353. done();
  12354. });
  12355. };
  12356. })(jQuery);
  12357. (function( $, undefined ) {
  12358. $.effects.effect.highlight = function( o, done ) {
  12359. var elem = $( this ),
  12360. props = [ "backgroundImage", "backgroundColor", "opacity" ],
  12361. mode = $.effects.setMode( elem, o.mode || "show" ),
  12362. animation = {
  12363. backgroundColor: elem.css( "backgroundColor" )
  12364. };
  12365. if (mode === "hide") {
  12366. animation.opacity = 0;
  12367. }
  12368. $.effects.save( elem, props );
  12369. elem
  12370. .show()
  12371. .css({
  12372. backgroundImage: "none",
  12373. backgroundColor: o.color || "#ffff99"
  12374. })
  12375. .animate( animation, {
  12376. queue: false,
  12377. duration: o.duration,
  12378. easing: o.easing,
  12379. complete: function() {
  12380. if ( mode === "hide" ) {
  12381. elem.hide();
  12382. }
  12383. $.effects.restore( elem, props );
  12384. done();
  12385. }
  12386. });
  12387. };
  12388. })(jQuery);
  12389. (function( $, undefined ) {
  12390. $.effects.effect.pulsate = function( o, done ) {
  12391. var elem = $( this ),
  12392. mode = $.effects.setMode( elem, o.mode || "show" ),
  12393. show = mode === "show",
  12394. hide = mode === "hide",
  12395. showhide = ( show || mode === "hide" ),
  12396. // showing or hiding leaves of the "last" animation
  12397. anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
  12398. duration = o.duration / anims,
  12399. animateTo = 0,
  12400. queue = elem.queue(),
  12401. queuelen = queue.length,
  12402. i;
  12403. if ( show || !elem.is(":visible")) {
  12404. elem.css( "opacity", 0 ).show();
  12405. animateTo = 1;
  12406. }
  12407. // anims - 1 opacity "toggles"
  12408. for ( i = 1; i < anims; i++ ) {
  12409. elem.animate({
  12410. opacity: animateTo
  12411. }, duration, o.easing );
  12412. animateTo = 1 - animateTo;
  12413. }
  12414. elem.animate({
  12415. opacity: animateTo
  12416. }, duration, o.easing);
  12417. elem.queue(function() {
  12418. if ( hide ) {
  12419. elem.hide();
  12420. }
  12421. done();
  12422. });
  12423. // We just queued up "anims" animations, we need to put them next in the queue
  12424. if ( queuelen > 1 ) {
  12425. queue.splice.apply( queue,
  12426. [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
  12427. }
  12428. elem.dequeue();
  12429. };
  12430. })(jQuery);
  12431. (function( $, undefined ) {
  12432. $.effects.effect.puff = function( o, done ) {
  12433. var elem = $( this ),
  12434. mode = $.effects.setMode( elem, o.mode || "hide" ),
  12435. hide = mode === "hide",
  12436. percent = parseInt( o.percent, 10 ) || 150,
  12437. factor = percent / 100,
  12438. original = {
  12439. height: elem.height(),
  12440. width: elem.width(),
  12441. outerHeight: elem.outerHeight(),
  12442. outerWidth: elem.outerWidth()
  12443. };
  12444. $.extend( o, {
  12445. effect: "scale",
  12446. queue: false,
  12447. fade: true,
  12448. mode: mode,
  12449. complete: done,
  12450. percent: hide ? percent : 100,
  12451. from: hide ?
  12452. original :
  12453. {
  12454. height: original.height * factor,
  12455. width: original.width * factor,
  12456. outerHeight: original.outerHeight * factor,
  12457. outerWidth: original.outerWidth * factor
  12458. }
  12459. });
  12460. elem.effect( o );
  12461. };
  12462. $.effects.effect.scale = function( o, done ) {
  12463. // Create element
  12464. var el = $( this ),
  12465. options = $.extend( true, {}, o ),
  12466. mode = $.effects.setMode( el, o.mode || "effect" ),
  12467. percent = parseInt( o.percent, 10 ) ||
  12468. ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
  12469. direction = o.direction || "both",
  12470. origin = o.origin,
  12471. original = {
  12472. height: el.height(),
  12473. width: el.width(),
  12474. outerHeight: el.outerHeight(),
  12475. outerWidth: el.outerWidth()
  12476. },
  12477. factor = {
  12478. y: direction !== "horizontal" ? (percent / 100) : 1,
  12479. x: direction !== "vertical" ? (percent / 100) : 1
  12480. };
  12481. // We are going to pass this effect to the size effect:
  12482. options.effect = "size";
  12483. options.queue = false;
  12484. options.complete = done;
  12485. // Set default origin and restore for show/hide
  12486. if ( mode !== "effect" ) {
  12487. options.origin = origin || ["middle","center"];
  12488. options.restore = true;
  12489. }
  12490. options.from = o.from || ( mode === "show" ? {
  12491. height: 0,
  12492. width: 0,
  12493. outerHeight: 0,
  12494. outerWidth: 0
  12495. } : original );
  12496. options.to = {
  12497. height: original.height * factor.y,
  12498. width: original.width * factor.x,
  12499. outerHeight: original.outerHeight * factor.y,
  12500. outerWidth: original.outerWidth * factor.x
  12501. };
  12502. // Fade option to support puff
  12503. if ( options.fade ) {
  12504. if ( mode === "show" ) {
  12505. options.from.opacity = 0;
  12506. options.to.opacity = 1;
  12507. }
  12508. if ( mode === "hide" ) {
  12509. options.from.opacity = 1;
  12510. options.to.opacity = 0;
  12511. }
  12512. }
  12513. // Animate
  12514. el.effect( options );
  12515. };
  12516. $.effects.effect.size = function( o, done ) {
  12517. // Create element
  12518. var original, baseline, factor,
  12519. el = $( this ),
  12520. props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
  12521. // Always restore
  12522. props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
  12523. // Copy for children
  12524. props2 = [ "width", "height", "overflow" ],
  12525. cProps = [ "fontSize" ],
  12526. vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
  12527. hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
  12528. // Set options
  12529. mode = $.effects.setMode( el, o.mode || "effect" ),
  12530. restore = o.restore || mode !== "effect",
  12531. scale = o.scale || "both",
  12532. origin = o.origin || [ "middle", "center" ],
  12533. position = el.css( "position" ),
  12534. props = restore ? props0 : props1,
  12535. zero = {
  12536. height: 0,
  12537. width: 0,
  12538. outerHeight: 0,
  12539. outerWidth: 0
  12540. };
  12541. if ( mode === "show" ) {
  12542. el.show();
  12543. }
  12544. original = {
  12545. height: el.height(),
  12546. width: el.width(),
  12547. outerHeight: el.outerHeight(),
  12548. outerWidth: el.outerWidth()
  12549. };
  12550. if ( o.mode === "toggle" && mode === "show" ) {
  12551. el.from = o.to || zero;
  12552. el.to = o.from || original;
  12553. } else {
  12554. el.from = o.from || ( mode === "show" ? zero : original );
  12555. el.to = o.to || ( mode === "hide" ? zero : original );
  12556. }
  12557. // Set scaling factor
  12558. factor = {
  12559. from: {
  12560. y: el.from.height / original.height,
  12561. x: el.from.width / original.width
  12562. },
  12563. to: {
  12564. y: el.to.height / original.height,
  12565. x: el.to.width / original.width
  12566. }
  12567. };
  12568. // Scale the css box
  12569. if ( scale === "box" || scale === "both" ) {
  12570. // Vertical props scaling
  12571. if ( factor.from.y !== factor.to.y ) {
  12572. props = props.concat( vProps );
  12573. el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
  12574. el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
  12575. }
  12576. // Horizontal props scaling
  12577. if ( factor.from.x !== factor.to.x ) {
  12578. props = props.concat( hProps );
  12579. el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
  12580. el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
  12581. }
  12582. }
  12583. // Scale the content
  12584. if ( scale === "content" || scale === "both" ) {
  12585. // Vertical props scaling
  12586. if ( factor.from.y !== factor.to.y ) {
  12587. props = props.concat( cProps ).concat( props2 );
  12588. el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
  12589. el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
  12590. }
  12591. }
  12592. $.effects.save( el, props );
  12593. el.show();
  12594. $.effects.createWrapper( el );
  12595. el.css( "overflow", "hidden" ).css( el.from );
  12596. // Adjust
  12597. if (origin) { // Calculate baseline shifts
  12598. baseline = $.effects.getBaseline( origin, original );
  12599. el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
  12600. el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
  12601. el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
  12602. el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
  12603. }
  12604. el.css( el.from ); // set top & left
  12605. // Animate
  12606. if ( scale === "content" || scale === "both" ) { // Scale the children
  12607. // Add margins/font-size
  12608. vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
  12609. hProps = hProps.concat([ "marginLeft", "marginRight" ]);
  12610. props2 = props0.concat(vProps).concat(hProps);
  12611. el.find( "*[width]" ).each( function(){
  12612. var child = $( this ),
  12613. c_original = {
  12614. height: child.height(),
  12615. width: child.width(),
  12616. outerHeight: child.outerHeight(),
  12617. outerWidth: child.outerWidth()
  12618. };
  12619. if (restore) {
  12620. $.effects.save(child, props2);
  12621. }
  12622. child.from = {
  12623. height: c_original.height * factor.from.y,
  12624. width: c_original.width * factor.from.x,
  12625. outerHeight: c_original.outerHeight * factor.from.y,
  12626. outerWidth: c_original.outerWidth * factor.from.x
  12627. };
  12628. child.to = {
  12629. height: c_original.height * factor.to.y,
  12630. width: c_original.width * factor.to.x,
  12631. outerHeight: c_original.height * factor.to.y,
  12632. outerWidth: c_original.width * factor.to.x
  12633. };
  12634. // Vertical props scaling
  12635. if ( factor.from.y !== factor.to.y ) {
  12636. child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
  12637. child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
  12638. }
  12639. // Horizontal props scaling
  12640. if ( factor.from.x !== factor.to.x ) {
  12641. child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
  12642. child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
  12643. }
  12644. // Animate children
  12645. child.css( child.from );
  12646. child.animate( child.to, o.duration, o.easing, function() {
  12647. // Restore children
  12648. if ( restore ) {
  12649. $.effects.restore( child, props2 );
  12650. }
  12651. });
  12652. });
  12653. }
  12654. // Animate
  12655. el.animate( el.to, {
  12656. queue: false,
  12657. duration: o.duration,
  12658. easing: o.easing,
  12659. complete: function() {
  12660. if ( el.to.opacity === 0 ) {
  12661. el.css( "opacity", el.from.opacity );
  12662. }
  12663. if( mode === "hide" ) {
  12664. el.hide();
  12665. }
  12666. $.effects.restore( el, props );
  12667. if ( !restore ) {
  12668. // we need to calculate our new positioning based on the scaling
  12669. if ( position === "static" ) {
  12670. el.css({
  12671. position: "relative",
  12672. top: el.to.top,
  12673. left: el.to.left
  12674. });
  12675. } else {
  12676. $.each([ "top", "left" ], function( idx, pos ) {
  12677. el.css( pos, function( _, str ) {
  12678. var val = parseInt( str, 10 ),
  12679. toRef = idx ? el.to.left : el.to.top;
  12680. // if original was "auto", recalculate the new value from wrapper
  12681. if ( str === "auto" ) {
  12682. return toRef + "px";
  12683. }
  12684. return val + toRef + "px";
  12685. });
  12686. });
  12687. }
  12688. }
  12689. $.effects.removeWrapper( el );
  12690. done();
  12691. }
  12692. });
  12693. };
  12694. })(jQuery);
  12695. (function( $, undefined ) {
  12696. $.effects.effect.shake = function( o, done ) {
  12697. var el = $( this ),
  12698. props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
  12699. mode = $.effects.setMode( el, o.mode || "effect" ),
  12700. direction = o.direction || "left",
  12701. distance = o.distance || 20,
  12702. times = o.times || 3,
  12703. anims = times * 2 + 1,
  12704. speed = Math.round(o.duration/anims),
  12705. ref = (direction === "up" || direction === "down") ? "top" : "left",
  12706. positiveMotion = (direction === "up" || direction === "left"),
  12707. animation = {},
  12708. animation1 = {},
  12709. animation2 = {},
  12710. i,
  12711. // we will need to re-assemble the queue to stack our animations in place
  12712. queue = el.queue(),
  12713. queuelen = queue.length;
  12714. $.effects.save( el, props );
  12715. el.show();
  12716. $.effects.createWrapper( el );
  12717. // Animation
  12718. animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
  12719. animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
  12720. animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
  12721. // Animate
  12722. el.animate( animation, speed, o.easing );
  12723. // Shakes
  12724. for ( i = 1; i < times; i++ ) {
  12725. el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
  12726. }
  12727. el
  12728. .animate( animation1, speed, o.easing )
  12729. .animate( animation, speed / 2, o.easing )
  12730. .queue(function() {
  12731. if ( mode === "hide" ) {
  12732. el.hide();
  12733. }
  12734. $.effects.restore( el, props );
  12735. $.effects.removeWrapper( el );
  12736. done();
  12737. });
  12738. // inject all the animations we just queued to be first in line (after "inprogress")
  12739. if ( queuelen > 1) {
  12740. queue.splice.apply( queue,
  12741. [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
  12742. }
  12743. el.dequeue();
  12744. };
  12745. })(jQuery);
  12746. (function( $, undefined ) {
  12747. $.effects.effect.slide = function( o, done ) {
  12748. // Create element
  12749. var el = $( this ),
  12750. props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
  12751. mode = $.effects.setMode( el, o.mode || "show" ),
  12752. show = mode === "show",
  12753. direction = o.direction || "left",
  12754. ref = (direction === "up" || direction === "down") ? "top" : "left",
  12755. positiveMotion = (direction === "up" || direction === "left"),
  12756. distance,
  12757. animation = {};
  12758. // Adjust
  12759. $.effects.save( el, props );
  12760. el.show();
  12761. distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
  12762. $.effects.createWrapper( el ).css({
  12763. overflow: "hidden"
  12764. });
  12765. if ( show ) {
  12766. el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
  12767. }
  12768. // Animation
  12769. animation[ ref ] = ( show ?
  12770. ( positiveMotion ? "+=" : "-=") :
  12771. ( positiveMotion ? "-=" : "+=")) +
  12772. distance;
  12773. // Animate
  12774. el.animate( animation, {
  12775. queue: false,
  12776. duration: o.duration,
  12777. easing: o.easing,
  12778. complete: function() {
  12779. if ( mode === "hide" ) {
  12780. el.hide();
  12781. }
  12782. $.effects.restore( el, props );
  12783. $.effects.removeWrapper( el );
  12784. done();
  12785. }
  12786. });
  12787. };
  12788. })(jQuery);
  12789. (function( $, undefined ) {
  12790. $.effects.effect.transfer = function( o, done ) {
  12791. var elem = $( this ),
  12792. target = $( o.to ),
  12793. targetFixed = target.css( "position" ) === "fixed",
  12794. body = $("body"),
  12795. fixTop = targetFixed ? body.scrollTop() : 0,
  12796. fixLeft = targetFixed ? body.scrollLeft() : 0,
  12797. endPosition = target.offset(),
  12798. animation = {
  12799. top: endPosition.top - fixTop ,
  12800. left: endPosition.left - fixLeft ,
  12801. height: target.innerHeight(),
  12802. width: target.innerWidth()
  12803. },
  12804. startPosition = elem.offset(),
  12805. transfer = $( '<div class="ui-effects-transfer"></div>' )
  12806. .appendTo( document.body )
  12807. .addClass( o.className )
  12808. .css({
  12809. top: startPosition.top - fixTop ,
  12810. left: startPosition.left - fixLeft ,
  12811. height: elem.innerHeight(),
  12812. width: elem.innerWidth(),
  12813. position: targetFixed ? "fixed" : "absolute"
  12814. })
  12815. .animate( animation, o.duration, o.easing, function() {
  12816. transfer.remove();
  12817. done();
  12818. });
  12819. };
  12820. })(jQuery);