dijit.js.uncompressed.js 257 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838
  1. require({cache:{
  2. 'dojo/uacss':function(){
  3. define(["./dom-geometry", "./_base/lang", "./ready", "./_base/sniff", "./_base/window"],
  4. function(geometry, lang, ready, has, baseWindow){
  5. // module:
  6. // dojo/uacss
  7. // summary:
  8. // Applies pre-set CSS classes to the top-level HTML node, based on:
  9. // - browser (ex: dj_ie)
  10. // - browser version (ex: dj_ie6)
  11. // - box model (ex: dj_contentBox)
  12. // - text direction (ex: dijitRtl)
  13. //
  14. // In addition, browser, browser version, and box model are
  15. // combined with an RTL flag when browser text is RTL. ex: dj_ie-rtl.
  16. var
  17. html = baseWindow.doc.documentElement,
  18. ie = has("ie"),
  19. opera = has("opera"),
  20. maj = Math.floor,
  21. ff = has("ff"),
  22. boxModel = geometry.boxModel.replace(/-/,''),
  23. classes = {
  24. "dj_quirks": has("quirks"),
  25. // NOTE: Opera not supported by dijit
  26. "dj_opera": opera,
  27. "dj_khtml": has("khtml"),
  28. "dj_webkit": has("webkit"),
  29. "dj_safari": has("safari"),
  30. "dj_chrome": has("chrome"),
  31. "dj_gecko": has("mozilla")
  32. }; // no dojo unsupported browsers
  33. if(ie){
  34. classes["dj_ie"] = true;
  35. classes["dj_ie" + maj(ie)] = true;
  36. classes["dj_iequirks"] = has("quirks");
  37. }
  38. if(ff){
  39. classes["dj_ff" + maj(ff)] = true;
  40. }
  41. classes["dj_" + boxModel] = true;
  42. // apply browser, browser version, and box model class names
  43. var classStr = "";
  44. for(var clz in classes){
  45. if(classes[clz]){
  46. classStr += clz + " ";
  47. }
  48. }
  49. html.className = lang.trim(html.className + " " + classStr);
  50. // If RTL mode, then add dj_rtl flag plus repeat existing classes with -rtl extension.
  51. // We can't run the code below until the <body> tag has loaded (so we can check for dir=rtl).
  52. // priority is 90 to run ahead of parser priority of 100
  53. ready(90, function(){
  54. if(!geometry.isBodyLtr()){
  55. var rtlClassStr = "dj_rtl dijitRtl " + classStr.replace(/ /g, "-rtl ");
  56. html.className = lang.trim(html.className + " " + rtlClassStr + "dj_rtl dijitRtl " + classStr.replace(/ /g, "-rtl "));
  57. }
  58. });
  59. return has;
  60. });
  61. },
  62. 'dijit/hccss':function(){
  63. define("dijit/hccss", [
  64. "require", // require.toUrl
  65. "dojo/_base/config", // config.blankGif
  66. "dojo/dom-class", // domClass.add domConstruct.create domStyle.getComputedStyle
  67. "dojo/dom-construct", // domClass.add domConstruct.create domStyle.getComputedStyle
  68. "dojo/dom-style", // domClass.add domConstruct.create domStyle.getComputedStyle
  69. "dojo/ready", // ready
  70. "dojo/_base/sniff", // has("ie") has("mozilla")
  71. "dojo/_base/window" // win.body
  72. ], function(require, config, domClass, domConstruct, domStyle, ready, has, win){
  73. // module:
  74. // dijit/hccss
  75. // summary:
  76. // Test if computer is in high contrast mode, and sets dijit_a11y flag on <body> if it is.
  77. if(has("ie") || has("mozilla")){ // NOTE: checking in Safari messes things up
  78. // priority is 90 to run ahead of parser priority of 100
  79. ready(90, function(){
  80. // summary:
  81. // Detects if we are in high-contrast mode or not
  82. // create div for testing if high contrast mode is on or images are turned off
  83. var div = domConstruct.create("div",{
  84. id: "a11yTestNode",
  85. style:{
  86. cssText:'border: 1px solid;'
  87. + 'border-color:red green;'
  88. + 'position: absolute;'
  89. + 'height: 5px;'
  90. + 'top: -999px;'
  91. + 'background-image: url("' + (config.blankGif || require.toUrl("dojo/resources/blank.gif")) + '");'
  92. }
  93. }, win.body());
  94. // test it
  95. var cs = domStyle.getComputedStyle(div);
  96. if(cs){
  97. var bkImg = cs.backgroundImage;
  98. var needsA11y = (cs.borderTopColor == cs.borderRightColor) || (bkImg != null && (bkImg == "none" || bkImg == "url(invalid-url:)" ));
  99. if(needsA11y){
  100. domClass.add(win.body(), "dijit_a11y");
  101. }
  102. if(has("ie")){
  103. div.outerHTML = ""; // prevent mixed-content warning, see http://support.microsoft.com/kb/925014
  104. }else{
  105. win.body().removeChild(div);
  106. }
  107. }
  108. });
  109. }
  110. });
  111. },
  112. 'dijit/_Contained':function(){
  113. define("dijit/_Contained", [
  114. "dojo/_base/declare", // declare
  115. "./registry" // registry.getEnclosingWidget(), registry.byNode()
  116. ], function(declare, registry){
  117. // module:
  118. // dijit/_Contained
  119. // summary:
  120. // Mixin for widgets that are children of a container widget
  121. return declare("dijit._Contained", null, {
  122. // summary:
  123. // Mixin for widgets that are children of a container widget
  124. //
  125. // example:
  126. // | // make a basic custom widget that knows about it's parents
  127. // | declare("my.customClass",[dijit._Widget,dijit._Contained],{});
  128. _getSibling: function(/*String*/ which){
  129. // summary:
  130. // Returns next or previous sibling
  131. // which:
  132. // Either "next" or "previous"
  133. // tags:
  134. // private
  135. var node = this.domNode;
  136. do{
  137. node = node[which+"Sibling"];
  138. }while(node && node.nodeType != 1);
  139. return node && registry.byNode(node); // dijit._Widget
  140. },
  141. getPreviousSibling: function(){
  142. // summary:
  143. // Returns null if this is the first child of the parent,
  144. // otherwise returns the next element sibling to the "left".
  145. return this._getSibling("previous"); // dijit._Widget
  146. },
  147. getNextSibling: function(){
  148. // summary:
  149. // Returns null if this is the last child of the parent,
  150. // otherwise returns the next element sibling to the "right".
  151. return this._getSibling("next"); // dijit._Widget
  152. },
  153. getIndexInParent: function(){
  154. // summary:
  155. // Returns the index of this widget within its container parent.
  156. // It returns -1 if the parent does not exist, or if the parent
  157. // is not a dijit._Container
  158. var p = this.getParent();
  159. if(!p || !p.getIndexOfChild){
  160. return -1; // int
  161. }
  162. return p.getIndexOfChild(this); // int
  163. }
  164. });
  165. });
  166. },
  167. 'dijit/Viewport':function(){
  168. define("dijit/Viewport", [
  169. "dojo/Evented",
  170. "dojo/on",
  171. "dojo/ready",
  172. "dojo/_base/sniff",
  173. "dojo/_base/window", // global
  174. "dojo/window" // getBox()
  175. ], function(Evented, on, ready, has, win, winUtils){
  176. // module:
  177. // dijit/Viewport
  178. /*=====
  179. return {
  180. // summary:
  181. // Utility singleton to watch for viewport resizes, avoiding duplicate notifications
  182. // which can lead to infinite loops.
  183. // description:
  184. // Usage: Viewport.on("resize", myCallback).
  185. //
  186. // myCallback() is called without arguments in case it's _WidgetBase.resize(),
  187. // which would interpret the argument as the size to make the widget.
  188. };
  189. =====*/
  190. var Viewport = new Evented();
  191. var focusedNode;
  192. ready(200, function(){
  193. var oldBox = winUtils.getBox();
  194. Viewport._rlh = on(win.global, "resize", function(){
  195. var newBox = winUtils.getBox();
  196. if(oldBox.h == newBox.h && oldBox.w == newBox.w){ return; }
  197. oldBox = newBox;
  198. Viewport.emit("resize");
  199. });
  200. // Also catch zoom changes on IE8, since they don't naturally generate resize events
  201. if(has("ie") == 8){
  202. var deviceXDPI = screen.deviceXDPI;
  203. setInterval(function(){
  204. if(screen.deviceXDPI != deviceXDPI){
  205. deviceXDPI = screen.deviceXDPI;
  206. Viewport.emit("resize");
  207. }
  208. }, 500);
  209. }
  210. // On iOS, keep track of the focused node so we can guess when the keyboard is/isn't being displayed.
  211. if(has("ios")){
  212. on(document, "focusin", function(evt){
  213. focusedNode = evt.target;
  214. });
  215. on(document, "focusout", function(evt){
  216. focusedNode = null;
  217. });
  218. }
  219. });
  220. Viewport.getEffectiveBox = function(/*Document*/ doc){
  221. // summary:
  222. // Get the size of the viewport, or on mobile devices, the part of the viewport not obscured by the
  223. // virtual keyboard.
  224. var box = winUtils.getBox(doc);
  225. // Account for iOS virtual keyboard, if it's being shown. Unfortunately no direct way to check or measure.
  226. var tag = focusedNode && focusedNode.tagName && focusedNode.tagName.toLowerCase();
  227. if(has("ios") && focusedNode && !focusedNode.readOnly && (tag == "textarea" || (tag == "input" &&
  228. /^(color|email|number|password|search|tel|text|url)$/.test(focusedNode.type)))){
  229. // Box represents the size of the viewport. Some of the viewport is likely covered by the keyboard.
  230. // Estimate height of visible viewport assuming viewport goes to bottom of screen, but is covered by keyboard.
  231. box.h *= (orientation == 0 || orientation == 180 ? 0.66 : 0.40);
  232. // Above measurement will be inaccurate if viewport was scrolled up so far that it ends before the bottom
  233. // of the screen. In this case, keyboard isn't covering as much of the viewport as we thought.
  234. // We know the visible size is at least the distance from the top of the viewport to the focused node.
  235. var rect = focusedNode.getBoundingClientRect();
  236. box.h = Math.max(box.h, rect.top + rect.height);
  237. }
  238. return box;
  239. };
  240. return Viewport;
  241. });
  242. },
  243. 'dojo/parser':function(){
  244. define(
  245. ["./_base/kernel", "./_base/lang", "./_base/array", "./_base/config", "./_base/html", "./_base/window", "./_base/url",
  246. "./_base/json", "./aspect", "./date/stamp", "./has", "./query", "./on", "./ready"],
  247. function(dojo, dlang, darray, config, dhtml, dwindow, _Url, djson, aspect, dates, has, query, don, ready){
  248. // module:
  249. // dojo/parser
  250. // summary:
  251. // The Dom/Widget parsing package
  252. new Date("X"); // workaround for #11279, new Date("") == NaN
  253. if (1) {
  254. var form = document.createElement("form");
  255. // Test if DOMNode.attributes only lists the attributes the user specified, not attributes w/default values.
  256. has.add("dom-attributes-explicit", form.attributes.length == 0);
  257. // IE8 will erroneously list a few attributes that weren't specified,
  258. // but we know to skip them because they have a specified flag which is false
  259. has.add("dom-attributes-specified-flag", form.attributes.length < 40);
  260. // Otherwise, it's IE6-7 form.attributes will list hundreds of values, need to do outerHTML instead.
  261. }
  262. dojo.parser = new function(){
  263. // summary:
  264. // The Dom/Widget parsing package
  265. var _nameMap = {
  266. // Map from widget name (ex: "dijit.form.Button") to structure mapping
  267. // lowercase version of attribute names to the version in the widget ex:
  268. // {
  269. // label: "label",
  270. // onclick: "onClick"
  271. // }
  272. };
  273. function getNameMap(proto){
  274. // summary:
  275. // Returns map from lowercase name to attribute name in class, ex: {onclick: "onClick"}
  276. var map = {};
  277. for(var name in proto){
  278. if(name.charAt(0)=="_"){ continue; } // skip internal properties
  279. map[name.toLowerCase()] = name;
  280. }
  281. return map;
  282. }
  283. // Widgets like BorderContainer add properties to _Widget via dojo.extend().
  284. // If BorderContainer is loaded after _Widget's parameter list has been cached,
  285. // we need to refresh that parameter list (for _Widget and all widgets that extend _Widget).
  286. aspect.after(dlang, "extend", function(){
  287. _nameMap = {};
  288. }, true);
  289. // Map from widget name (ex: "dijit.form.Button") to a map of { "list-of-mixins": ctor }
  290. // if "list-of-mixins" is "__type" this is the raw type without mixins
  291. var _ctorMap = {};
  292. function getCtor(type){
  293. var map = _ctorMap[type] || (_ctorMap[type] = {});
  294. return map["__type"] || (map["__type"] = (dlang.getObject(type) || require(type)));
  295. }
  296. this._functionFromScript = function(script, attrData){
  297. // summary:
  298. // Convert a <script type="dojo/method" args="a, b, c"> ... </script>
  299. // into a function
  300. // script: DOMNode
  301. // The <script> DOMNode
  302. // attrData: String
  303. // For HTML5 compliance, searches for attrData + "args" (typically
  304. // "data-dojo-args") instead of "args"
  305. var preamble = "";
  306. var suffix = "";
  307. var argsStr = (script.getAttribute(attrData + "args") || script.getAttribute("args"));
  308. if(argsStr){
  309. darray.forEach(argsStr.split(/\s*,\s*/), function(part, idx){
  310. preamble += "var "+part+" = arguments["+idx+"]; ";
  311. });
  312. }
  313. var withStr = script.getAttribute("with");
  314. if(withStr && withStr.length){
  315. darray.forEach(withStr.split(/\s*,\s*/), function(part){
  316. preamble += "with("+part+"){";
  317. suffix += "}";
  318. });
  319. }
  320. return new Function(preamble+script.innerHTML+suffix);
  321. };
  322. this.instantiate = /*====== dojo.parser.instantiate= ======*/ function(nodes, mixin, options) {
  323. // summary:
  324. // Takes array of nodes, and turns them into class instances and
  325. // potentially calls a startup method to allow them to connect with
  326. // any children.
  327. // nodes: Array
  328. // Array of DOM nodes
  329. // mixin: Object?
  330. // An object that will be mixed in with each node in the array.
  331. // Values in the mixin will override values in the node, if they
  332. // exist.
  333. // options: Object?
  334. // An object used to hold kwArgs for instantiation.
  335. // See parse.options argument for details.
  336. mixin = mixin || {};
  337. options = options || {};
  338. var dojoType = (options.scope || dojo._scopeName) + "Type", // typically "dojoType"
  339. attrData = "data-" + (options.scope || dojo._scopeName) + "-",// typically "data-dojo-"
  340. dataDojoType = attrData + "type"; // typically "data-dojo-type"
  341. var list = [];
  342. darray.forEach(nodes, function(node){
  343. var type = dojoType in mixin ? mixin[dojoType] : node.getAttribute(dataDojoType) || node.getAttribute(dojoType);
  344. if(type){
  345. list.push({
  346. node: node,
  347. "type": type
  348. });
  349. }
  350. });
  351. // Instantiate the nodes and return the objects
  352. return this._instantiate(list, mixin, options);
  353. };
  354. this._instantiate = /*====== dojo.parser.instantiate= ======*/ function(nodes, mixin, options){
  355. // summary:
  356. // Takes array of objects representing nodes, and turns them into class instances and
  357. // potentially calls a startup method to allow them to connect with
  358. // any children.
  359. // nodes: Array
  360. // Array of objects like
  361. // | {
  362. // | type: "dijit.form.Button",
  363. // | node: DOMNode,
  364. // | scripts: [ ... ], // array of <script type="dojo/..."> children of node
  365. // | inherited: { ... } // settings inherited from ancestors like dir, theme, etc.
  366. // | }
  367. // mixin: Object
  368. // An object that will be mixed in with each node in the array.
  369. // Values in the mixin will override values in the node, if they
  370. // exist.
  371. // options: Object
  372. // An options object used to hold kwArgs for instantiation.
  373. // See parse.options argument for details.
  374. var thelist = [];
  375. // Precompute names of special attributes we are looking for
  376. // TODO: for 2.0 default to data-dojo- regardless of scopeName (or maybe scopeName won't exist in 2.0)
  377. var dojoType = (options.scope || dojo._scopeName) + "Type", // typically "dojoType"
  378. attrData = "data-" + (options.scope || dojo._scopeName) + "-",// typically "data-dojo-"
  379. dataDojoType = attrData + "type", // typically "data-dojo-type"
  380. dataDojoProps = attrData + "props", // typically "data-dojo-props"
  381. dataDojoAttachPoint = attrData + "attach-point",
  382. dataDojoAttachEvent = attrData + "attach-event",
  383. dataDojoId = attrData + "id",
  384. dataDojoMixins = attrData + "mixins";
  385. // And make hash to quickly check if a given attribute is special, and to map the name to something friendly
  386. var specialAttrs = {};
  387. darray.forEach([dataDojoProps, dataDojoType, dojoType, dataDojoId, "jsId", dataDojoAttachPoint,
  388. dataDojoAttachEvent, "dojoAttachPoint", "dojoAttachEvent", "class", "style", dataDojoMixins], function(name){
  389. specialAttrs[name.toLowerCase()] = name.replace(options.scope, "dojo");
  390. });
  391. function extend(type, mixins){
  392. return type.createSubclass && type.createSubclass(mixins) || type.extend.apply(type, mixins);
  393. }
  394. darray.forEach(nodes, function(obj){
  395. if(!obj){ return; }
  396. var node = obj.node,
  397. type = obj.type,
  398. mixins = node.getAttribute(dataDojoMixins), ctor;
  399. if(mixins){
  400. var map = _ctorMap[type];
  401. // remove whitespaces
  402. mixins = mixins.replace(/ /g, "");
  403. ctor = map && map[mixins];
  404. if(!ctor){
  405. // first get ctor for raw type (& create _ctorMap[type] if needed (should not be))
  406. ctor = getCtor(type);
  407. // then do the mixin
  408. ctor = _ctorMap[type][mixins] = extend(ctor, darray.map(mixins.split(","), getCtor));
  409. }
  410. }else{
  411. ctor = getCtor(type);
  412. }
  413. var proto = ctor && ctor.prototype;
  414. // Setup hash to hold parameter settings for this widget. Start with the parameter
  415. // settings inherited from ancestors ("dir" and "lang").
  416. // Inherited setting may later be overridden by explicit settings on node itself.
  417. var params = {};
  418. if(options.defaults){
  419. // settings for the document itself (or whatever subtree is being parsed)
  420. dlang.mixin(params, options.defaults);
  421. }
  422. if(obj.inherited){
  423. // settings from dir=rtl or lang=... on a node above this node
  424. dlang.mixin(params, obj.inherited);
  425. }
  426. // Get list of attributes explicitly listed in the markup
  427. var attributes;
  428. if(has("dom-attributes-explicit")){
  429. // Standard path to get list of user specified attributes
  430. attributes = node.attributes;
  431. }else if(has("dom-attributes-specified-flag")){
  432. // Special processing needed for IE8, to skip a few faux values in attributes[]
  433. attributes = darray.filter(node.attributes, function(a){ return a.specified;});
  434. }else{
  435. // Special path for IE6-7, avoid (sometimes >100) bogus entries in node.attributes
  436. var clone = /^input$|^img$/i.test(node.nodeName) ? node : node.cloneNode(false),
  437. attrs = clone.outerHTML.replace(/=[^\s"']+|="[^"]*"|='[^']*'/g, "").replace(/^\s*<[a-zA-Z0-9]*\s*/, "").replace(/\s*>.*$/, "");
  438. attributes = darray.map(attrs.split(/\s+/), function(name){
  439. var lcName = name.toLowerCase();
  440. return {
  441. name: name,
  442. // getAttribute() doesn't work for button.value, returns innerHTML of button.
  443. // but getAttributeNode().value doesn't work for the form.encType or li.value
  444. value: (node.nodeName == "LI" && name == "value") || lcName == "enctype" ?
  445. node.getAttribute(lcName) : node.getAttributeNode(lcName).value
  446. };
  447. });
  448. }
  449. // Read in attributes and process them, including data-dojo-props, data-dojo-type,
  450. // dojoAttachPoint, etc., as well as normal foo=bar attributes.
  451. var i=0, item;
  452. while(item = attributes[i++]){
  453. var name = item.name,
  454. lcName = name.toLowerCase(),
  455. value = item.value;
  456. if(lcName in specialAttrs){
  457. switch(specialAttrs[lcName]){
  458. // Data-dojo-props. Save for later to make sure it overrides direct foo=bar settings
  459. case "data-dojo-props":
  460. var extra = value;
  461. break;
  462. // data-dojo-id or jsId. TODO: drop jsId in 2.0
  463. case "data-dojo-id":
  464. case "jsId":
  465. var jsname = value;
  466. break;
  467. // For the benefit of _Templated
  468. case "data-dojo-attach-point":
  469. case "dojoAttachPoint":
  470. params.dojoAttachPoint = value;
  471. break;
  472. case "data-dojo-attach-event":
  473. case "dojoAttachEvent":
  474. params.dojoAttachEvent = value;
  475. break;
  476. // Special parameter handling needed for IE
  477. case "class":
  478. params["class"] = node.className;
  479. break;
  480. case "style":
  481. params["style"] = node.style && node.style.cssText;
  482. break;
  483. }
  484. }else{
  485. // Normal attribute, ex: value="123"
  486. // Find attribute in widget corresponding to specified name.
  487. // May involve case conversion, ex: onclick --> onClick
  488. if(!(name in proto)){
  489. var map = (_nameMap[type] || (_nameMap[type] = getNameMap(proto)));
  490. name = map[lcName] || name;
  491. }
  492. // Set params[name] to value, doing type conversion
  493. if(name in proto){
  494. switch(typeof proto[name]){
  495. case "string":
  496. params[name] = value;
  497. break;
  498. case "number":
  499. params[name] = value.length ? Number(value) : NaN;
  500. break;
  501. case "boolean":
  502. // for checked/disabled value might be "" or "checked". interpret as true.
  503. params[name] = value.toLowerCase() != "false";
  504. break;
  505. case "function":
  506. if(value === "" || value.search(/[^\w\.]+/i) != -1){
  507. // The user has specified some text for a function like "return x+5"
  508. params[name] = new Function(value);
  509. }else{
  510. // The user has specified the name of a function like "myOnClick"
  511. // or a single word function "return"
  512. params[name] = dlang.getObject(value, false) || new Function(value);
  513. }
  514. break;
  515. default:
  516. var pVal = proto[name];
  517. params[name] =
  518. (pVal && "length" in pVal) ? (value ? value.split(/\s*,\s*/) : []) : // array
  519. (pVal instanceof Date) ?
  520. (value == "" ? new Date("") : // the NaN of dates
  521. value == "now" ? new Date() : // current date
  522. dates.fromISOString(value)) :
  523. (pVal instanceof dojo._Url) ? (dojo.baseUrl + value) :
  524. djson.fromJson(value);
  525. }
  526. }else{
  527. params[name] = value;
  528. }
  529. }
  530. }
  531. // Mix things found in data-dojo-props into the params, overriding any direct settings
  532. if(extra){
  533. try{
  534. extra = djson.fromJson.call(options.propsThis, "{" + extra + "}");
  535. dlang.mixin(params, extra);
  536. }catch(e){
  537. // give the user a pointer to their invalid parameters. FIXME: can we kill this in production?
  538. throw new Error(e.toString() + " in data-dojo-props='" + extra + "'");
  539. }
  540. }
  541. // Any parameters specified in "mixin" override everything else.
  542. dlang.mixin(params, mixin);
  543. var scripts = obj.scripts || (ctor && (ctor._noScript || proto._noScript) ? [] :
  544. query("> script[type^='dojo/']", node));
  545. // Process <script type="dojo/*"> script tags
  546. // <script type="dojo/method" event="foo"> tags are added to params, and passed to
  547. // the widget on instantiation.
  548. // <script type="dojo/method"> tags (with no event) are executed after instantiation
  549. // <script type="dojo/connect" data-dojo-event="foo"> tags are dojo.connected after instantiation
  550. // <script type="dojo/watch" data-dojo-prop="foo"> tags are dojo.watch after instantiation
  551. // <script type="dojo/on" data-dojo-event="foo"> tags are dojo.on after instantiation
  552. // note: dojo/* script tags cannot exist in self closing widgets, like <input />
  553. var connects = [], // functions to connect after instantiation
  554. calls = [], // functions to call after instantiation
  555. watch = [], //functions to watch after instantiation
  556. on = []; //functions to on after instantiation
  557. if(scripts){
  558. for(i=0; i<scripts.length; i++){
  559. var script = scripts[i];
  560. node.removeChild(script);
  561. // FIXME: drop event="" support in 2.0. use data-dojo-event="" instead
  562. var event = (script.getAttribute(attrData + "event") || script.getAttribute("event")),
  563. prop = script.getAttribute(attrData + "prop"),
  564. scriptType = script.getAttribute("type"),
  565. nf = this._functionFromScript(script, attrData);
  566. if(event){
  567. if(scriptType == "dojo/connect"){
  568. connects.push({event: event, func: nf});
  569. }else if(scriptType == "dojo/on"){
  570. on.push({event: event, func: nf});
  571. }else{
  572. params[event] = nf;
  573. }
  574. }else if(scriptType == "dojo/watch"){
  575. watch.push({prop: prop, func: nf});
  576. }else{
  577. calls.push(nf);
  578. }
  579. }
  580. }
  581. // create the instance
  582. var markupFactory = ctor.markupFactory || proto.markupFactory;
  583. var instance = markupFactory ? markupFactory(params, node, ctor) : new ctor(params, node);
  584. thelist.push(instance);
  585. // map it to the JS namespace if that makes sense
  586. if(jsname){
  587. dlang.setObject(jsname, instance);
  588. }
  589. // process connections and startup functions
  590. for(i=0; i<connects.length; i++){
  591. aspect.after(instance, connects[i].event, dojo.hitch(instance, connects[i].func), true);
  592. }
  593. for(i=0; i<calls.length; i++){
  594. calls[i].call(instance);
  595. }
  596. for(i=0; i<watch.length; i++){
  597. instance.watch(watch[i].prop, watch[i].func);
  598. }
  599. for(i=0; i<on.length; i++){
  600. don(instance, on[i].event, on[i].func);
  601. }
  602. }, this);
  603. // Call startup on each top level instance if it makes sense (as for
  604. // widgets). Parent widgets will recursively call startup on their
  605. // (non-top level) children
  606. if(!mixin._started){
  607. darray.forEach(thelist, function(instance){
  608. if( !options.noStart && instance &&
  609. dlang.isFunction(instance.startup) &&
  610. !instance._started
  611. ){
  612. instance.startup();
  613. }
  614. });
  615. }
  616. return thelist;
  617. };
  618. this.scan = /*====== dojo.parser.scan= ======*/ function(root, options){
  619. // summary:
  620. // Scan a DOM tree and return an array of objects representing the DOMNodes
  621. // that need to be turned into widgets.
  622. // description:
  623. // Search specified node (or document root node) recursively for class instances
  624. // and return an array of objects that represent potential widgets to be
  625. // instantiated. Searches for either data-dojo-type="MID" or dojoType="MID" where
  626. // "MID" is a module ID like "dijit/form/Button" or a fully qualified Class name
  627. // like "dijit.form.Button".
  628. //
  629. // See parser.parse() for details of markup.
  630. // root: DomNode?
  631. // A default starting root node from which to start the parsing. Can be
  632. // omitted, defaulting to the entire document. If omitted, the `options`
  633. // object can be passed in this place. If the `options` object has a
  634. // `rootNode` member, that is used.
  635. // options: Object
  636. // a kwArgs options object, see parse() for details
  637. // Output list
  638. var list = [];
  639. var dojoType = (options.scope || dojo._scopeName) + "Type", // typically "dojoType"
  640. attrData = "data-" + (options.scope || dojo._scopeName) + "-", // typically "data-dojo-"
  641. dataDojoType = attrData + "type", // typically "data-dojo-type"
  642. dataDojoTextDir = attrData + "textdir"; // typically "data-dojo-textdir"
  643. // Info on DOMNode currently being processed
  644. var node = root.firstChild;
  645. // Info on parent of DOMNode currently being processed
  646. // - inherited: dir, lang, and textDir setting of parent, or inherited by parent
  647. // - parent: pointer to identical structure for my parent (or null if no parent)
  648. // - scripts: if specified, collects <script type="dojo/..."> type nodes from children
  649. var inherited = options.inherited;
  650. if(!inherited){
  651. function findAncestorAttr(node, attr){
  652. return (node.getAttribute && node.getAttribute(attr)) ||
  653. (node !== dwindow.doc && node !== dwindow.doc.documentElement && node.parentNode ? findAncestorAttr(node.parentNode, attr) : null);
  654. }
  655. inherited = {
  656. dir: findAncestorAttr(root, "dir"),
  657. lang: findAncestorAttr(root, "lang"),
  658. textDir: findAncestorAttr(root, dataDojoTextDir)
  659. };
  660. for(var key in inherited){
  661. if(!inherited[key]){ delete inherited[key]; }
  662. }
  663. }
  664. var parent = {
  665. inherited: inherited
  666. };
  667. // For collecting <script type="dojo/..."> type nodes (when null, we don't need to collect)
  668. var scripts;
  669. // when true, only look for <script type="dojo/..."> tags, and don't recurse to children
  670. var scriptsOnly;
  671. function getEffective(parent){
  672. // summary:
  673. // Get effective dir, lang, textDir settings for specified obj
  674. // (matching "parent" object structure above), and do caching.
  675. // Take care not to return null entries.
  676. if(!parent.inherited){
  677. parent.inherited = {};
  678. var node = parent.node,
  679. grandparent = getEffective(parent.parent);
  680. var inherited = {
  681. dir: node.getAttribute("dir") || grandparent.dir,
  682. lang: node.getAttribute("lang") || grandparent.lang,
  683. textDir: node.getAttribute(dataDojoTextDir) || grandparent.textDir
  684. };
  685. for(var key in inherited){
  686. if(inherited[key]){
  687. parent.inherited[key] = inherited[key];
  688. }
  689. }
  690. }
  691. return parent.inherited;
  692. }
  693. // DFS on DOM tree, collecting nodes with data-dojo-type specified.
  694. while(true){
  695. if(!node){
  696. // Finished this level, continue to parent's next sibling
  697. if(!parent || !parent.node){
  698. break;
  699. }
  700. node = parent.node.nextSibling;
  701. scripts = parent.scripts;
  702. scriptsOnly = false;
  703. parent = parent.parent;
  704. continue;
  705. }
  706. if(node.nodeType != 1){
  707. // Text or comment node, skip to next sibling
  708. node = node.nextSibling;
  709. continue;
  710. }
  711. if(scripts && node.nodeName.toLowerCase() == "script"){
  712. // Save <script type="dojo/..."> for parent, then continue to next sibling
  713. type = node.getAttribute("type");
  714. if(type && /^dojo\/\w/i.test(type)){
  715. scripts.push(node);
  716. }
  717. node = node.nextSibling;
  718. continue;
  719. }
  720. if(scriptsOnly){
  721. node = node.nextSibling;
  722. continue;
  723. }
  724. // Check for data-dojo-type attribute, fallback to backward compatible dojoType
  725. var type = node.getAttribute(dataDojoType) || node.getAttribute(dojoType);
  726. // Short circuit for leaf nodes containing nothing [but text]
  727. var firstChild = node.firstChild;
  728. if(!type && (!firstChild || (firstChild.nodeType == 3 && !firstChild.nextSibling))){
  729. node = node.nextSibling;
  730. continue;
  731. }
  732. // Setup data structure to save info on current node for when we return from processing descendant nodes
  733. var current = {
  734. node: node,
  735. scripts: scripts,
  736. parent: parent
  737. };
  738. // If dojoType/data-dojo-type specified, add to output array of nodes to instantiate
  739. // Note: won't find classes declared via dojo.Declaration, so use try/catch to avoid throw from require()
  740. // We don't care yet about mixins ctors, we check script stop only on main class
  741. var ctor;
  742. try{
  743. ctor = type && getCtor(type);
  744. }catch(e){
  745. }
  746. var childScripts = ctor && !ctor.prototype._noScript ? [] : null; // <script> nodes that are parent's children
  747. if(type){
  748. list.push({
  749. "type": type,
  750. node: node,
  751. scripts: childScripts,
  752. inherited: getEffective(current) // dir & lang settings for current node, explicit or inherited
  753. });
  754. }
  755. // Recurse, collecting <script type="dojo/..."> children, and also looking for
  756. // descendant nodes with dojoType specified (unless the widget has the stopParser flag).
  757. // When finished with children, go to my next sibling.
  758. node = firstChild;
  759. scripts = childScripts;
  760. scriptsOnly = ctor && ctor.prototype.stopParser && !(options.template);
  761. parent = current;
  762. }
  763. return list;
  764. };
  765. this.parse = /*====== dojo.parser.parse= ======*/ function(rootNode, options){
  766. // summary:
  767. // Scan the DOM for class instances, and instantiate them.
  768. //
  769. // description:
  770. // Search specified node (or root node) recursively for class instances,
  771. // and instantiate them. Searches for either data-dojo-type="Class" or
  772. // dojoType="Class" where "Class" is a a fully qualified class name,
  773. // like `dijit.form.Button`
  774. //
  775. // Using `data-dojo-type`:
  776. // Attributes using can be mixed into the parameters used to instantiate the
  777. // Class by using a `data-dojo-props` attribute on the node being converted.
  778. // `data-dojo-props` should be a string attribute to be converted from JSON.
  779. //
  780. // Using `dojoType`:
  781. // Attributes are read from the original domNode and converted to appropriate
  782. // types by looking up the Class prototype values. This is the default behavior
  783. // from Dojo 1.0 to Dojo 1.5. `dojoType` support is deprecated, and will
  784. // go away in Dojo 2.0.
  785. //
  786. // rootNode: DomNode?
  787. // A default starting root node from which to start the parsing. Can be
  788. // omitted, defaulting to the entire document. If omitted, the `options`
  789. // object can be passed in this place. If the `options` object has a
  790. // `rootNode` member, that is used.
  791. //
  792. // options: Object?
  793. // A hash of options.
  794. //
  795. // * noStart: Boolean?
  796. // when set will prevent the parser from calling .startup()
  797. // when locating the nodes.
  798. // * rootNode: DomNode?
  799. // identical to the function's `rootNode` argument, though
  800. // allowed to be passed in via this `options object.
  801. // * template: Boolean
  802. // If true, ignores ContentPane's stopParser flag and parses contents inside of
  803. // a ContentPane inside of a template. This allows dojoAttachPoint on widgets/nodes
  804. // nested inside the ContentPane to work.
  805. // * inherited: Object
  806. // Hash possibly containing dir and lang settings to be applied to
  807. // parsed widgets, unless there's another setting on a sub-node that overrides
  808. // * scope: String
  809. // Root for attribute names to search for. If scopeName is dojo,
  810. // will search for data-dojo-type (or dojoType). For backwards compatibility
  811. // reasons defaults to dojo._scopeName (which is "dojo" except when
  812. // multi-version support is used, when it will be something like dojo16, dojo20, etc.)
  813. // * propsThis: Object
  814. // If specified, "this" referenced from data-dojo-props will refer to propsThis.
  815. // Intended for use from the widgets-in-template feature of `dijit._WidgetsInTemplateMixin`
  816. //
  817. // example:
  818. // Parse all widgets on a page:
  819. // | dojo.parser.parse();
  820. //
  821. // example:
  822. // Parse all classes within the node with id="foo"
  823. // | dojo.parser.parse(dojo.byId('foo'));
  824. //
  825. // example:
  826. // Parse all classes in a page, but do not call .startup() on any
  827. // child
  828. // | dojo.parser.parse({ noStart: true })
  829. //
  830. // example:
  831. // Parse all classes in a node, but do not call .startup()
  832. // | dojo.parser.parse(someNode, { noStart:true });
  833. // | // or
  834. // | dojo.parser.parse({ noStart:true, rootNode: someNode });
  835. // determine the root node and options based on the passed arguments.
  836. var root;
  837. if(!options && rootNode && rootNode.rootNode){
  838. options = rootNode;
  839. root = options.rootNode;
  840. }else if(rootNode && dlang.isObject(rootNode) && !("nodeType" in rootNode)){
  841. options = rootNode;
  842. }else{
  843. root = rootNode;
  844. }
  845. root = root ? dhtml.byId(root) : dwindow.body();
  846. options = options || {};
  847. // List of all nodes on page w/dojoType specified
  848. var list = this.scan(root, options);
  849. // go build the object instances
  850. var mixin = options.template ? {template: true} : {};
  851. return this._instantiate(list, mixin, options); // Array
  852. };
  853. }();
  854. //Register the parser callback. It should be the first callback
  855. //after the a11y test.
  856. if(config.parseOnLoad){
  857. ready(100, dojo.parser, "parse");
  858. }
  859. return dojo.parser;
  860. });
  861. },
  862. 'dijit/_Container':function(){
  863. define("dijit/_Container", [
  864. "dojo/_base/array", // array.forEach array.indexOf
  865. "dojo/_base/declare", // declare
  866. "dojo/dom-construct", // domConstruct.place
  867. "./registry" // registry.byNode()
  868. ], function(array, declare, domConstruct, registry){
  869. // module:
  870. // dijit/_Container
  871. // summary:
  872. // Mixin for widgets that contain a set of widget children.
  873. return declare("dijit._Container", null, {
  874. // summary:
  875. // Mixin for widgets that contain a set of widget children.
  876. // description:
  877. // Use this mixin for widgets that needs to know about and
  878. // keep track of their widget children. Suitable for widgets like BorderContainer
  879. // and TabContainer which contain (only) a set of child widgets.
  880. //
  881. // It's not suitable for widgets like ContentPane
  882. // which contains mixed HTML (plain DOM nodes in addition to widgets),
  883. // and where contained widgets are not necessarily directly below
  884. // this.containerNode. In that case calls like addChild(node, position)
  885. // wouldn't make sense.
  886. buildRendering: function(){
  887. this.inherited(arguments);
  888. if(!this.containerNode){
  889. // all widgets with descendants must set containerNode
  890. this.containerNode = this.domNode;
  891. }
  892. },
  893. addChild: function(/*dijit._Widget*/ widget, /*int?*/ insertIndex){
  894. // summary:
  895. // Makes the given widget a child of this widget.
  896. // description:
  897. // Inserts specified child widget's dom node as a child of this widget's
  898. // container node, and possibly does other processing (such as layout).
  899. var refNode = this.containerNode;
  900. if(insertIndex && typeof insertIndex == "number"){
  901. var children = this.getChildren();
  902. if(children && children.length >= insertIndex){
  903. refNode = children[insertIndex-1].domNode;
  904. insertIndex = "after";
  905. }
  906. }
  907. domConstruct.place(widget.domNode, refNode, insertIndex);
  908. // If I've been started but the child widget hasn't been started,
  909. // start it now. Make sure to do this after widget has been
  910. // inserted into the DOM tree, so it can see that it's being controlled by me,
  911. // so it doesn't try to size itself.
  912. if(this._started && !widget._started){
  913. widget.startup();
  914. }
  915. },
  916. removeChild: function(/*Widget|int*/ widget){
  917. // summary:
  918. // Removes the passed widget instance from this widget but does
  919. // not destroy it. You can also pass in an integer indicating
  920. // the index within the container to remove
  921. if(typeof widget == "number"){
  922. widget = this.getChildren()[widget];
  923. }
  924. if(widget){
  925. var node = widget.domNode;
  926. if(node && node.parentNode){
  927. node.parentNode.removeChild(node); // detach but don't destroy
  928. }
  929. }
  930. },
  931. hasChildren: function(){
  932. // summary:
  933. // Returns true if widget has children, i.e. if this.containerNode contains something.
  934. return this.getChildren().length > 0; // Boolean
  935. },
  936. _getSiblingOfChild: function(/*dijit._Widget*/ child, /*int*/ dir){
  937. // summary:
  938. // Get the next or previous widget sibling of child
  939. // dir:
  940. // if 1, get the next sibling
  941. // if -1, get the previous sibling
  942. // tags:
  943. // private
  944. var node = child.domNode,
  945. which = (dir>0 ? "nextSibling" : "previousSibling");
  946. do{
  947. node = node[which];
  948. }while(node && (node.nodeType != 1 || !registry.byNode(node)));
  949. return node && registry.byNode(node); // dijit._Widget
  950. },
  951. getIndexOfChild: function(/*dijit._Widget*/ child){
  952. // summary:
  953. // Gets the index of the child in this container or -1 if not found
  954. return array.indexOf(this.getChildren(), child); // int
  955. }
  956. });
  957. });
  958. },
  959. 'dijit/_base/scroll':function(){
  960. define("dijit/_base/scroll", [
  961. "dojo/window", // windowUtils.scrollIntoView
  962. ".." // export symbol to dijit
  963. ], function(windowUtils, dijit){
  964. // module:
  965. // dijit/_base/scroll
  966. // summary:
  967. // Back compatibility module, new code should use windowUtils directly instead of using this module.
  968. dijit.scrollIntoView = function(/*DomNode*/ node, /*Object?*/ pos){
  969. // summary:
  970. // Scroll the passed node into view, if it is not already.
  971. // Deprecated, use `windowUtils.scrollIntoView` instead.
  972. windowUtils.scrollIntoView(node, pos);
  973. };
  974. });
  975. },
  976. 'dijit/layout/_LayoutWidget':function(){
  977. define("dijit/layout/_LayoutWidget", [
  978. "dojo/_base/lang", // lang.mixin
  979. "../_Widget",
  980. "../_Container",
  981. "../_Contained",
  982. "dojo/_base/declare", // declare
  983. "dojo/dom-class", // domClass.add domClass.remove
  984. "dojo/dom-geometry", // domGeometry.marginBox
  985. "dojo/dom-style", // domStyle.getComputedStyle
  986. "dojo/_base/sniff", // has("ie")
  987. "dojo/_base/window" // win.global
  988. ], function(lang, _Widget, _Container, _Contained,
  989. declare, domClass, domGeometry, domStyle, has, win){
  990. /*=====
  991. var _Widget = dijit._Widget;
  992. var _Container = dijit._Container;
  993. var _Contained = dijit._Contained;
  994. =====*/
  995. // module:
  996. // dijit/layout/_LayoutWidget
  997. // summary:
  998. // _LayoutWidget Base class for a _Container widget which is responsible for laying out its children.
  999. // Widgets which mixin this code must define layout() to manage placement and sizing of the children.
  1000. return declare("dijit.layout._LayoutWidget", [_Widget, _Container, _Contained], {
  1001. // summary:
  1002. // Base class for a _Container widget which is responsible for laying out its children.
  1003. // Widgets which mixin this code must define layout() to manage placement and sizing of the children.
  1004. // baseClass: [protected extension] String
  1005. // This class name is applied to the widget's domNode
  1006. // and also may be used to generate names for sub nodes,
  1007. // for example dijitTabContainer-content.
  1008. baseClass: "dijitLayoutContainer",
  1009. // isLayoutContainer: [protected] Boolean
  1010. // Indicates that this widget is going to call resize() on its
  1011. // children widgets, setting their size, when they become visible.
  1012. isLayoutContainer: true,
  1013. buildRendering: function(){
  1014. this.inherited(arguments);
  1015. domClass.add(this.domNode, "dijitContainer");
  1016. },
  1017. startup: function(){
  1018. // summary:
  1019. // Called after all the widgets have been instantiated and their
  1020. // dom nodes have been inserted somewhere under win.doc.body.
  1021. //
  1022. // Widgets should override this method to do any initialization
  1023. // dependent on other widgets existing, and then call
  1024. // this superclass method to finish things off.
  1025. //
  1026. // startup() in subclasses shouldn't do anything
  1027. // size related because the size of the widget hasn't been set yet.
  1028. if(this._started){ return; }
  1029. // Need to call inherited first - so that child widgets get started
  1030. // up correctly
  1031. this.inherited(arguments);
  1032. // If I am a not being controlled by a parent layout widget...
  1033. var parent = this.getParent && this.getParent();
  1034. if(!(parent && parent.isLayoutContainer)){
  1035. // Do recursive sizing and layout of all my descendants
  1036. // (passing in no argument to resize means that it has to glean the size itself)
  1037. this.resize();
  1038. // Since my parent isn't a layout container, and my style *may be* width=height=100%
  1039. // or something similar (either set directly or via a CSS class),
  1040. // monitor when viewport size changes so that I can re-layout.
  1041. this.connect(win.global, 'onresize', function(){
  1042. // Using function(){} closure to ensure no arguments passed to resize().
  1043. this.resize();
  1044. });
  1045. }
  1046. },
  1047. resize: function(changeSize, resultSize){
  1048. // summary:
  1049. // Call this to resize a widget, or after its size has changed.
  1050. // description:
  1051. // Change size mode:
  1052. // When changeSize is specified, changes the marginBox of this widget
  1053. // and forces it to relayout its contents accordingly.
  1054. // changeSize may specify height, width, or both.
  1055. //
  1056. // If resultSize is specified it indicates the size the widget will
  1057. // become after changeSize has been applied.
  1058. //
  1059. // Notification mode:
  1060. // When changeSize is null, indicates that the caller has already changed
  1061. // the size of the widget, or perhaps it changed because the browser
  1062. // window was resized. Tells widget to relayout its contents accordingly.
  1063. //
  1064. // If resultSize is also specified it indicates the size the widget has
  1065. // become.
  1066. //
  1067. // In either mode, this method also:
  1068. // 1. Sets this._borderBox and this._contentBox to the new size of
  1069. // the widget. Queries the current domNode size if necessary.
  1070. // 2. Calls layout() to resize contents (and maybe adjust child widgets).
  1071. //
  1072. // changeSize: Object?
  1073. // Sets the widget to this margin-box size and position.
  1074. // May include any/all of the following properties:
  1075. // | {w: int, h: int, l: int, t: int}
  1076. //
  1077. // resultSize: Object?
  1078. // The margin-box size of this widget after applying changeSize (if
  1079. // changeSize is specified). If caller knows this size and
  1080. // passes it in, we don't need to query the browser to get the size.
  1081. // | {w: int, h: int}
  1082. var node = this.domNode;
  1083. // set margin box size, unless it wasn't specified, in which case use current size
  1084. if(changeSize){
  1085. domGeometry.setMarginBox(node, changeSize);
  1086. }
  1087. // If either height or width wasn't specified by the user, then query node for it.
  1088. // But note that setting the margin box and then immediately querying dimensions may return
  1089. // inaccurate results, so try not to depend on it.
  1090. var mb = resultSize || {};
  1091. lang.mixin(mb, changeSize || {}); // changeSize overrides resultSize
  1092. if( !("h" in mb) || !("w" in mb) ){
  1093. mb = lang.mixin(domGeometry.getMarginBox(node), mb); // just use domGeometry.marginBox() to fill in missing values
  1094. }
  1095. // Compute and save the size of my border box and content box
  1096. // (w/out calling domGeometry.getContentBox() since that may fail if size was recently set)
  1097. var cs = domStyle.getComputedStyle(node);
  1098. var me = domGeometry.getMarginExtents(node, cs);
  1099. var be = domGeometry.getBorderExtents(node, cs);
  1100. var bb = (this._borderBox = {
  1101. w: mb.w - (me.w + be.w),
  1102. h: mb.h - (me.h + be.h)
  1103. });
  1104. var pe = domGeometry.getPadExtents(node, cs);
  1105. this._contentBox = {
  1106. l: domStyle.toPixelValue(node, cs.paddingLeft),
  1107. t: domStyle.toPixelValue(node, cs.paddingTop),
  1108. w: bb.w - pe.w,
  1109. h: bb.h - pe.h
  1110. };
  1111. // Callback for widget to adjust size of its children
  1112. this.layout();
  1113. },
  1114. layout: function(){
  1115. // summary:
  1116. // Widgets override this method to size and position their contents/children.
  1117. // When this is called this._contentBox is guaranteed to be set (see resize()).
  1118. //
  1119. // This is called after startup(), and also when the widget's size has been
  1120. // changed.
  1121. // tags:
  1122. // protected extension
  1123. },
  1124. _setupChild: function(/*dijit._Widget*/child){
  1125. // summary:
  1126. // Common setup for initial children and children which are added after startup
  1127. // tags:
  1128. // protected extension
  1129. var cls = this.baseClass + "-child "
  1130. + (child.baseClass ? this.baseClass + "-" + child.baseClass : "");
  1131. domClass.add(child.domNode, cls);
  1132. },
  1133. addChild: function(/*dijit._Widget*/ child, /*Integer?*/ insertIndex){
  1134. // Overrides _Container.addChild() to call _setupChild()
  1135. this.inherited(arguments);
  1136. if(this._started){
  1137. this._setupChild(child);
  1138. }
  1139. },
  1140. removeChild: function(/*dijit._Widget*/ child){
  1141. // Overrides _Container.removeChild() to remove class added by _setupChild()
  1142. var cls = this.baseClass + "-child"
  1143. + (child.baseClass ?
  1144. " " + this.baseClass + "-" + child.baseClass : "");
  1145. domClass.remove(child.domNode, cls);
  1146. this.inherited(arguments);
  1147. }
  1148. });
  1149. });
  1150. },
  1151. 'dijit/_base':function(){
  1152. define("dijit/_base", [
  1153. ".",
  1154. "./a11y", // used to be in dijit/_base/manager
  1155. "./WidgetSet", // used to be in dijit/_base/manager
  1156. "./_base/focus",
  1157. "./_base/manager",
  1158. "./_base/place",
  1159. "./_base/popup",
  1160. "./_base/scroll",
  1161. "./_base/sniff",
  1162. "./_base/typematic",
  1163. "./_base/wai",
  1164. "./_base/window"
  1165. ], function(dijit){
  1166. // module:
  1167. // dijit/_base
  1168. // summary:
  1169. // Includes all the modules in dijit/_base
  1170. return dijit._base;
  1171. });
  1172. },
  1173. 'dijit/form/_FormWidgetMixin':function(){
  1174. define("dijit/form/_FormWidgetMixin", [
  1175. "dojo/_base/array", // array.forEach
  1176. "dojo/_base/declare", // declare
  1177. "dojo/dom-attr", // domAttr.set
  1178. "dojo/dom-style", // domStyle.get
  1179. "dojo/_base/lang", // lang.hitch lang.isArray
  1180. "dojo/mouse", // mouse.isLeft
  1181. "dojo/_base/sniff", // has("webkit")
  1182. "dojo/_base/window", // win.body
  1183. "dojo/window", // winUtils.scrollIntoView
  1184. "../a11y" // a11y.hasDefaultTabStop
  1185. ], function(array, declare, domAttr, domStyle, lang, mouse, has, win, winUtils, a11y){
  1186. // module:
  1187. // dijit/form/_FormWidgetMixin
  1188. // summary:
  1189. // Mixin for widgets corresponding to native HTML elements such as <checkbox> or <button>,
  1190. // which can be children of a <form> node or a `dijit.form.Form` widget.
  1191. return declare("dijit.form._FormWidgetMixin", null, {
  1192. // summary:
  1193. // Mixin for widgets corresponding to native HTML elements such as <checkbox> or <button>,
  1194. // which can be children of a <form> node or a `dijit.form.Form` widget.
  1195. //
  1196. // description:
  1197. // Represents a single HTML element.
  1198. // All these widgets should have these attributes just like native HTML input elements.
  1199. // You can set them during widget construction or afterwards, via `dijit._Widget.attr`.
  1200. //
  1201. // They also share some common methods.
  1202. // name: [const] String
  1203. // Name used when submitting form; same as "name" attribute or plain HTML elements
  1204. name: "",
  1205. // alt: String
  1206. // Corresponds to the native HTML <input> element's attribute.
  1207. alt: "",
  1208. // value: String
  1209. // Corresponds to the native HTML <input> element's attribute.
  1210. value: "",
  1211. // type: [const] String
  1212. // Corresponds to the native HTML <input> element's attribute.
  1213. type: "text",
  1214. // tabIndex: Integer
  1215. // Order fields are traversed when user hits the tab key
  1216. tabIndex: "0",
  1217. _setTabIndexAttr: "focusNode", // force copy even when tabIndex default value, needed since Button is <span>
  1218. // disabled: Boolean
  1219. // Should this widget respond to user input?
  1220. // In markup, this is specified as "disabled='disabled'", or just "disabled".
  1221. disabled: false,
  1222. // intermediateChanges: Boolean
  1223. // Fires onChange for each value change or only on demand
  1224. intermediateChanges: false,
  1225. // scrollOnFocus: Boolean
  1226. // On focus, should this widget scroll into view?
  1227. scrollOnFocus: true,
  1228. // Override _WidgetBase mapping id to this.domNode, needs to be on focusNode so <label> etc.
  1229. // works with screen reader
  1230. _setIdAttr: "focusNode",
  1231. _setDisabledAttr: function(/*Boolean*/ value){
  1232. this._set("disabled", value);
  1233. domAttr.set(this.focusNode, 'disabled', value);
  1234. if(this.valueNode){
  1235. domAttr.set(this.valueNode, 'disabled', value);
  1236. }
  1237. this.focusNode.setAttribute("aria-disabled", value ? "true" : "false");
  1238. if(value){
  1239. // reset these, because after the domNode is disabled, we can no longer receive
  1240. // mouse related events, see #4200
  1241. this._set("hovering", false);
  1242. this._set("active", false);
  1243. // clear tab stop(s) on this widget's focusable node(s) (ComboBox has two focusable nodes)
  1244. var attachPointNames = "tabIndex" in this.attributeMap ? this.attributeMap.tabIndex :
  1245. ("_setTabIndexAttr" in this) ? this._setTabIndexAttr : "focusNode";
  1246. array.forEach(lang.isArray(attachPointNames) ? attachPointNames : [attachPointNames], function(attachPointName){
  1247. var node = this[attachPointName];
  1248. // complex code because tabIndex=-1 on a <div> doesn't work on FF
  1249. if(has("webkit") || a11y.hasDefaultTabStop(node)){ // see #11064 about webkit bug
  1250. node.setAttribute('tabIndex', "-1");
  1251. }else{
  1252. node.removeAttribute('tabIndex');
  1253. }
  1254. }, this);
  1255. }else{
  1256. if(this.tabIndex != ""){
  1257. this.set('tabIndex', this.tabIndex);
  1258. }
  1259. }
  1260. },
  1261. _onFocus: function(/*String*/ by){
  1262. // If user clicks on the widget, even if the mouse is released outside of it,
  1263. // this widget's focusNode should get focus (to mimic native browser hehavior).
  1264. // Browsers often need help to make sure the focus via mouse actually gets to the focusNode.
  1265. if(by == "mouse" && this.isFocusable()){
  1266. // IE exhibits strange scrolling behavior when refocusing a node so only do it when !focused.
  1267. var focusConnector = this.connect(this.focusNode, "onfocus", function(){
  1268. this.disconnect(mouseUpConnector);
  1269. this.disconnect(focusConnector);
  1270. });
  1271. // Set a global event to handle mouseup, so it fires properly
  1272. // even if the cursor leaves this.domNode before the mouse up event.
  1273. var mouseUpConnector = this.connect(win.body(), "onmouseup", function(){
  1274. this.disconnect(mouseUpConnector);
  1275. this.disconnect(focusConnector);
  1276. // if here, then the mousedown did not focus the focusNode as the default action
  1277. if(this.focused){
  1278. this.focus();
  1279. }
  1280. });
  1281. }
  1282. if(this.scrollOnFocus){
  1283. this.defer(function(){ winUtils.scrollIntoView(this.domNode); }); // without defer, the input caret position can change on mouse click
  1284. }
  1285. this.inherited(arguments);
  1286. },
  1287. isFocusable: function(){
  1288. // summary:
  1289. // Tells if this widget is focusable or not. Used internally by dijit.
  1290. // tags:
  1291. // protected
  1292. return !this.disabled && this.focusNode && (domStyle.get(this.domNode, "display") != "none");
  1293. },
  1294. focus: function(){
  1295. // summary:
  1296. // Put focus on this widget
  1297. if(!this.disabled && this.focusNode.focus){
  1298. try{ this.focusNode.focus(); }catch(e){}/*squelch errors from hidden nodes*/
  1299. }
  1300. },
  1301. compare: function(/*anything*/ val1, /*anything*/ val2){
  1302. // summary:
  1303. // Compare 2 values (as returned by get('value') for this widget).
  1304. // tags:
  1305. // protected
  1306. if(typeof val1 == "number" && typeof val2 == "number"){
  1307. return (isNaN(val1) && isNaN(val2)) ? 0 : val1 - val2;
  1308. }else if(val1 > val2){
  1309. return 1;
  1310. }else if(val1 < val2){
  1311. return -1;
  1312. }else{
  1313. return 0;
  1314. }
  1315. },
  1316. onChange: function(/*===== newValue =====*/){
  1317. // summary:
  1318. // Callback when this widget's value is changed.
  1319. // tags:
  1320. // callback
  1321. },
  1322. // _onChangeActive: [private] Boolean
  1323. // Indicates that changes to the value should call onChange() callback.
  1324. // This is false during widget initialization, to avoid calling onChange()
  1325. // when the initial value is set.
  1326. _onChangeActive: false,
  1327. _handleOnChange: function(/*anything*/ newValue, /*Boolean?*/ priorityChange){
  1328. // summary:
  1329. // Called when the value of the widget is set. Calls onChange() if appropriate
  1330. // newValue:
  1331. // the new value
  1332. // priorityChange:
  1333. // For a slider, for example, dragging the slider is priorityChange==false,
  1334. // but on mouse up, it's priorityChange==true. If intermediateChanges==false,
  1335. // onChange is only called form priorityChange=true events.
  1336. // tags:
  1337. // private
  1338. if(this._lastValueReported == undefined && (priorityChange === null || !this._onChangeActive)){
  1339. // this block executes not for a change, but during initialization,
  1340. // and is used to store away the original value (or for ToggleButton, the original checked state)
  1341. this._resetValue = this._lastValueReported = newValue;
  1342. }
  1343. this._pendingOnChange = this._pendingOnChange
  1344. || (typeof newValue != typeof this._lastValueReported)
  1345. || (this.compare(newValue, this._lastValueReported) != 0);
  1346. if((this.intermediateChanges || priorityChange || priorityChange === undefined) && this._pendingOnChange){
  1347. this._lastValueReported = newValue;
  1348. this._pendingOnChange = false;
  1349. if(this._onChangeActive){
  1350. if(this._onChangeHandle){
  1351. this._onChangeHandle.remove();
  1352. }
  1353. // defer allows hidden value processing to run and
  1354. // also the onChange handler can safely adjust focus, etc
  1355. this._onChangeHandle = this.defer(
  1356. function(){
  1357. this._onChangeHandle = null;
  1358. this.onChange(newValue);
  1359. }); // try to collapse multiple onChange's fired faster than can be processed
  1360. }
  1361. }
  1362. },
  1363. create: function(){
  1364. // Overrides _Widget.create()
  1365. this.inherited(arguments);
  1366. this._onChangeActive = true;
  1367. },
  1368. destroy: function(){
  1369. if(this._onChangeHandle){ // destroy called before last onChange has fired
  1370. this._onChangeHandle.remove();
  1371. this.onChange(this._lastValueReported);
  1372. }
  1373. this.inherited(arguments);
  1374. }
  1375. });
  1376. });
  1377. },
  1378. 'dijit/BackgroundIframe':function(){
  1379. define("dijit/BackgroundIframe", [
  1380. "require", // require.toUrl
  1381. ".", // to export dijit.BackgroundIframe
  1382. "dojo/_base/config",
  1383. "dojo/dom-construct", // domConstruct.create
  1384. "dojo/dom-style", // domStyle.set
  1385. "dojo/_base/lang", // lang.extend lang.hitch
  1386. "dojo/on",
  1387. "dojo/_base/sniff", // has("ie"), has("mozilla"), has("quirks")
  1388. "dojo/_base/window" // win.doc.createElement
  1389. ], function(require, dijit, config, domConstruct, domStyle, lang, on, has, win){
  1390. // module:
  1391. // dijit/BackgroundIFrame
  1392. // Flag for whether to create background iframe behind popups like Menus and Dialog.
  1393. // A background iframe is useful to prevent problems with popups appearing behind applets/pdf files,
  1394. // and is also useful on older versions of IE (IE6 and IE7) to prevent the "bleed through select" problem.
  1395. // TODO: For 2.0, make this false by default. Also, possibly move definition to has.js so that this module can be
  1396. // conditionally required via dojo/has!bgIfame?dijit/BackgroundIframe
  1397. has.add("bgIframe", has("ie") || has("mozilla"));
  1398. // summary:
  1399. // new dijit.BackgroundIframe(node)
  1400. // Makes a background iframe as a child of node, that fills
  1401. // area (and position) of node
  1402. // TODO: remove _frames, it isn't being used much, since popups never release their
  1403. // iframes (see [22236])
  1404. var _frames = new function(){
  1405. // summary:
  1406. // cache of iframes
  1407. var queue = [];
  1408. this.pop = function(){
  1409. var iframe;
  1410. if(queue.length){
  1411. iframe = queue.pop();
  1412. iframe.style.display="";
  1413. }else{
  1414. if(has("ie") < 9){
  1415. var burl = config["dojoBlankHtmlUrl"] || require.toUrl("dojo/resources/blank.html") || "javascript:\"\"";
  1416. var html="<iframe src='" + burl + "' role='presentation'"
  1417. + " style='position: absolute; left: 0px; top: 0px;"
  1418. + "z-index: -1; filter:Alpha(Opacity=\"0\");'>";
  1419. iframe = win.doc.createElement(html);
  1420. }else{
  1421. iframe = domConstruct.create("iframe");
  1422. iframe.src = 'javascript:""';
  1423. iframe.className = "dijitBackgroundIframe";
  1424. iframe.setAttribute("role", "presentation");
  1425. domStyle.set(iframe, "opacity", 0.1);
  1426. }
  1427. iframe.tabIndex = -1; // Magic to prevent iframe from getting focus on tab keypress - as style didn't work.
  1428. }
  1429. return iframe;
  1430. };
  1431. this.push = function(iframe){
  1432. iframe.style.display="none";
  1433. queue.push(iframe);
  1434. }
  1435. }();
  1436. dijit.BackgroundIframe = function(/*DomNode*/ node){
  1437. // summary:
  1438. // For IE/FF z-index schenanigans. id attribute is required.
  1439. //
  1440. // description:
  1441. // new dijit.BackgroundIframe(node)
  1442. // Makes a background iframe as a child of node, that fills
  1443. // area (and position) of node
  1444. if(!node.id){ throw new Error("no id"); }
  1445. if(has("bgIframe")){
  1446. var iframe = (this.iframe = _frames.pop());
  1447. node.appendChild(iframe);
  1448. if(has("ie")<7 || has("quirks")){
  1449. this.resize(node);
  1450. this._conn = on(node, 'resize', lang.hitch(this, function(){
  1451. this.resize(node);
  1452. }));
  1453. }else{
  1454. domStyle.set(iframe, {
  1455. width: '100%',
  1456. height: '100%'
  1457. });
  1458. }
  1459. }
  1460. };
  1461. lang.extend(dijit.BackgroundIframe, {
  1462. resize: function(node){
  1463. // summary:
  1464. // Resize the iframe so it's the same size as node.
  1465. // Needed on IE6 and IE/quirks because height:100% doesn't work right.
  1466. if(this.iframe){
  1467. domStyle.set(this.iframe, {
  1468. width: node.offsetWidth + 'px',
  1469. height: node.offsetHeight + 'px'
  1470. });
  1471. }
  1472. },
  1473. destroy: function(){
  1474. // summary:
  1475. // destroy the iframe
  1476. if(this._conn){
  1477. this._conn.remove();
  1478. this._conn = null;
  1479. }
  1480. if(this.iframe){
  1481. _frames.push(this.iframe);
  1482. delete this.iframe;
  1483. }
  1484. }
  1485. });
  1486. return dijit.BackgroundIframe;
  1487. });
  1488. },
  1489. 'dijit/form/_FormValueMixin':function(){
  1490. define("dijit/form/_FormValueMixin", [
  1491. "dojo/_base/declare", // declare
  1492. "dojo/dom-attr", // domAttr.set
  1493. "dojo/keys", // keys.ESCAPE
  1494. "dojo/_base/sniff", // has("ie"), has("quirks")
  1495. "./_FormWidgetMixin"
  1496. ], function(declare, domAttr, keys, has, _FormWidgetMixin){
  1497. /*=====
  1498. var _FormWidgetMixin = dijit.form._FormWidgetMixin;
  1499. =====*/
  1500. // module:
  1501. // dijit/form/_FormValueMixin
  1502. // summary:
  1503. // Mixin for widgets corresponding to native HTML elements such as <input> or <select> that have user changeable values.
  1504. return declare("dijit.form._FormValueMixin", _FormWidgetMixin, {
  1505. // summary:
  1506. // Mixin for widgets corresponding to native HTML elements such as <input> or <select> that have user changeable values.
  1507. // description:
  1508. // Each _FormValueMixin represents a single input value, and has a (possibly hidden) <input> element,
  1509. // to which it serializes it's input value, so that form submission (either normal submission or via FormBind?)
  1510. // works as expected.
  1511. // readOnly: Boolean
  1512. // Should this widget respond to user input?
  1513. // In markup, this is specified as "readOnly".
  1514. // Similar to disabled except readOnly form values are submitted.
  1515. readOnly: false,
  1516. _setReadOnlyAttr: function(/*Boolean*/ value){
  1517. domAttr.set(this.focusNode, 'readOnly', value);
  1518. this._set("readOnly", value);
  1519. },
  1520. postCreate: function(){
  1521. this.inherited(arguments);
  1522. if(has("ie")){ // IE won't stop the event with keypress
  1523. this.connect(this.focusNode || this.domNode, "onkeydown", this._onKeyDown);
  1524. }
  1525. // Update our reset value if it hasn't yet been set (because this.set()
  1526. // is only called when there *is* a value)
  1527. if(this._resetValue === undefined){
  1528. this._lastValueReported = this._resetValue = this.value;
  1529. }
  1530. },
  1531. _setValueAttr: function(/*anything*/ newValue, /*Boolean?*/ priorityChange){
  1532. // summary:
  1533. // Hook so set('value', value) works.
  1534. // description:
  1535. // Sets the value of the widget.
  1536. // If the value has changed, then fire onChange event, unless priorityChange
  1537. // is specified as null (or false?)
  1538. this._handleOnChange(newValue, priorityChange);
  1539. },
  1540. _handleOnChange: function(/*anything*/ newValue, /*Boolean?*/ priorityChange){
  1541. // summary:
  1542. // Called when the value of the widget has changed. Saves the new value in this.value,
  1543. // and calls onChange() if appropriate. See _FormWidget._handleOnChange() for details.
  1544. this._set("value", newValue);
  1545. this.inherited(arguments);
  1546. },
  1547. undo: function(){
  1548. // summary:
  1549. // Restore the value to the last value passed to onChange
  1550. this._setValueAttr(this._lastValueReported, false);
  1551. },
  1552. reset: function(){
  1553. // summary:
  1554. // Reset the widget's value to what it was at initialization time
  1555. this._hasBeenBlurred = false;
  1556. this._setValueAttr(this._resetValue, true);
  1557. },
  1558. _onKeyDown: function(e){
  1559. if(e.keyCode == keys.ESCAPE && !(e.ctrlKey || e.altKey || e.metaKey)){
  1560. var te;
  1561. if(has("ie") < 9 || (has("ie") && has("quirks"))){
  1562. e.preventDefault(); // default behavior needs to be stopped here since keypress is too late
  1563. te = document.createEventObject();
  1564. te.keyCode = keys.ESCAPE;
  1565. te.shiftKey = e.shiftKey;
  1566. e.srcElement.fireEvent('onkeypress', te);
  1567. }
  1568. }
  1569. }
  1570. });
  1571. });
  1572. },
  1573. 'dojo/Stateful':function(){
  1574. define(["./_base/declare", "./_base/lang", "./_base/array"], function(declare, lang, array) {
  1575. // module:
  1576. // dojo/Stateful
  1577. // summary:
  1578. // TODOC
  1579. return declare("dojo.Stateful", null, {
  1580. // summary:
  1581. // Base class for objects that provide named properties with optional getter/setter
  1582. // control and the ability to watch for property changes
  1583. // example:
  1584. // | var obj = new dojo.Stateful();
  1585. // | obj.watch("foo", function(){
  1586. // | console.log("foo changed to " + this.get("foo"));
  1587. // | });
  1588. // | obj.set("foo","bar");
  1589. postscript: function(mixin){
  1590. if(mixin){
  1591. lang.mixin(this, mixin);
  1592. }
  1593. },
  1594. get: function(/*String*/name){
  1595. // summary:
  1596. // Get a property on a Stateful instance.
  1597. // name:
  1598. // The property to get.
  1599. // returns:
  1600. // The property value on this Stateful instance.
  1601. // description:
  1602. // Get a named property on a Stateful object. The property may
  1603. // potentially be retrieved via a getter method in subclasses. In the base class
  1604. // this just retrieves the object's property.
  1605. // For example:
  1606. // | stateful = new dojo.Stateful({foo: 3});
  1607. // | stateful.get("foo") // returns 3
  1608. // | stateful.foo // returns 3
  1609. return this[name]; //Any
  1610. },
  1611. set: function(/*String*/name, /*Object*/value){
  1612. // summary:
  1613. // Set a property on a Stateful instance
  1614. // name:
  1615. // The property to set.
  1616. // value:
  1617. // The value to set in the property.
  1618. // returns:
  1619. // The function returns this dojo.Stateful instance.
  1620. // description:
  1621. // Sets named properties on a stateful object and notifies any watchers of
  1622. // the property. A programmatic setter may be defined in subclasses.
  1623. // For example:
  1624. // | stateful = new dojo.Stateful();
  1625. // | stateful.watch(function(name, oldValue, value){
  1626. // | // this will be called on the set below
  1627. // | }
  1628. // | stateful.set(foo, 5);
  1629. //
  1630. // set() may also be called with a hash of name/value pairs, ex:
  1631. // | myObj.set({
  1632. // | foo: "Howdy",
  1633. // | bar: 3
  1634. // | })
  1635. // This is equivalent to calling set(foo, "Howdy") and set(bar, 3)
  1636. if(typeof name === "object"){
  1637. for(var x in name){
  1638. if(name.hasOwnProperty(x) && x !="_watchCallbacks"){
  1639. this.set(x, name[x]);
  1640. }
  1641. }
  1642. return this;
  1643. }
  1644. var oldValue = this[name];
  1645. this[name] = value;
  1646. if(this._watchCallbacks){
  1647. this._watchCallbacks(name, oldValue, value);
  1648. }
  1649. return this; //dojo.Stateful
  1650. },
  1651. watch: function(/*String?*/name, /*Function*/callback){
  1652. // summary:
  1653. // Watches a property for changes
  1654. // name:
  1655. // Indicates the property to watch. This is optional (the callback may be the
  1656. // only parameter), and if omitted, all the properties will be watched
  1657. // returns:
  1658. // An object handle for the watch. The unwatch method of this object
  1659. // can be used to discontinue watching this property:
  1660. // | var watchHandle = obj.watch("foo", callback);
  1661. // | watchHandle.unwatch(); // callback won't be called now
  1662. // callback:
  1663. // The function to execute when the property changes. This will be called after
  1664. // the property has been changed. The callback will be called with the |this|
  1665. // set to the instance, the first argument as the name of the property, the
  1666. // second argument as the old value and the third argument as the new value.
  1667. var callbacks = this._watchCallbacks;
  1668. if(!callbacks){
  1669. var self = this;
  1670. callbacks = this._watchCallbacks = function(name, oldValue, value, ignoreCatchall){
  1671. var notify = function(propertyCallbacks){
  1672. if(propertyCallbacks){
  1673. propertyCallbacks = propertyCallbacks.slice();
  1674. for(var i = 0, l = propertyCallbacks.length; i < l; i++){
  1675. propertyCallbacks[i].call(self, name, oldValue, value);
  1676. }
  1677. }
  1678. };
  1679. notify(callbacks['_' + name]);
  1680. if(!ignoreCatchall){
  1681. notify(callbacks["*"]); // the catch-all
  1682. }
  1683. }; // we use a function instead of an object so it will be ignored by JSON conversion
  1684. }
  1685. if(!callback && typeof name === "function"){
  1686. callback = name;
  1687. name = "*";
  1688. }else{
  1689. // prepend with dash to prevent name conflicts with function (like "name" property)
  1690. name = '_' + name;
  1691. }
  1692. var propertyCallbacks = callbacks[name];
  1693. if(typeof propertyCallbacks !== "object"){
  1694. propertyCallbacks = callbacks[name] = [];
  1695. }
  1696. propertyCallbacks.push(callback);
  1697. return {
  1698. unwatch: function(){
  1699. propertyCallbacks.splice(array.indexOf(propertyCallbacks, callback), 1);
  1700. }
  1701. }; //Object
  1702. }
  1703. });
  1704. });
  1705. },
  1706. 'dojo/touch':function(){
  1707. define(["./_base/kernel", "./aspect", "./dom", "./on", "./has", "./mouse", "./domReady", "./_base/window"],
  1708. function(dojo, aspect, dom, on, has, mouse, domReady, win){
  1709. // module:
  1710. // dojo/touch
  1711. var hasTouch = has("touch");
  1712. // TODO: get iOS version from dojo/sniff after #15827 is fixed
  1713. var ios4 = false;
  1714. if(has("ios")){
  1715. var ua = navigator.userAgent;
  1716. var v = ua.match(/OS ([\d_]+)/) ? RegExp.$1 : "1";
  1717. var os = parseFloat(v.replace(/_/, '.').replace(/_/g, ''));
  1718. ios4 = os < 5;
  1719. }
  1720. // Time of most recent touchstart or touchmove event
  1721. var lastTouch;
  1722. function dualEvent(mouseType, touchType){
  1723. // Returns synthetic event that listens for both the specified mouse event and specified touch event.
  1724. // But ignore fake mouse events that were generated due to the user touching the screen.
  1725. if(hasTouch){
  1726. return function(node, listener){
  1727. var handle1 = on(node, touchType, listener),
  1728. handle2 = on(node, mouseType, function(evt){
  1729. if(!lastTouch || (new Date()).getTime() > lastTouch + 1000){
  1730. listener.call(this, evt);
  1731. }
  1732. });
  1733. return {
  1734. remove: function(){
  1735. handle1.remove();
  1736. handle2.remove();
  1737. }
  1738. };
  1739. };
  1740. }else{
  1741. // Avoid creating listeners for touch events on performance sensitive older browsers like IE6
  1742. return function(node, listener){
  1743. return on(node, mouseType, listener);
  1744. }
  1745. }
  1746. }
  1747. var touchmove, hoveredNode;
  1748. if(hasTouch){
  1749. domReady(function(){
  1750. // Keep track of currently hovered node
  1751. hoveredNode = win.body(); // currently hovered node
  1752. win.doc.addEventListener("touchstart", function(evt){
  1753. lastTouch = (new Date()).getTime();
  1754. // Precede touchstart event with touch.over event. DnD depends on this.
  1755. // Use addEventListener(cb, true) to run cb before any touchstart handlers on node run,
  1756. // and to ensure this code runs even if the listener on the node does event.stop().
  1757. var oldNode = hoveredNode;
  1758. hoveredNode = evt.target;
  1759. on.emit(oldNode, "dojotouchout", {
  1760. target: oldNode,
  1761. relatedTarget: hoveredNode,
  1762. bubbles: true
  1763. });
  1764. on.emit(hoveredNode, "dojotouchover", {
  1765. target: hoveredNode,
  1766. relatedTarget: oldNode,
  1767. bubbles: true
  1768. });
  1769. }, true);
  1770. // Fire synthetic touchover and touchout events on nodes since the browser won't do it natively.
  1771. on(win.doc, "touchmove", function(evt){
  1772. lastTouch = (new Date()).getTime();
  1773. var newNode = win.doc.elementFromPoint(
  1774. evt.pageX - (ios4 ? 0 : win.global.pageXOffset), // iOS 4 expects page coords
  1775. evt.pageY - (ios4 ? 0 : win.global.pageYOffset)
  1776. );
  1777. if(newNode && hoveredNode !== newNode){
  1778. // touch out on the old node
  1779. on.emit(hoveredNode, "dojotouchout", {
  1780. target: hoveredNode,
  1781. relatedTarget: newNode,
  1782. bubbles: true
  1783. });
  1784. // touchover on the new node
  1785. on.emit(newNode, "dojotouchover", {
  1786. target: newNode,
  1787. relatedTarget: hoveredNode,
  1788. bubbles: true
  1789. });
  1790. hoveredNode = newNode;
  1791. }
  1792. });
  1793. });
  1794. // Define synthetic touch.move event that unlike the native touchmove, fires for the node the finger is
  1795. // currently dragging over rather than the node where the touch started.
  1796. touchmove = function(node, listener){
  1797. return on(win.doc, "touchmove", function(evt){
  1798. if(node === win.doc || dom.isDescendant(hoveredNode, node)){
  1799. evt.target = hoveredNode;
  1800. listener.call(this, evt);
  1801. }
  1802. });
  1803. };
  1804. }
  1805. //device neutral events - touch.press|move|release|cancel/over/out
  1806. var touch = {
  1807. press: dualEvent("mousedown", "touchstart"),
  1808. move: dualEvent("mousemove", touchmove),
  1809. release: dualEvent("mouseup", "touchend"),
  1810. cancel: dualEvent(mouse.leave, "touchcancel"),
  1811. over: dualEvent("mouseover", "dojotouchover"),
  1812. out: dualEvent("mouseout", "dojotouchout"),
  1813. enter: mouse._eventHandler(dualEvent("mouseover","dojotouchover")),
  1814. leave: mouse._eventHandler(dualEvent("mouseout", "dojotouchout"))
  1815. };
  1816. /*=====
  1817. touch = {
  1818. // summary:
  1819. // This module provides unified touch event handlers by exporting
  1820. // press, move, release and cancel which can also run well on desktop.
  1821. // Based on http://dvcs.w3.org/hg/webevents/raw-file/tip/touchevents.html
  1822. //
  1823. // example:
  1824. // Used with dojo.on
  1825. // | define(["dojo/on", "dojo/touch"], function(on, touch){
  1826. // | on(node, touch.press, function(e){});
  1827. // | on(node, touch.move, function(e){});
  1828. // | on(node, touch.release, function(e){});
  1829. // | on(node, touch.cancel, function(e){});
  1830. // example:
  1831. // Used with touch.* directly
  1832. // | touch.press(node, function(e){});
  1833. // | touch.move(node, function(e){});
  1834. // | touch.release(node, function(e){});
  1835. // | touch.cancel(node, function(e){});
  1836. press: function(node, listener){
  1837. // summary:
  1838. // Register a listener to 'touchstart'|'mousedown' for the given node
  1839. // node: Dom
  1840. // Target node to listen to
  1841. // listener: Function
  1842. // Callback function
  1843. // returns:
  1844. // A handle which will be used to remove the listener by handle.remove()
  1845. },
  1846. move: function(node, listener){
  1847. // summary:
  1848. // Register a listener to 'touchmove'|'mousemove' for the given node
  1849. // node: Dom
  1850. // Target node to listen to
  1851. // listener: Function
  1852. // Callback function
  1853. // returns:
  1854. // A handle which will be used to remove the listener by handle.remove()
  1855. },
  1856. release: function(node, listener){
  1857. // summary:
  1858. // Register a listener to 'touchend'|'mouseup' for the given node
  1859. // node: Dom
  1860. // Target node to listen to
  1861. // listener: Function
  1862. // Callback function
  1863. // returns:
  1864. // A handle which will be used to remove the listener by handle.remove()
  1865. },
  1866. cancel: function(node, listener){
  1867. // summary:
  1868. // Register a listener to 'touchcancel'|'mouseleave' for the given node
  1869. // node: Dom
  1870. // Target node to listen to
  1871. // listener: Function
  1872. // Callback function
  1873. // returns:
  1874. // A handle which will be used to remove the listener by handle.remove()
  1875. },
  1876. over: function(node, listener){
  1877. // summary:
  1878. // Register a listener to 'mouseover' or touch equivalent for the given node
  1879. // node: Dom
  1880. // Target node to listen to
  1881. // listener: Function
  1882. // Callback function
  1883. // returns:
  1884. // A handle which will be used to remove the listener by handle.remove()
  1885. },
  1886. out: function(node, listener){
  1887. // summary:
  1888. // Register a listener to 'mouseout' or touch equivalent for the given node
  1889. // node: Dom
  1890. // Target node to listen to
  1891. // listener: Function
  1892. // Callback function
  1893. // returns:
  1894. // A handle which will be used to remove the listener by handle.remove()
  1895. },
  1896. enter: function(node, listener){
  1897. // summary:
  1898. // Register a listener to mouse.enter or touch equivalent for the given node
  1899. // node: Dom
  1900. // Target node to listen to
  1901. // listener: Function
  1902. // Callback function
  1903. // returns:
  1904. // A handle which will be used to remove the listener by handle.remove()
  1905. },
  1906. leave: function(node, listener){
  1907. // summary:
  1908. // Register a listener to mouse.leave or touch equivalent for the given node
  1909. // node: Dom
  1910. // Target node to listen to
  1911. // listener: Function
  1912. // Callback function
  1913. // returns:
  1914. // A handle which will be used to remove the listener by handle.remove()
  1915. }
  1916. };
  1917. =====*/
  1918. 1 && (dojo.touch = touch);
  1919. return touch;
  1920. });
  1921. },
  1922. 'dijit/_CssStateMixin':function(){
  1923. define("dijit/_CssStateMixin", [
  1924. "dojo/touch",
  1925. "dojo/_base/array", // array.forEach array.map
  1926. "dojo/_base/declare", // declare
  1927. "dojo/dom-class", // domClass.toggle
  1928. "dojo/_base/lang", // lang.hitch
  1929. "dojo/_base/window" // win.body
  1930. ], function(touch, array, declare, domClass, lang, win){
  1931. // module:
  1932. // dijit/_CssStateMixin
  1933. // summary:
  1934. // Mixin for widgets to set CSS classes on the widget DOM nodes depending on hover/mouse press/focus
  1935. // state changes, and also higher-level state changes such becoming disabled or selected.
  1936. return declare("dijit._CssStateMixin", [], {
  1937. // summary:
  1938. // Mixin for widgets to set CSS classes on the widget DOM nodes depending on hover/mouse press/focus
  1939. // state changes, and also higher-level state changes such becoming disabled or selected.
  1940. //
  1941. // description:
  1942. // By mixing this class into your widget, and setting the this.baseClass attribute, it will automatically
  1943. // maintain CSS classes on the widget root node (this.domNode) depending on hover,
  1944. // active, focus, etc. state. Ex: with a baseClass of dijitButton, it will apply the classes
  1945. // dijitButtonHovered and dijitButtonActive, as the user moves the mouse over the widget and clicks it.
  1946. //
  1947. // It also sets CSS like dijitButtonDisabled based on widget semantic state.
  1948. //
  1949. // By setting the cssStateNodes attribute, a widget can also track events on subnodes (like buttons
  1950. // within the widget).
  1951. // cssStateNodes: [protected] Object
  1952. // List of sub-nodes within the widget that need CSS classes applied on mouse hover/press and focus
  1953. //.
  1954. // Each entry in the hash is a an attachpoint names (like "upArrowButton") mapped to a CSS class names
  1955. // (like "dijitUpArrowButton"). Example:
  1956. // | {
  1957. // | "upArrowButton": "dijitUpArrowButton",
  1958. // | "downArrowButton": "dijitDownArrowButton"
  1959. // | }
  1960. // The above will set the CSS class dijitUpArrowButton to the this.upArrowButton DOMNode when it
  1961. // is hovered, etc.
  1962. cssStateNodes: {},
  1963. // hovering: [readonly] Boolean
  1964. // True if cursor is over this widget
  1965. hovering: false,
  1966. // active: [readonly] Boolean
  1967. // True if mouse was pressed while over this widget, and hasn't been released yet
  1968. active: false,
  1969. _applyAttributes: function(){
  1970. // This code would typically be in postCreate(), but putting in _applyAttributes() for
  1971. // performance: so the class changes happen before DOM is inserted into the document.
  1972. // Change back to postCreate() in 2.0. See #11635.
  1973. this.inherited(arguments);
  1974. // Automatically monitor mouse events (essentially :hover and :active) on this.domNode
  1975. array.forEach(["onmouseenter", "onmouseleave", touch.press], function(e){
  1976. this.connect(this.domNode, e, "_cssMouseEvent");
  1977. }, this);
  1978. // Monitoring changes to disabled, readonly, etc. state, and update CSS class of root node
  1979. array.forEach(["disabled", "readOnly", "checked", "selected", "focused", "state", "hovering", "active"], function(attr){
  1980. this.watch(attr, lang.hitch(this, "_setStateClass"));
  1981. }, this);
  1982. // Events on sub nodes within the widget
  1983. for(var ap in this.cssStateNodes){
  1984. this._trackMouseState(this[ap], this.cssStateNodes[ap]);
  1985. }
  1986. // Set state initially; there's probably no hover/active/focus state but widget might be
  1987. // disabled/readonly/checked/selected so we want to set CSS classes for those conditions.
  1988. this._setStateClass();
  1989. },
  1990. _cssMouseEvent: function(/*Event*/ event){
  1991. // summary:
  1992. // Sets hovering and active properties depending on mouse state,
  1993. // which triggers _setStateClass() to set appropriate CSS classes for this.domNode.
  1994. if(!this.disabled){
  1995. switch(event.type){
  1996. case "mouseenter":
  1997. case "mouseover": // generated on non-IE browsers even though we connected to mouseenter
  1998. this._set("hovering", true);
  1999. this._set("active", this._mouseDown);
  2000. break;
  2001. case "mouseleave":
  2002. case "mouseout": // generated on non-IE browsers even though we connected to mouseleave
  2003. this._set("hovering", false);
  2004. this._set("active", false);
  2005. break;
  2006. case "mousedown":
  2007. case "touchpress":
  2008. this._set("active", true);
  2009. this._mouseDown = true;
  2010. // Set a global event to handle mouseup, so it fires properly
  2011. // even if the cursor leaves this.domNode before the mouse up event.
  2012. // Alternately could set active=false on mouseout.
  2013. var mouseUpConnector = this.connect(win.body(), touch.release, function(){
  2014. this._mouseDown = false;
  2015. this._set("active", false);
  2016. this.disconnect(mouseUpConnector);
  2017. });
  2018. break;
  2019. }
  2020. }
  2021. },
  2022. _setStateClass: function(){
  2023. // summary:
  2024. // Update the visual state of the widget by setting the css classes on this.domNode
  2025. // (or this.stateNode if defined) by combining this.baseClass with
  2026. // various suffixes that represent the current widget state(s).
  2027. //
  2028. // description:
  2029. // In the case where a widget has multiple
  2030. // states, it sets the class based on all possible
  2031. // combinations. For example, an invalid form widget that is being hovered
  2032. // will be "dijitInput dijitInputInvalid dijitInputHover dijitInputInvalidHover".
  2033. //
  2034. // The widget may have one or more of the following states, determined
  2035. // by this.state, this.checked, this.valid, and this.selected:
  2036. // - Error - ValidationTextBox sets this.state to "Error" if the current input value is invalid
  2037. // - Incomplete - ValidationTextBox sets this.state to "Incomplete" if the current input value is not finished yet
  2038. // - Checked - ex: a checkmark or a ToggleButton in a checked state, will have this.checked==true
  2039. // - Selected - ex: currently selected tab will have this.selected==true
  2040. //
  2041. // In addition, it may have one or more of the following states,
  2042. // based on this.disabled and flags set in _onMouse (this.active, this.hovering) and from focus manager (this.focused):
  2043. // - Disabled - if the widget is disabled
  2044. // - Active - if the mouse (or space/enter key?) is being pressed down
  2045. // - Focused - if the widget has focus
  2046. // - Hover - if the mouse is over the widget
  2047. // Compute new set of classes
  2048. var newStateClasses = this.baseClass.split(" ");
  2049. function multiply(modifier){
  2050. newStateClasses = newStateClasses.concat(array.map(newStateClasses, function(c){ return c+modifier; }), "dijit"+modifier);
  2051. }
  2052. if(!this.isLeftToRight()){
  2053. // For RTL mode we need to set an addition class like dijitTextBoxRtl.
  2054. multiply("Rtl");
  2055. }
  2056. var checkedState = this.checked == "mixed" ? "Mixed" : (this.checked ? "Checked" : "");
  2057. if(this.checked){
  2058. multiply(checkedState);
  2059. }
  2060. if(this.state){
  2061. multiply(this.state);
  2062. }
  2063. if(this.selected){
  2064. multiply("Selected");
  2065. }
  2066. if(this.disabled){
  2067. multiply("Disabled");
  2068. }else if(this.readOnly){
  2069. multiply("ReadOnly");
  2070. }else{
  2071. if(this.active){
  2072. multiply("Active");
  2073. }else if(this.hovering){
  2074. multiply("Hover");
  2075. }
  2076. }
  2077. if(this.focused){
  2078. multiply("Focused");
  2079. }
  2080. // Remove old state classes and add new ones.
  2081. // For performance concerns we only write into domNode.className once.
  2082. var tn = this.stateNode || this.domNode,
  2083. classHash = {}; // set of all classes (state and otherwise) for node
  2084. array.forEach(tn.className.split(" "), function(c){ classHash[c] = true; });
  2085. if("_stateClasses" in this){
  2086. array.forEach(this._stateClasses, function(c){ delete classHash[c]; });
  2087. }
  2088. array.forEach(newStateClasses, function(c){ classHash[c] = true; });
  2089. var newClasses = [];
  2090. for(var c in classHash){
  2091. newClasses.push(c);
  2092. }
  2093. tn.className = newClasses.join(" ");
  2094. this._stateClasses = newStateClasses;
  2095. },
  2096. _trackMouseState: function(/*DomNode*/ node, /*String*/ clazz){
  2097. // summary:
  2098. // Track mouse/focus events on specified node and set CSS class on that node to indicate
  2099. // current state. Usually not called directly, but via cssStateNodes attribute.
  2100. // description:
  2101. // Given class=foo, will set the following CSS class on the node
  2102. // - fooActive: if the user is currently pressing down the mouse button while over the node
  2103. // - fooHover: if the user is hovering the mouse over the node, but not pressing down a button
  2104. // - fooFocus: if the node is focused
  2105. //
  2106. // Note that it won't set any classes if the widget is disabled.
  2107. // node: DomNode
  2108. // Should be a sub-node of the widget, not the top node (this.domNode), since the top node
  2109. // is handled specially and automatically just by mixing in this class.
  2110. // clazz: String
  2111. // CSS class name (ex: dijitSliderUpArrow).
  2112. // Current state of node (initially false)
  2113. // NB: setting specifically to false because domClass.toggle() needs true boolean as third arg
  2114. var hovering=false, active=false, focused=false;
  2115. var self = this,
  2116. cn = lang.hitch(this, "connect", node);
  2117. function setClass(){
  2118. var disabled = ("disabled" in self && self.disabled) || ("readonly" in self && self.readonly);
  2119. domClass.toggle(node, clazz+"Hover", hovering && !active && !disabled);
  2120. domClass.toggle(node, clazz+"Active", active && !disabled);
  2121. domClass.toggle(node, clazz+"Focused", focused && !disabled);
  2122. }
  2123. // Mouse
  2124. cn("onmouseenter", function(){
  2125. hovering = true;
  2126. setClass();
  2127. });
  2128. cn("onmouseleave", function(){
  2129. hovering = false;
  2130. active = false;
  2131. setClass();
  2132. });
  2133. cn(touch.press, function(){
  2134. active = true;
  2135. setClass();
  2136. });
  2137. cn(touch.release, function(){
  2138. active = false;
  2139. setClass();
  2140. });
  2141. // Focus
  2142. cn("onfocus", function(){
  2143. focused = true;
  2144. setClass();
  2145. });
  2146. cn("onblur", function(){
  2147. focused = false;
  2148. setClass();
  2149. });
  2150. // Just in case widget is enabled/disabled while it has focus/hover/active state.
  2151. // Maybe this is overkill.
  2152. this.watch("disabled", setClass);
  2153. this.watch("readOnly", setClass);
  2154. }
  2155. });
  2156. });
  2157. },
  2158. 'dojo/_base/url':function(){
  2159. define(["./kernel"], function(dojo) {
  2160. // module:
  2161. // dojo/url
  2162. // summary:
  2163. // This module contains dojo._Url
  2164. var
  2165. ore = new RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$"),
  2166. ire = new RegExp("^((([^\\[:]+):)?([^@]+)@)?(\\[([^\\]]+)\\]|([^\\[:]*))(:([0-9]+))?$"),
  2167. _Url = function(){
  2168. var n = null,
  2169. _a = arguments,
  2170. uri = [_a[0]];
  2171. // resolve uri components relative to each other
  2172. for(var i = 1; i<_a.length; i++){
  2173. if(!_a[i]){ continue; }
  2174. // Safari doesn't support this.constructor so we have to be explicit
  2175. // FIXME: Tracked (and fixed) in Webkit bug 3537.
  2176. // http://bugs.webkit.org/show_bug.cgi?id=3537
  2177. var relobj = new _Url(_a[i]+""),
  2178. uriobj = new _Url(uri[0]+"");
  2179. if(
  2180. relobj.path == "" &&
  2181. !relobj.scheme &&
  2182. !relobj.authority &&
  2183. !relobj.query
  2184. ){
  2185. if(relobj.fragment != n){
  2186. uriobj.fragment = relobj.fragment;
  2187. }
  2188. relobj = uriobj;
  2189. }else if(!relobj.scheme){
  2190. relobj.scheme = uriobj.scheme;
  2191. if(!relobj.authority){
  2192. relobj.authority = uriobj.authority;
  2193. if(relobj.path.charAt(0) != "/"){
  2194. var path = uriobj.path.substring(0,
  2195. uriobj.path.lastIndexOf("/") + 1) + relobj.path;
  2196. var segs = path.split("/");
  2197. for(var j = 0; j < segs.length; j++){
  2198. if(segs[j] == "."){
  2199. // flatten "./" references
  2200. if(j == segs.length - 1){
  2201. segs[j] = "";
  2202. }else{
  2203. segs.splice(j, 1);
  2204. j--;
  2205. }
  2206. }else if(j > 0 && !(j == 1 && segs[0] == "") &&
  2207. segs[j] == ".." && segs[j-1] != ".."){
  2208. // flatten "../" references
  2209. if(j == (segs.length - 1)){
  2210. segs.splice(j, 1);
  2211. segs[j - 1] = "";
  2212. }else{
  2213. segs.splice(j - 1, 2);
  2214. j -= 2;
  2215. }
  2216. }
  2217. }
  2218. relobj.path = segs.join("/");
  2219. }
  2220. }
  2221. }
  2222. uri = [];
  2223. if(relobj.scheme){
  2224. uri.push(relobj.scheme, ":");
  2225. }
  2226. if(relobj.authority){
  2227. uri.push("//", relobj.authority);
  2228. }
  2229. uri.push(relobj.path);
  2230. if(relobj.query){
  2231. uri.push("?", relobj.query);
  2232. }
  2233. if(relobj.fragment){
  2234. uri.push("#", relobj.fragment);
  2235. }
  2236. }
  2237. this.uri = uri.join("");
  2238. // break the uri into its main components
  2239. var r = this.uri.match(ore);
  2240. this.scheme = r[2] || (r[1] ? "" : n);
  2241. this.authority = r[4] || (r[3] ? "" : n);
  2242. this.path = r[5]; // can never be undefined
  2243. this.query = r[7] || (r[6] ? "" : n);
  2244. this.fragment = r[9] || (r[8] ? "" : n);
  2245. if(this.authority != n){
  2246. // server based naming authority
  2247. r = this.authority.match(ire);
  2248. this.user = r[3] || n;
  2249. this.password = r[4] || n;
  2250. this.host = r[6] || r[7]; // ipv6 || ipv4
  2251. this.port = r[9] || n;
  2252. }
  2253. };
  2254. _Url.prototype.toString = function(){ return this.uri; };
  2255. return dojo._Url = _Url;
  2256. });
  2257. },
  2258. 'dojo/string':function(){
  2259. define(["./_base/kernel", "./_base/lang"], function(dojo, lang) {
  2260. // module:
  2261. // dojo/string
  2262. // summary:
  2263. // TODOC
  2264. lang.getObject("string", true, dojo);
  2265. /*=====
  2266. dojo.string = {
  2267. // summary: String utilities for Dojo
  2268. };
  2269. =====*/
  2270. dojo.string.rep = function(/*String*/str, /*Integer*/num){
  2271. // summary:
  2272. // Efficiently replicate a string `n` times.
  2273. // str:
  2274. // the string to replicate
  2275. // num:
  2276. // number of times to replicate the string
  2277. if(num <= 0 || !str){ return ""; }
  2278. var buf = [];
  2279. for(;;){
  2280. if(num & 1){
  2281. buf.push(str);
  2282. }
  2283. if(!(num >>= 1)){ break; }
  2284. str += str;
  2285. }
  2286. return buf.join(""); // String
  2287. };
  2288. dojo.string.pad = function(/*String*/text, /*Integer*/size, /*String?*/ch, /*Boolean?*/end){
  2289. // summary:
  2290. // Pad a string to guarantee that it is at least `size` length by
  2291. // filling with the character `ch` at either the start or end of the
  2292. // string. Pads at the start, by default.
  2293. // text:
  2294. // the string to pad
  2295. // size:
  2296. // length to provide padding
  2297. // ch:
  2298. // character to pad, defaults to '0'
  2299. // end:
  2300. // adds padding at the end if true, otherwise pads at start
  2301. // example:
  2302. // | // Fill the string to length 10 with "+" characters on the right. Yields "Dojo++++++".
  2303. // | dojo.string.pad("Dojo", 10, "+", true);
  2304. if(!ch){
  2305. ch = '0';
  2306. }
  2307. var out = String(text),
  2308. pad = dojo.string.rep(ch, Math.ceil((size - out.length) / ch.length));
  2309. return end ? out + pad : pad + out; // String
  2310. };
  2311. dojo.string.substitute = function( /*String*/ template,
  2312. /*Object|Array*/map,
  2313. /*Function?*/ transform,
  2314. /*Object?*/ thisObject){
  2315. // summary:
  2316. // Performs parameterized substitutions on a string. Throws an
  2317. // exception if any parameter is unmatched.
  2318. // template:
  2319. // a string with expressions in the form `${key}` to be replaced or
  2320. // `${key:format}` which specifies a format function. keys are case-sensitive.
  2321. // map:
  2322. // hash to search for substitutions
  2323. // transform:
  2324. // a function to process all parameters before substitution takes
  2325. // place, e.g. mylib.encodeXML
  2326. // thisObject:
  2327. // where to look for optional format function; default to the global
  2328. // namespace
  2329. // example:
  2330. // Substitutes two expressions in a string from an Array or Object
  2331. // | // returns "File 'foo.html' is not found in directory '/temp'."
  2332. // | // by providing substitution data in an Array
  2333. // | dojo.string.substitute(
  2334. // | "File '${0}' is not found in directory '${1}'.",
  2335. // | ["foo.html","/temp"]
  2336. // | );
  2337. // |
  2338. // | // also returns "File 'foo.html' is not found in directory '/temp'."
  2339. // | // but provides substitution data in an Object structure. Dotted
  2340. // | // notation may be used to traverse the structure.
  2341. // | dojo.string.substitute(
  2342. // | "File '${name}' is not found in directory '${info.dir}'.",
  2343. // | { name: "foo.html", info: { dir: "/temp" } }
  2344. // | );
  2345. // example:
  2346. // Use a transform function to modify the values:
  2347. // | // returns "file 'foo.html' is not found in directory '/temp'."
  2348. // | dojo.string.substitute(
  2349. // | "${0} is not found in ${1}.",
  2350. // | ["foo.html","/temp"],
  2351. // | function(str){
  2352. // | // try to figure out the type
  2353. // | var prefix = (str.charAt(0) == "/") ? "directory": "file";
  2354. // | return prefix + " '" + str + "'";
  2355. // | }
  2356. // | );
  2357. // example:
  2358. // Use a formatter
  2359. // | // returns "thinger -- howdy"
  2360. // | dojo.string.substitute(
  2361. // | "${0:postfix}", ["thinger"], null, {
  2362. // | postfix: function(value, key){
  2363. // | return value + " -- howdy";
  2364. // | }
  2365. // | }
  2366. // | );
  2367. thisObject = thisObject || dojo.global;
  2368. transform = transform ?
  2369. lang.hitch(thisObject, transform) : function(v){ return v; };
  2370. return template.replace(/\$\{([^\s\:\}]+)(?:\:([^\s\:\}]+))?\}/g,
  2371. function(match, key, format){
  2372. var value = lang.getObject(key, false, map);
  2373. if(format){
  2374. value = lang.getObject(format, false, thisObject).call(thisObject, value, key);
  2375. }
  2376. return transform(value, key).toString();
  2377. }); // String
  2378. };
  2379. /*=====
  2380. dojo.string.trim = function(str){
  2381. // summary:
  2382. // Trims whitespace from both sides of the string
  2383. // str: String
  2384. // String to be trimmed
  2385. // returns: String
  2386. // Returns the trimmed string
  2387. // description:
  2388. // This version of trim() was taken from [Steven Levithan's blog](http://blog.stevenlevithan.com/archives/faster-trim-javascript).
  2389. // The short yet performant version of this function is dojo.trim(),
  2390. // which is part of Dojo base. Uses String.prototype.trim instead, if available.
  2391. return ""; // String
  2392. }
  2393. =====*/
  2394. dojo.string.trim = String.prototype.trim ?
  2395. lang.trim : // aliasing to the native function
  2396. function(str){
  2397. str = str.replace(/^\s+/, '');
  2398. for(var i = str.length - 1; i >= 0; i--){
  2399. if(/\S/.test(str.charAt(i))){
  2400. str = str.substring(0, i + 1);
  2401. break;
  2402. }
  2403. }
  2404. return str;
  2405. };
  2406. return dojo.string;
  2407. });
  2408. },
  2409. 'dijit/form/_FormValueWidget':function(){
  2410. define("dijit/form/_FormValueWidget", [
  2411. "dojo/_base/declare", // declare
  2412. "dojo/_base/sniff", // has("ie")
  2413. "./_FormWidget",
  2414. "./_FormValueMixin"
  2415. ], function(declare, has, _FormWidget, _FormValueMixin){
  2416. /*=====
  2417. var _FormWidget = dijit.form._FormWidget;
  2418. var _FormValueMixin = dijit.form._FormValueMixin;
  2419. =====*/
  2420. // module:
  2421. // dijit/form/_FormValueWidget
  2422. // summary:
  2423. // FormValueWidget
  2424. return declare("dijit.form._FormValueWidget", [_FormWidget, _FormValueMixin],
  2425. {
  2426. // summary:
  2427. // Base class for widgets corresponding to native HTML elements such as <input> or <select> that have user changeable values.
  2428. // description:
  2429. // Each _FormValueWidget represents a single input value, and has a (possibly hidden) <input> element,
  2430. // to which it serializes it's input value, so that form submission (either normal submission or via FormBind?)
  2431. // works as expected.
  2432. // Don't attempt to mixin the 'type', 'name' attributes here programatically -- they must be declared
  2433. // directly in the template as read by the parser in order to function. IE is known to specifically
  2434. // require the 'name' attribute at element creation time. See #8484, #8660.
  2435. _layoutHackIE7: function(){
  2436. // summary:
  2437. // Work around table sizing bugs on IE7 by forcing redraw
  2438. if(has("ie") == 7){ // fix IE7 layout bug when the widget is scrolled out of sight
  2439. var domNode = this.domNode;
  2440. var parent = domNode.parentNode;
  2441. var pingNode = domNode.firstChild || domNode; // target node most unlikely to have a custom filter
  2442. var origFilter = pingNode.style.filter; // save custom filter, most likely nothing
  2443. var _this = this;
  2444. while(parent && parent.clientHeight == 0){ // search for parents that haven't rendered yet
  2445. (function ping(){
  2446. var disconnectHandle = _this.connect(parent, "onscroll",
  2447. function(){
  2448. _this.disconnect(disconnectHandle); // only call once
  2449. pingNode.style.filter = (new Date()).getMilliseconds(); // set to anything that's unique
  2450. setTimeout(function(){ pingNode.style.filter = origFilter }, 0); // restore custom filter, if any
  2451. }
  2452. );
  2453. })();
  2454. parent = parent.parentNode;
  2455. }
  2456. }
  2457. }
  2458. });
  2459. });
  2460. },
  2461. 'dijit/registry':function(){
  2462. define("dijit/registry", [
  2463. "dojo/_base/array", // array.forEach array.map
  2464. "dojo/_base/sniff", // has("ie")
  2465. "dojo/_base/unload", // unload.addOnWindowUnload
  2466. "dojo/_base/window", // win.body
  2467. "." // dijit._scopeName
  2468. ], function(array, has, unload, win, dijit){
  2469. // module:
  2470. // dijit/registry
  2471. // summary:
  2472. // Registry of existing widget on page, plus some utility methods.
  2473. // Must be accessed through AMD api, ex:
  2474. // require(["dijit/registry"], function(registry){ registry.byId("foo"); })
  2475. var _widgetTypeCtr = {}, hash = {};
  2476. var registry = {
  2477. // summary:
  2478. // A set of widgets indexed by id
  2479. length: 0,
  2480. add: function(/*dijit._Widget*/ widget){
  2481. // summary:
  2482. // Add a widget to the registry. If a duplicate ID is detected, a error is thrown.
  2483. //
  2484. // widget: dijit._Widget
  2485. // Any dijit._Widget subclass.
  2486. if(hash[widget.id]){
  2487. throw new Error("Tried to register widget with id==" + widget.id + " but that id is already registered");
  2488. }
  2489. hash[widget.id] = widget;
  2490. this.length++;
  2491. },
  2492. remove: function(/*String*/ id){
  2493. // summary:
  2494. // Remove a widget from the registry. Does not destroy the widget; simply
  2495. // removes the reference.
  2496. if(hash[id]){
  2497. delete hash[id];
  2498. this.length--;
  2499. }
  2500. },
  2501. byId: function(/*String|Widget*/ id){
  2502. // summary:
  2503. // Find a widget by it's id.
  2504. // If passed a widget then just returns the widget.
  2505. return typeof id == "string" ? hash[id] : id; // dijit._Widget
  2506. },
  2507. byNode: function(/*DOMNode*/ node){
  2508. // summary:
  2509. // Returns the widget corresponding to the given DOMNode
  2510. return hash[node.getAttribute("widgetId")]; // dijit._Widget
  2511. },
  2512. toArray: function(){
  2513. // summary:
  2514. // Convert registry into a true Array
  2515. //
  2516. // example:
  2517. // Work with the widget .domNodes in a real Array
  2518. // | array.map(dijit.registry.toArray(), function(w){ return w.domNode; });
  2519. var ar = [];
  2520. for(var id in hash){
  2521. ar.push(hash[id]);
  2522. }
  2523. return ar; // dijit._Widget[]
  2524. },
  2525. getUniqueId: function(/*String*/widgetType){
  2526. // summary:
  2527. // Generates a unique id for a given widgetType
  2528. var id;
  2529. do{
  2530. id = widgetType + "_" +
  2531. (widgetType in _widgetTypeCtr ?
  2532. ++_widgetTypeCtr[widgetType] : _widgetTypeCtr[widgetType] = 0);
  2533. }while(hash[id]);
  2534. return dijit._scopeName == "dijit" ? id : dijit._scopeName + "_" + id; // String
  2535. },
  2536. findWidgets: function(/*DomNode*/ root){
  2537. // summary:
  2538. // Search subtree under root returning widgets found.
  2539. // Doesn't search for nested widgets (ie, widgets inside other widgets).
  2540. var outAry = [];
  2541. function getChildrenHelper(root){
  2542. for(var node = root.firstChild; node; node = node.nextSibling){
  2543. if(node.nodeType == 1){
  2544. var widgetId = node.getAttribute("widgetId");
  2545. if(widgetId){
  2546. var widget = hash[widgetId];
  2547. if(widget){ // may be null on page w/multiple dojo's loaded
  2548. outAry.push(widget);
  2549. }
  2550. }else{
  2551. getChildrenHelper(node);
  2552. }
  2553. }
  2554. }
  2555. }
  2556. getChildrenHelper(root);
  2557. return outAry;
  2558. },
  2559. _destroyAll: function(){
  2560. // summary:
  2561. // Code to destroy all widgets and do other cleanup on page unload
  2562. // Clean up focus manager lingering references to widgets and nodes
  2563. dijit._curFocus = null;
  2564. dijit._prevFocus = null;
  2565. dijit._activeStack = [];
  2566. // Destroy all the widgets, top down
  2567. array.forEach(registry.findWidgets(win.body()), function(widget){
  2568. // Avoid double destroy of widgets like Menu that are attached to <body>
  2569. // even though they are logically children of other widgets.
  2570. if(!widget._destroyed){
  2571. if(widget.destroyRecursive){
  2572. widget.destroyRecursive();
  2573. }else if(widget.destroy){
  2574. widget.destroy();
  2575. }
  2576. }
  2577. });
  2578. },
  2579. getEnclosingWidget: function(/*DOMNode*/ node){
  2580. // summary:
  2581. // Returns the widget whose DOM tree contains the specified DOMNode, or null if
  2582. // the node is not contained within the DOM tree of any widget
  2583. while(node){
  2584. var id = node.getAttribute && node.getAttribute("widgetId");
  2585. if(id){
  2586. return hash[id];
  2587. }
  2588. node = node.parentNode;
  2589. }
  2590. return null;
  2591. },
  2592. // In case someone needs to access hash.
  2593. // Actually, this is accessed from WidgetSet back-compatibility code
  2594. _hash: hash
  2595. };
  2596. /*=====
  2597. dijit.registry = {
  2598. // summary:
  2599. // A list of widgets on a page.
  2600. };
  2601. =====*/
  2602. dijit.registry = registry;
  2603. return registry;
  2604. });
  2605. },
  2606. 'dijit/_base/manager':function(){
  2607. define("dijit/_base/manager", [
  2608. "dojo/_base/array",
  2609. "dojo/_base/config", // defaultDuration
  2610. "../registry",
  2611. ".." // for setting exports to dijit namespace
  2612. ], function(array, config, registry, dijit){
  2613. // module:
  2614. // dijit/_base/manager
  2615. // summary:
  2616. // Shim to methods on registry, plus a few other declarations.
  2617. // New code should access dijit/registry directly when possible.
  2618. /*=====
  2619. dijit.byId = function(id){
  2620. // summary:
  2621. // Returns a widget by it's id, or if passed a widget, no-op (like dom.byId())
  2622. // id: String|dijit._Widget
  2623. return registry.byId(id); // dijit._Widget
  2624. };
  2625. dijit.getUniqueId = function(widgetType){
  2626. // summary:
  2627. // Generates a unique id for a given widgetType
  2628. // widgetType: String
  2629. return registry.getUniqueId(widgetType); // String
  2630. };
  2631. dijit.findWidgets = function(root){
  2632. // summary:
  2633. // Search subtree under root returning widgets found.
  2634. // Doesn't search for nested widgets (ie, widgets inside other widgets).
  2635. // root: DOMNode
  2636. return registry.findWidgets(root);
  2637. };
  2638. dijit._destroyAll = function(){
  2639. // summary:
  2640. // Code to destroy all widgets and do other cleanup on page unload
  2641. return registry._destroyAll();
  2642. };
  2643. dijit.byNode = function(node){
  2644. // summary:
  2645. // Returns the widget corresponding to the given DOMNode
  2646. // node: DOMNode
  2647. return registry.byNode(node); // dijit._Widget
  2648. };
  2649. dijit.getEnclosingWidget = function(node){
  2650. // summary:
  2651. // Returns the widget whose DOM tree contains the specified DOMNode, or null if
  2652. // the node is not contained within the DOM tree of any widget
  2653. // node: DOMNode
  2654. return registry.getEnclosingWidget(node);
  2655. };
  2656. =====*/
  2657. array.forEach(["byId", "getUniqueId", "findWidgets", "_destroyAll", "byNode", "getEnclosingWidget"], function(name){
  2658. dijit[name] = registry[name];
  2659. });
  2660. /*=====
  2661. dojo.mixin(dijit, {
  2662. // defaultDuration: Integer
  2663. // The default fx.animation speed (in ms) to use for all Dijit
  2664. // transitional fx.animations, unless otherwise specified
  2665. // on a per-instance basis. Defaults to 200, overrided by
  2666. // `djConfig.defaultDuration`
  2667. defaultDuration: 200
  2668. });
  2669. =====*/
  2670. dijit.defaultDuration = config["defaultDuration"] || 200;
  2671. return dijit;
  2672. });
  2673. },
  2674. 'dijit/_base/place':function(){
  2675. define("dijit/_base/place", [
  2676. "dojo/_base/array", // array.forEach
  2677. "dojo/_base/lang", // lang.isArray
  2678. "dojo/window", // windowUtils.getBox
  2679. "../place",
  2680. ".." // export to dijit namespace
  2681. ], function(array, lang, windowUtils, place, dijit){
  2682. // module:
  2683. // dijit/_base/place
  2684. // summary:
  2685. // Back compatibility module, new code should use dijit/place directly instead of using this module.
  2686. dijit.getViewport = function(){
  2687. // summary:
  2688. // Deprecated method to return the dimensions and scroll position of the viewable area of a browser window.
  2689. // New code should use windowUtils.getBox()
  2690. return windowUtils.getBox();
  2691. };
  2692. /*=====
  2693. dijit.placeOnScreen = function(node, pos, corners, padding){
  2694. // summary:
  2695. // Positions one of the node's corners at specified position
  2696. // such that node is fully visible in viewport.
  2697. // Deprecated, new code should use dijit.place.at() instead.
  2698. };
  2699. =====*/
  2700. dijit.placeOnScreen = place.at;
  2701. /*=====
  2702. dijit.placeOnScreenAroundElement = function(node, aroundElement, aroundCorners, layoutNode){
  2703. // summary:
  2704. // Like dijit.placeOnScreenAroundNode(), except it accepts an arbitrary object
  2705. // for the "around" argument and finds a proper processor to place a node.
  2706. // Deprecated, new code should use dijit.place.around() instead.
  2707. };
  2708. ====*/
  2709. dijit.placeOnScreenAroundElement = function(node, aroundNode, aroundCorners, layoutNode){
  2710. // Convert old style {"BL": "TL", "BR": "TR"} type argument
  2711. // to style needed by dijit.place code:
  2712. // [
  2713. // {aroundCorner: "BL", corner: "TL" },
  2714. // {aroundCorner: "BR", corner: "TR" }
  2715. // ]
  2716. var positions;
  2717. if(lang.isArray(aroundCorners)){
  2718. positions = aroundCorners;
  2719. }else{
  2720. positions = [];
  2721. for(var key in aroundCorners){
  2722. positions.push({aroundCorner: key, corner: aroundCorners[key]});
  2723. }
  2724. }
  2725. return place.around(node, aroundNode, positions, true, layoutNode);
  2726. };
  2727. /*=====
  2728. dijit.placeOnScreenAroundNode = function(node, aroundNode, aroundCorners, layoutNode){
  2729. // summary:
  2730. // Position node adjacent or kitty-corner to aroundNode
  2731. // such that it's fully visible in viewport.
  2732. // Deprecated, new code should use dijit.place.around() instead.
  2733. };
  2734. =====*/
  2735. dijit.placeOnScreenAroundNode = dijit.placeOnScreenAroundElement;
  2736. /*=====
  2737. dijit.placeOnScreenAroundRectangle = function(node, aroundRect, aroundCorners, layoutNode){
  2738. // summary:
  2739. // Like dijit.placeOnScreenAroundNode(), except that the "around"
  2740. // parameter is an arbitrary rectangle on the screen (x, y, width, height)
  2741. // instead of a dom node.
  2742. // Deprecated, new code should use dijit.place.around() instead.
  2743. };
  2744. =====*/
  2745. dijit.placeOnScreenAroundRectangle = dijit.placeOnScreenAroundElement;
  2746. dijit.getPopupAroundAlignment = function(/*Array*/ position, /*Boolean*/ leftToRight){
  2747. // summary:
  2748. // Deprecated method, unneeded when using dijit/place directly.
  2749. // Transforms the passed array of preferred positions into a format suitable for
  2750. // passing as the aroundCorners argument to dijit.placeOnScreenAroundElement.
  2751. //
  2752. // position: String[]
  2753. // This variable controls the position of the drop down.
  2754. // It's an array of strings with the following values:
  2755. //
  2756. // * before: places drop down to the left of the target node/widget, or to the right in
  2757. // the case of RTL scripts like Hebrew and Arabic
  2758. // * after: places drop down to the right of the target node/widget, or to the left in
  2759. // the case of RTL scripts like Hebrew and Arabic
  2760. // * above: drop down goes above target node
  2761. // * below: drop down goes below target node
  2762. //
  2763. // The list is positions is tried, in order, until a position is found where the drop down fits
  2764. // within the viewport.
  2765. //
  2766. // leftToRight: Boolean
  2767. // Whether the popup will be displaying in leftToRight mode.
  2768. //
  2769. var align = {};
  2770. array.forEach(position, function(pos){
  2771. var ltr = leftToRight;
  2772. switch(pos){
  2773. case "after":
  2774. align[leftToRight ? "BR" : "BL"] = leftToRight ? "BL" : "BR";
  2775. break;
  2776. case "before":
  2777. align[leftToRight ? "BL" : "BR"] = leftToRight ? "BR" : "BL";
  2778. break;
  2779. case "below-alt":
  2780. ltr = !ltr;
  2781. // fall through
  2782. case "below":
  2783. // first try to align left borders, next try to align right borders (or reverse for RTL mode)
  2784. align[ltr ? "BL" : "BR"] = ltr ? "TL" : "TR";
  2785. align[ltr ? "BR" : "BL"] = ltr ? "TR" : "TL";
  2786. break;
  2787. case "above-alt":
  2788. ltr = !ltr;
  2789. // fall through
  2790. case "above":
  2791. default:
  2792. // first try to align left borders, next try to align right borders (or reverse for RTL mode)
  2793. align[ltr ? "TL" : "TR"] = ltr ? "BL" : "BR";
  2794. align[ltr ? "TR" : "TL"] = ltr ? "BR" : "BL";
  2795. break;
  2796. }
  2797. });
  2798. return align;
  2799. };
  2800. return dijit;
  2801. });
  2802. },
  2803. 'dijit/WidgetSet':function(){
  2804. define("dijit/WidgetSet", [
  2805. "dojo/_base/array", // array.forEach array.map
  2806. "dojo/_base/declare", // declare
  2807. "dojo/_base/window", // win.global
  2808. "./registry" // to add functions to dijit.registry
  2809. ], function(array, declare, win, registry){
  2810. // module:
  2811. // dijit/WidgetSet
  2812. // summary:
  2813. // Legacy registry code. New modules should just use registry.
  2814. // Will be removed in 2.0.
  2815. var WidgetSet = declare("dijit.WidgetSet", null, {
  2816. // summary:
  2817. // A set of widgets indexed by id. A default instance of this class is
  2818. // available as `dijit.registry`
  2819. //
  2820. // example:
  2821. // Create a small list of widgets:
  2822. // | var ws = new dijit.WidgetSet();
  2823. // | ws.add(dijit.byId("one"));
  2824. // | ws.add(dijit.byId("two"));
  2825. // | // destroy both:
  2826. // | ws.forEach(function(w){ w.destroy(); });
  2827. //
  2828. // example:
  2829. // Using dijit.registry:
  2830. // | dijit.registry.forEach(function(w){ /* do something */ });
  2831. constructor: function(){
  2832. this._hash = {};
  2833. this.length = 0;
  2834. },
  2835. add: function(/*dijit._Widget*/ widget){
  2836. // summary:
  2837. // Add a widget to this list. If a duplicate ID is detected, a error is thrown.
  2838. //
  2839. // widget: dijit._Widget
  2840. // Any dijit._Widget subclass.
  2841. if(this._hash[widget.id]){
  2842. throw new Error("Tried to register widget with id==" + widget.id + " but that id is already registered");
  2843. }
  2844. this._hash[widget.id] = widget;
  2845. this.length++;
  2846. },
  2847. remove: function(/*String*/ id){
  2848. // summary:
  2849. // Remove a widget from this WidgetSet. Does not destroy the widget; simply
  2850. // removes the reference.
  2851. if(this._hash[id]){
  2852. delete this._hash[id];
  2853. this.length--;
  2854. }
  2855. },
  2856. forEach: function(/*Function*/ func, /* Object? */thisObj){
  2857. // summary:
  2858. // Call specified function for each widget in this set.
  2859. //
  2860. // func:
  2861. // A callback function to run for each item. Is passed the widget, the index
  2862. // in the iteration, and the full hash, similar to `array.forEach`.
  2863. //
  2864. // thisObj:
  2865. // An optional scope parameter
  2866. //
  2867. // example:
  2868. // Using the default `dijit.registry` instance:
  2869. // | dijit.registry.forEach(function(widget){
  2870. // | console.log(widget.declaredClass);
  2871. // | });
  2872. //
  2873. // returns:
  2874. // Returns self, in order to allow for further chaining.
  2875. thisObj = thisObj || win.global;
  2876. var i = 0, id;
  2877. for(id in this._hash){
  2878. func.call(thisObj, this._hash[id], i++, this._hash);
  2879. }
  2880. return this; // dijit.WidgetSet
  2881. },
  2882. filter: function(/*Function*/ filter, /* Object? */thisObj){
  2883. // summary:
  2884. // Filter down this WidgetSet to a smaller new WidgetSet
  2885. // Works the same as `array.filter` and `NodeList.filter`
  2886. //
  2887. // filter:
  2888. // Callback function to test truthiness. Is passed the widget
  2889. // reference and the pseudo-index in the object.
  2890. //
  2891. // thisObj: Object?
  2892. // Option scope to use for the filter function.
  2893. //
  2894. // example:
  2895. // Arbitrary: select the odd widgets in this list
  2896. // | dijit.registry.filter(function(w, i){
  2897. // | return i % 2 == 0;
  2898. // | }).forEach(function(w){ /* odd ones */ });
  2899. thisObj = thisObj || win.global;
  2900. var res = new WidgetSet(), i = 0, id;
  2901. for(id in this._hash){
  2902. var w = this._hash[id];
  2903. if(filter.call(thisObj, w, i++, this._hash)){
  2904. res.add(w);
  2905. }
  2906. }
  2907. return res; // dijit.WidgetSet
  2908. },
  2909. byId: function(/*String*/ id){
  2910. // summary:
  2911. // Find a widget in this list by it's id.
  2912. // example:
  2913. // Test if an id is in a particular WidgetSet
  2914. // | var ws = new dijit.WidgetSet();
  2915. // | ws.add(dijit.byId("bar"));
  2916. // | var t = ws.byId("bar") // returns a widget
  2917. // | var x = ws.byId("foo"); // returns undefined
  2918. return this._hash[id]; // dijit._Widget
  2919. },
  2920. byClass: function(/*String*/ cls){
  2921. // summary:
  2922. // Reduce this widgetset to a new WidgetSet of a particular `declaredClass`
  2923. //
  2924. // cls: String
  2925. // The Class to scan for. Full dot-notated string.
  2926. //
  2927. // example:
  2928. // Find all `dijit.TitlePane`s in a page:
  2929. // | dijit.registry.byClass("dijit.TitlePane").forEach(function(tp){ tp.close(); });
  2930. var res = new WidgetSet(), id, widget;
  2931. for(id in this._hash){
  2932. widget = this._hash[id];
  2933. if(widget.declaredClass == cls){
  2934. res.add(widget);
  2935. }
  2936. }
  2937. return res; // dijit.WidgetSet
  2938. },
  2939. toArray: function(){
  2940. // summary:
  2941. // Convert this WidgetSet into a true Array
  2942. //
  2943. // example:
  2944. // Work with the widget .domNodes in a real Array
  2945. // | array.map(dijit.registry.toArray(), function(w){ return w.domNode; });
  2946. var ar = [];
  2947. for(var id in this._hash){
  2948. ar.push(this._hash[id]);
  2949. }
  2950. return ar; // dijit._Widget[]
  2951. },
  2952. map: function(/* Function */func, /* Object? */thisObj){
  2953. // summary:
  2954. // Create a new Array from this WidgetSet, following the same rules as `array.map`
  2955. // example:
  2956. // | var nodes = dijit.registry.map(function(w){ return w.domNode; });
  2957. //
  2958. // returns:
  2959. // A new array of the returned values.
  2960. return array.map(this.toArray(), func, thisObj); // Array
  2961. },
  2962. every: function(func, thisObj){
  2963. // summary:
  2964. // A synthetic clone of `array.every` acting explicitly on this WidgetSet
  2965. //
  2966. // func: Function
  2967. // A callback function run for every widget in this list. Exits loop
  2968. // when the first false return is encountered.
  2969. //
  2970. // thisObj: Object?
  2971. // Optional scope parameter to use for the callback
  2972. thisObj = thisObj || win.global;
  2973. var x = 0, i;
  2974. for(i in this._hash){
  2975. if(!func.call(thisObj, this._hash[i], x++, this._hash)){
  2976. return false; // Boolean
  2977. }
  2978. }
  2979. return true; // Boolean
  2980. },
  2981. some: function(func, thisObj){
  2982. // summary:
  2983. // A synthetic clone of `array.some` acting explicitly on this WidgetSet
  2984. //
  2985. // func: Function
  2986. // A callback function run for every widget in this list. Exits loop
  2987. // when the first true return is encountered.
  2988. //
  2989. // thisObj: Object?
  2990. // Optional scope parameter to use for the callback
  2991. thisObj = thisObj || win.global;
  2992. var x = 0, i;
  2993. for(i in this._hash){
  2994. if(func.call(thisObj, this._hash[i], x++, this._hash)){
  2995. return true; // Boolean
  2996. }
  2997. }
  2998. return false; // Boolean
  2999. }
  3000. });
  3001. // Add in 1.x compatibility methods to dijit.registry.
  3002. // These functions won't show up in the API doc but since they are deprecated anyway,
  3003. // that's probably for the best.
  3004. array.forEach(["forEach", "filter", "byClass", "map", "every", "some"], function(func){
  3005. registry[func] = WidgetSet.prototype[func];
  3006. });
  3007. return WidgetSet;
  3008. });
  3009. },
  3010. 'dijit/a11y':function(){
  3011. define("dijit/a11y", [
  3012. "dojo/_base/array", // array.forEach array.map
  3013. "dojo/dom", // dom.byId
  3014. "dojo/dom-attr", // domAttr.attr domAttr.has
  3015. "dojo/dom-style", // domStyle.style
  3016. "dojo/_base/lang", // lang.mixin()
  3017. "dojo/_base/sniff", // has("ie") 1
  3018. "./main" // for exporting methods to dijit namespace
  3019. ], function(array, dom, domAttr, domStyle, lang, has, dijit){
  3020. // module:
  3021. // dijit/a11y
  3022. var undefined;
  3023. var a11y = {
  3024. // summary:
  3025. // Accessibility utility functions (keyboard, tab stops, etc.)
  3026. _isElementShown: function(/*Element*/ elem){
  3027. var s = domStyle.get(elem);
  3028. return (s.visibility != "hidden")
  3029. && (s.visibility != "collapsed")
  3030. && (s.display != "none")
  3031. && (domAttr.get(elem, "type") != "hidden");
  3032. },
  3033. hasDefaultTabStop: function(/*Element*/ elem){
  3034. // summary:
  3035. // Tests if element is tab-navigable even without an explicit tabIndex setting
  3036. // No explicit tabIndex setting, need to investigate node type
  3037. switch(elem.nodeName.toLowerCase()){
  3038. case "a":
  3039. // An <a> w/out a tabindex is only navigable if it has an href
  3040. return domAttr.has(elem, "href");
  3041. case "area":
  3042. case "button":
  3043. case "input":
  3044. case "object":
  3045. case "select":
  3046. case "textarea":
  3047. // These are navigable by default
  3048. return true;
  3049. case "iframe":
  3050. // If it's an editor <iframe> then it's tab navigable.
  3051. var body;
  3052. try{
  3053. // non-IE
  3054. var contentDocument = elem.contentDocument;
  3055. if("designMode" in contentDocument && contentDocument.designMode == "on"){
  3056. return true;
  3057. }
  3058. body = contentDocument.body;
  3059. }catch(e1){
  3060. // contentWindow.document isn't accessible within IE7/8
  3061. // if the iframe.src points to a foreign url and this
  3062. // page contains an element, that could get focus
  3063. try{
  3064. body = elem.contentWindow.document.body;
  3065. }catch(e2){
  3066. return false;
  3067. }
  3068. }
  3069. return body && (body.contentEditable == 'true' ||
  3070. (body.firstChild && body.firstChild.contentEditable == 'true'));
  3071. default:
  3072. return elem.contentEditable == 'true';
  3073. }
  3074. },
  3075. effectiveTabIndex: function(/*Element*/ elem){
  3076. // summary:
  3077. // Returns effective tabIndex of an element, either a number, or undefined if element isn't focusable.
  3078. if(domAttr.get(elem, "disabled")){
  3079. return undefined;
  3080. }else if(domAttr.has(elem, "tabIndex")){
  3081. // Explicit tab index setting
  3082. return +domAttr.get(elem, "tabIndex");// + to convert string --> number
  3083. }else{
  3084. // No explicit tabIndex setting, so depends on node type
  3085. return a11y.hasDefaultTabStop(elem) ? 0 : undefined;
  3086. }
  3087. },
  3088. isTabNavigable: function(/*Element*/ elem){
  3089. // summary:
  3090. // Tests if an element is tab-navigable
  3091. return a11y.effectiveTabIndex(elem) >= 0;
  3092. },
  3093. isFocusable: function(/*Element*/ elem){
  3094. // summary:
  3095. // Tests if an element is focusable by tabbing to it, or clicking it with the mouse.
  3096. return a11y.effectiveTabIndex(elem) >= -1;
  3097. },
  3098. _getTabNavigable: function(/*DOMNode*/ root){
  3099. // summary:
  3100. // Finds descendants of the specified root node.
  3101. // description:
  3102. // Finds the following descendants of the specified root node:
  3103. //
  3104. // - the first tab-navigable element in document order
  3105. // without a tabIndex or with tabIndex="0"
  3106. // - the last tab-navigable element in document order
  3107. // without a tabIndex or with tabIndex="0"
  3108. // - the first element in document order with the lowest
  3109. // positive tabIndex value
  3110. // - the last element in document order with the highest
  3111. // positive tabIndex value
  3112. var first, last, lowest, lowestTabindex, highest, highestTabindex, radioSelected = {};
  3113. function radioName(node){
  3114. // If this element is part of a radio button group, return the name for that group.
  3115. return node && node.tagName.toLowerCase() == "input" &&
  3116. node.type && node.type.toLowerCase() == "radio" &&
  3117. node.name && node.name.toLowerCase();
  3118. }
  3119. var shown = a11y._isElementShown, effectiveTabIndex = a11y.effectiveTabIndex;
  3120. var walkTree = function(/*DOMNode*/ parent){
  3121. for(var child = parent.firstChild; child; child = child.nextSibling){
  3122. // Skip text elements, hidden elements, and also non-HTML elements (those in custom namespaces) in IE,
  3123. // since show() invokes getAttribute("type"), which crash on VML nodes in IE.
  3124. if(child.nodeType != 1 || (has("ie") <= 9 && child.scopeName !== "HTML") || !shown(child)){
  3125. continue;
  3126. }
  3127. var tabindex = effectiveTabIndex(child);
  3128. if(tabindex >= 0){
  3129. if(tabindex == 0){
  3130. if(!first){
  3131. first = child;
  3132. }
  3133. last = child;
  3134. }else if(tabindex > 0){
  3135. if(!lowest || tabindex < lowestTabindex){
  3136. lowestTabindex = tabindex;
  3137. lowest = child;
  3138. }
  3139. if(!highest || tabindex >= highestTabindex){
  3140. highestTabindex = tabindex;
  3141. highest = child;
  3142. }
  3143. }
  3144. var rn = radioName(child);
  3145. if(domAttr.get(child, "checked") && rn){
  3146. radioSelected[rn] = child;
  3147. }
  3148. }
  3149. if(child.nodeName.toUpperCase() != 'SELECT'){
  3150. walkTree(child);
  3151. }
  3152. }
  3153. };
  3154. if(shown(root)){
  3155. walkTree(root);
  3156. }
  3157. function rs(node){
  3158. // substitute checked radio button for unchecked one, if there is a checked one with the same name.
  3159. return radioSelected[radioName(node)] || node;
  3160. }
  3161. return { first: rs(first), last: rs(last), lowest: rs(lowest), highest: rs(highest) };
  3162. },
  3163. getFirstInTabbingOrder: function(/*String|DOMNode*/ root, /*Document?*/ doc){
  3164. // summary:
  3165. // Finds the descendant of the specified root node
  3166. // that is first in the tabbing order
  3167. var elems = a11y._getTabNavigable(dom.byId(root, doc));
  3168. return elems.lowest ? elems.lowest : elems.first; // DomNode
  3169. },
  3170. getLastInTabbingOrder: function(/*String|DOMNode*/ root, /*Document?*/ doc){
  3171. // summary:
  3172. // Finds the descendant of the specified root node
  3173. // that is last in the tabbing order
  3174. var elems = a11y._getTabNavigable(dom.byId(root, doc));
  3175. return elems.last ? elems.last : elems.highest; // DomNode
  3176. }
  3177. };
  3178. 1 && lang.mixin(dijit, a11y);
  3179. return a11y;
  3180. });
  3181. },
  3182. 'dijit/typematic':function(){
  3183. define([
  3184. "dojo/_base/array", // array.forEach
  3185. "dojo/_base/connect", // connect.connect
  3186. "dojo/_base/event", // event.stop
  3187. "dojo/_base/kernel", // kernel.deprecated
  3188. "dojo/_base/lang", // lang.mixin, lang.hitch
  3189. "dojo/on",
  3190. "dojo/_base/sniff", // has("ie")
  3191. "." // setting dijit.typematic global
  3192. ], function(array, connect, event, kernel, lang, on, has, dijit){
  3193. // module:
  3194. // dijit/typematic
  3195. // summary:
  3196. // These functions are used to repetitively call a user specified callback
  3197. // method when a specific key or mouse click over a specific DOM node is
  3198. // held down for a specific amount of time.
  3199. // Only 1 such event is allowed to occur on the browser page at 1 time.
  3200. var typematic = (dijit.typematic = {
  3201. // summary:
  3202. // These functions are used to repetitively call a user specified callback
  3203. // method when a specific key or mouse click over a specific DOM node is
  3204. // held down for a specific amount of time.
  3205. // Only 1 such event is allowed to occur on the browser page at 1 time.
  3206. _fireEventAndReload: function(){
  3207. this._timer = null;
  3208. this._callback(++this._count, this._node, this._evt);
  3209. // Schedule next event, timer is at most minDelay (default 10ms) to avoid
  3210. // browser overload (particularly avoiding starving DOH robot so it never gets to send a mouseup)
  3211. this._currentTimeout = Math.max(
  3212. this._currentTimeout < 0 ? this._initialDelay :
  3213. (this._subsequentDelay > 1 ? this._subsequentDelay : Math.round(this._currentTimeout * this._subsequentDelay)),
  3214. this._minDelay);
  3215. this._timer = setTimeout(lang.hitch(this, "_fireEventAndReload"), this._currentTimeout);
  3216. },
  3217. trigger: function(/*Event*/ evt, /*Object*/ _this, /*DOMNode*/ node, /*Function*/ callback, /*Object*/ obj, /*Number*/ subsequentDelay, /*Number*/ initialDelay, /*Number?*/ minDelay){
  3218. // summary:
  3219. // Start a timed, repeating callback sequence.
  3220. // If already started, the function call is ignored.
  3221. // This method is not normally called by the user but can be
  3222. // when the normal listener code is insufficient.
  3223. // evt:
  3224. // key or mouse event object to pass to the user callback
  3225. // _this:
  3226. // pointer to the user's widget space.
  3227. // node:
  3228. // the DOM node object to pass the the callback function
  3229. // callback:
  3230. // function to call until the sequence is stopped called with 3 parameters:
  3231. // count:
  3232. // integer representing number of repeated calls (0..n) with -1 indicating the iteration has stopped
  3233. // node:
  3234. // the DOM node object passed in
  3235. // evt:
  3236. // key or mouse event object
  3237. // obj:
  3238. // user space object used to uniquely identify each typematic sequence
  3239. // subsequentDelay (optional):
  3240. // if > 1, the number of milliseconds until the 3->n events occur
  3241. // or else the fractional time multiplier for the next event's delay, default=0.9
  3242. // initialDelay (optional):
  3243. // the number of milliseconds until the 2nd event occurs, default=500ms
  3244. // minDelay (optional):
  3245. // the maximum delay in milliseconds for event to fire, default=10ms
  3246. if(obj != this._obj){
  3247. this.stop();
  3248. this._initialDelay = initialDelay || 500;
  3249. this._subsequentDelay = subsequentDelay || 0.90;
  3250. this._minDelay = minDelay || 10;
  3251. this._obj = obj;
  3252. this._evt = evt;
  3253. this._node = node;
  3254. this._currentTimeout = -1;
  3255. this._count = -1;
  3256. this._callback = lang.hitch(_this, callback);
  3257. this._fireEventAndReload();
  3258. this._evt = lang.mixin({faux: true}, evt);
  3259. }
  3260. },
  3261. stop: function(){
  3262. // summary:
  3263. // Stop an ongoing timed, repeating callback sequence.
  3264. if(this._timer){
  3265. clearTimeout(this._timer);
  3266. this._timer = null;
  3267. }
  3268. if(this._obj){
  3269. this._callback(-1, this._node, this._evt);
  3270. this._obj = null;
  3271. }
  3272. },
  3273. addKeyListener: function(/*DOMNode*/ node, /*Object*/ keyObject, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay, /*Number?*/ minDelay){
  3274. // summary:
  3275. // Start listening for a specific typematic key.
  3276. // See also the trigger method for other parameters.
  3277. // keyObject:
  3278. // an object defining the key to listen for:
  3279. // charOrCode:
  3280. // the printable character (string) or keyCode (number) to listen for.
  3281. // keyCode:
  3282. // (deprecated - use charOrCode) the keyCode (number) to listen for (implies charCode = 0).
  3283. // charCode:
  3284. // (deprecated - use charOrCode) the charCode (number) to listen for.
  3285. // ctrlKey:
  3286. // desired ctrl key state to initiate the callback sequence:
  3287. // - pressed (true)
  3288. // - released (false)
  3289. // - either (unspecified)
  3290. // altKey:
  3291. // same as ctrlKey but for the alt key
  3292. // shiftKey:
  3293. // same as ctrlKey but for the shift key
  3294. // returns:
  3295. // a connection handle
  3296. if(keyObject.keyCode){
  3297. keyObject.charOrCode = keyObject.keyCode;
  3298. kernel.deprecated("keyCode attribute parameter for dijit.typematic.addKeyListener is deprecated. Use charOrCode instead.", "", "2.0");
  3299. }else if(keyObject.charCode){
  3300. keyObject.charOrCode = String.fromCharCode(keyObject.charCode);
  3301. kernel.deprecated("charCode attribute parameter for dijit.typematic.addKeyListener is deprecated. Use charOrCode instead.", "", "2.0");
  3302. }
  3303. var handles = [
  3304. on(node, connect._keypress, lang.hitch(this, function(evt){
  3305. if(evt.charOrCode == keyObject.charOrCode &&
  3306. (keyObject.ctrlKey === undefined || keyObject.ctrlKey == evt.ctrlKey) &&
  3307. (keyObject.altKey === undefined || keyObject.altKey == evt.altKey) &&
  3308. (keyObject.metaKey === undefined || keyObject.metaKey == (evt.metaKey || false)) && // IE doesn't even set metaKey
  3309. (keyObject.shiftKey === undefined || keyObject.shiftKey == evt.shiftKey)){
  3310. event.stop(evt);
  3311. typematic.trigger(evt, _this, node, callback, keyObject, subsequentDelay, initialDelay, minDelay);
  3312. }else if(typematic._obj == keyObject){
  3313. typematic.stop();
  3314. }
  3315. })),
  3316. on(node, "keyup", lang.hitch(this, function(){
  3317. if(typematic._obj == keyObject){
  3318. typematic.stop();
  3319. }
  3320. }))
  3321. ];
  3322. return { remove: function(){ array.forEach(handles, function(h){ h.remove(); }); } };
  3323. },
  3324. addMouseListener: function(/*DOMNode*/ node, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay, /*Number?*/ minDelay){
  3325. // summary:
  3326. // Start listening for a typematic mouse click.
  3327. // See the trigger method for other parameters.
  3328. // returns:
  3329. // a connection handle
  3330. var handles = [
  3331. on(node, "mousedown", lang.hitch(this, function(evt){
  3332. event.stop(evt);
  3333. typematic.trigger(evt, _this, node, callback, node, subsequentDelay, initialDelay, minDelay);
  3334. })),
  3335. on(node, "mouseup", lang.hitch(this, function(evt){
  3336. if(this._obj){
  3337. event.stop(evt);
  3338. }
  3339. typematic.stop();
  3340. })),
  3341. on(node, "mouseout", lang.hitch(this, function(evt){
  3342. event.stop(evt);
  3343. typematic.stop();
  3344. })),
  3345. on(node, "mousemove", lang.hitch(this, function(evt){
  3346. evt.preventDefault();
  3347. })),
  3348. on(node, "dblclick", lang.hitch(this, function(evt){
  3349. event.stop(evt);
  3350. if(has("ie") < 9){
  3351. typematic.trigger(evt, _this, node, callback, node, subsequentDelay, initialDelay, minDelay);
  3352. setTimeout(lang.hitch(this, typematic.stop), 50);
  3353. }
  3354. }))
  3355. ];
  3356. return { remove: function(){ array.forEach(handles, function(h){ h.remove(); }); } };
  3357. },
  3358. addListener: function(/*Node*/ mouseNode, /*Node*/ keyNode, /*Object*/ keyObject, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay, /*Number?*/ minDelay){
  3359. // summary:
  3360. // Start listening for a specific typematic key and mouseclick.
  3361. // This is a thin wrapper to addKeyListener and addMouseListener.
  3362. // See the addMouseListener and addKeyListener methods for other parameters.
  3363. // mouseNode:
  3364. // the DOM node object to listen on for mouse events.
  3365. // keyNode:
  3366. // the DOM node object to listen on for key events.
  3367. // returns:
  3368. // a connection handle
  3369. var handles = [
  3370. this.addKeyListener(keyNode, keyObject, _this, callback, subsequentDelay, initialDelay, minDelay),
  3371. this.addMouseListener(mouseNode, _this, callback, subsequentDelay, initialDelay, minDelay)
  3372. ];
  3373. return { remove: function(){ array.forEach(handles, function(h){ h.remove(); }); } };
  3374. }
  3375. });
  3376. return typematic;
  3377. });
  3378. },
  3379. 'dijit/_base/focus':function(){
  3380. define("dijit/_base/focus", [
  3381. "dojo/_base/array", // array.forEach
  3382. "dojo/dom", // dom.isDescendant
  3383. "dojo/_base/lang", // lang.isArray
  3384. "dojo/topic", // publish
  3385. "dojo/_base/window", // win.doc win.doc.selection win.global win.global.getSelection win.withGlobal
  3386. "../focus",
  3387. ".." // for exporting symbols to dijit
  3388. ], function(array, dom, lang, topic, win, focus, dijit){
  3389. // module:
  3390. // dijit/_base/focus
  3391. // summary:
  3392. // Deprecated module to monitor currently focused node and stack of currently focused widgets.
  3393. // New code should access dijit/focus directly.
  3394. lang.mixin(dijit, {
  3395. // _curFocus: DomNode
  3396. // Currently focused item on screen
  3397. _curFocus: null,
  3398. // _prevFocus: DomNode
  3399. // Previously focused item on screen
  3400. _prevFocus: null,
  3401. isCollapsed: function(){
  3402. // summary:
  3403. // Returns true if there is no text selected
  3404. return dijit.getBookmark().isCollapsed;
  3405. },
  3406. getBookmark: function(){
  3407. // summary:
  3408. // Retrieves a bookmark that can be used with moveToBookmark to return to the same range
  3409. var bm, rg, tg, sel = win.doc.selection, cf = focus.curNode;
  3410. if(win.global.getSelection){
  3411. //W3C Range API for selections.
  3412. sel = win.global.getSelection();
  3413. if(sel){
  3414. if(sel.isCollapsed){
  3415. tg = cf? cf.tagName : "";
  3416. if(tg){
  3417. //Create a fake rangelike item to restore selections.
  3418. tg = tg.toLowerCase();
  3419. if(tg == "textarea" ||
  3420. (tg == "input" && (!cf.type || cf.type.toLowerCase() == "text"))){
  3421. sel = {
  3422. start: cf.selectionStart,
  3423. end: cf.selectionEnd,
  3424. node: cf,
  3425. pRange: true
  3426. };
  3427. return {isCollapsed: (sel.end <= sel.start), mark: sel}; //Object.
  3428. }
  3429. }
  3430. bm = {isCollapsed:true};
  3431. if(sel.rangeCount){
  3432. bm.mark = sel.getRangeAt(0).cloneRange();
  3433. }
  3434. }else{
  3435. rg = sel.getRangeAt(0);
  3436. bm = {isCollapsed: false, mark: rg.cloneRange()};
  3437. }
  3438. }
  3439. }else if(sel){
  3440. // If the current focus was a input of some sort and no selection, don't bother saving
  3441. // a native bookmark. This is because it causes issues with dialog/page selection restore.
  3442. // So, we need to create psuedo bookmarks to work with.
  3443. tg = cf ? cf.tagName : "";
  3444. tg = tg.toLowerCase();
  3445. if(cf && tg && (tg == "button" || tg == "textarea" || tg == "input")){
  3446. if(sel.type && sel.type.toLowerCase() == "none"){
  3447. return {
  3448. isCollapsed: true,
  3449. mark: null
  3450. }
  3451. }else{
  3452. rg = sel.createRange();
  3453. return {
  3454. isCollapsed: rg.text && rg.text.length?false:true,
  3455. mark: {
  3456. range: rg,
  3457. pRange: true
  3458. }
  3459. };
  3460. }
  3461. }
  3462. bm = {};
  3463. //'IE' way for selections.
  3464. try{
  3465. // createRange() throws exception when dojo in iframe
  3466. //and nothing selected, see #9632
  3467. rg = sel.createRange();
  3468. bm.isCollapsed = !(sel.type == 'Text' ? rg.htmlText.length : rg.length);
  3469. }catch(e){
  3470. bm.isCollapsed = true;
  3471. return bm;
  3472. }
  3473. if(sel.type.toUpperCase() == 'CONTROL'){
  3474. if(rg.length){
  3475. bm.mark=[];
  3476. var i=0,len=rg.length;
  3477. while(i<len){
  3478. bm.mark.push(rg.item(i++));
  3479. }
  3480. }else{
  3481. bm.isCollapsed = true;
  3482. bm.mark = null;
  3483. }
  3484. }else{
  3485. bm.mark = rg.getBookmark();
  3486. }
  3487. }else{
  3488. console.warn("No idea how to store the current selection for this browser!");
  3489. }
  3490. return bm; // Object
  3491. },
  3492. moveToBookmark: function(/*Object*/ bookmark){
  3493. // summary:
  3494. // Moves current selection to a bookmark
  3495. // bookmark:
  3496. // This should be a returned object from dijit.getBookmark()
  3497. var _doc = win.doc,
  3498. mark = bookmark.mark;
  3499. if(mark){
  3500. if(win.global.getSelection){
  3501. //W3C Rangi API (FF, WebKit, Opera, etc)
  3502. var sel = win.global.getSelection();
  3503. if(sel && sel.removeAllRanges){
  3504. if(mark.pRange){
  3505. var n = mark.node;
  3506. n.selectionStart = mark.start;
  3507. n.selectionEnd = mark.end;
  3508. }else{
  3509. sel.removeAllRanges();
  3510. sel.addRange(mark);
  3511. }
  3512. }else{
  3513. console.warn("No idea how to restore selection for this browser!");
  3514. }
  3515. }else if(_doc.selection && mark){
  3516. //'IE' way.
  3517. var rg;
  3518. if(mark.pRange){
  3519. rg = mark.range;
  3520. }else if(lang.isArray(mark)){
  3521. rg = _doc.body.createControlRange();
  3522. //rg.addElement does not have call/apply method, so can not call it directly
  3523. //rg is not available in "range.addElement(item)", so can't use that either
  3524. array.forEach(mark, function(n){
  3525. rg.addElement(n);
  3526. });
  3527. }else{
  3528. rg = _doc.body.createTextRange();
  3529. rg.moveToBookmark(mark);
  3530. }
  3531. rg.select();
  3532. }
  3533. }
  3534. },
  3535. getFocus: function(/*Widget?*/ menu, /*Window?*/ openedForWindow){
  3536. // summary:
  3537. // Called as getFocus(), this returns an Object showing the current focus
  3538. // and selected text.
  3539. //
  3540. // Called as getFocus(widget), where widget is a (widget representing) a button
  3541. // that was just pressed, it returns where focus was before that button
  3542. // was pressed. (Pressing the button may have either shifted focus to the button,
  3543. // or removed focus altogether.) In this case the selected text is not returned,
  3544. // since it can't be accurately determined.
  3545. //
  3546. // menu: dijit._Widget or {domNode: DomNode} structure
  3547. // The button that was just pressed. If focus has disappeared or moved
  3548. // to this button, returns the previous focus. In this case the bookmark
  3549. // information is already lost, and null is returned.
  3550. //
  3551. // openedForWindow:
  3552. // iframe in which menu was opened
  3553. //
  3554. // returns:
  3555. // A handle to restore focus/selection, to be passed to `dijit.focus`
  3556. var node = !focus.curNode || (menu && dom.isDescendant(focus.curNode, menu.domNode)) ? dijit._prevFocus : focus.curNode;
  3557. return {
  3558. node: node,
  3559. bookmark: node && (node == focus.curNode) && win.withGlobal(openedForWindow || win.global, dijit.getBookmark),
  3560. openedForWindow: openedForWindow
  3561. }; // Object
  3562. },
  3563. // _activeStack: dijit._Widget[]
  3564. // List of currently active widgets (focused widget and it's ancestors)
  3565. _activeStack: [],
  3566. registerIframe: function(/*DomNode*/ iframe){
  3567. // summary:
  3568. // Registers listeners on the specified iframe so that any click
  3569. // or focus event on that iframe (or anything in it) is reported
  3570. // as a focus/click event on the <iframe> itself.
  3571. // description:
  3572. // Currently only used by editor.
  3573. // returns:
  3574. // Handle to pass to unregisterIframe()
  3575. return focus.registerIframe(iframe);
  3576. },
  3577. unregisterIframe: function(/*Object*/ handle){
  3578. // summary:
  3579. // Unregisters listeners on the specified iframe created by registerIframe.
  3580. // After calling be sure to delete or null out the handle itself.
  3581. // handle:
  3582. // Handle returned by registerIframe()
  3583. handle && handle.remove();
  3584. },
  3585. registerWin: function(/*Window?*/targetWindow, /*DomNode?*/ effectiveNode){
  3586. // summary:
  3587. // Registers listeners on the specified window (either the main
  3588. // window or an iframe's window) to detect when the user has clicked somewhere
  3589. // or focused somewhere.
  3590. // description:
  3591. // Users should call registerIframe() instead of this method.
  3592. // targetWindow:
  3593. // If specified this is the window associated with the iframe,
  3594. // i.e. iframe.contentWindow.
  3595. // effectiveNode:
  3596. // If specified, report any focus events inside targetWindow as
  3597. // an event on effectiveNode, rather than on evt.target.
  3598. // returns:
  3599. // Handle to pass to unregisterWin()
  3600. return focus.registerWin(targetWindow, effectiveNode);
  3601. },
  3602. unregisterWin: function(/*Handle*/ handle){
  3603. // summary:
  3604. // Unregisters listeners on the specified window (either the main
  3605. // window or an iframe's window) according to handle returned from registerWin().
  3606. // After calling be sure to delete or null out the handle itself.
  3607. handle && handle.remove();
  3608. }
  3609. });
  3610. // Override focus singleton's focus function so that dijit.focus()
  3611. // has backwards compatible behavior of restoring selection (although
  3612. // probably no one is using that).
  3613. focus.focus = function(/*Object || DomNode */ handle){
  3614. // summary:
  3615. // Sets the focused node and the selection according to argument.
  3616. // To set focus to an iframe's content, pass in the iframe itself.
  3617. // handle:
  3618. // object returned by get(), or a DomNode
  3619. if(!handle){ return; }
  3620. var node = "node" in handle ? handle.node : handle, // because handle is either DomNode or a composite object
  3621. bookmark = handle.bookmark,
  3622. openedForWindow = handle.openedForWindow,
  3623. collapsed = bookmark ? bookmark.isCollapsed : false;
  3624. // Set the focus
  3625. // Note that for iframe's we need to use the <iframe> to follow the parentNode chain,
  3626. // but we need to set focus to iframe.contentWindow
  3627. if(node){
  3628. var focusNode = (node.tagName.toLowerCase() == "iframe") ? node.contentWindow : node;
  3629. if(focusNode && focusNode.focus){
  3630. try{
  3631. // Gecko throws sometimes if setting focus is impossible,
  3632. // node not displayed or something like that
  3633. focusNode.focus();
  3634. }catch(e){/*quiet*/}
  3635. }
  3636. focus._onFocusNode(node);
  3637. }
  3638. // set the selection
  3639. // do not need to restore if current selection is not empty
  3640. // (use keyboard to select a menu item) or if previous selection was collapsed
  3641. // as it may cause focus shift (Esp in IE).
  3642. if(bookmark && win.withGlobal(openedForWindow || win.global, dijit.isCollapsed) && !collapsed){
  3643. if(openedForWindow){
  3644. openedForWindow.focus();
  3645. }
  3646. try{
  3647. win.withGlobal(openedForWindow || win.global, dijit.moveToBookmark, null, [bookmark]);
  3648. }catch(e2){
  3649. /*squelch IE internal error, see http://trac.dojotoolkit.org/ticket/1984 */
  3650. }
  3651. }
  3652. };
  3653. // For back compatibility, monitor changes to focused node and active widget stack,
  3654. // publishing events and copying changes from focus manager variables into dijit (top level) variables
  3655. focus.watch("curNode", function(name, oldVal, newVal){
  3656. dijit._curFocus = newVal;
  3657. dijit._prevFocus = oldVal;
  3658. if(newVal){
  3659. topic.publish("focusNode", newVal); // publish
  3660. }
  3661. });
  3662. focus.watch("activeStack", function(name, oldVal, newVal){
  3663. dijit._activeStack = newVal;
  3664. });
  3665. focus.on("widget-blur", function(widget, by){
  3666. topic.publish("widgetBlur", widget, by); // publish
  3667. });
  3668. focus.on("widget-focus", function(widget, by){
  3669. topic.publish("widgetFocus", widget, by); // publish
  3670. });
  3671. return dijit;
  3672. });
  3673. },
  3674. 'dijit/place':function(){
  3675. define("dijit/place", [
  3676. "dojo/_base/array", // array.forEach array.map array.some
  3677. "dojo/dom-geometry", // domGeometry.position
  3678. "dojo/dom-style", // domStyle.getComputedStyle
  3679. "dojo/_base/kernel", // kernel.deprecated
  3680. "dojo/_base/window", // win.body
  3681. "./Viewport", // getEffectiveBox
  3682. "." // dijit (defining dijit.place to match API doc)
  3683. ], function(array, domGeometry, domStyle, kernel, win, Viewport, dijit){
  3684. // module:
  3685. // dijit/place
  3686. // summary:
  3687. // Code to place a popup relative to another node
  3688. function _place(/*DomNode*/ node, choices, layoutNode, aroundNodeCoords){
  3689. // summary:
  3690. // Given a list of spots to put node, put it at the first spot where it fits,
  3691. // of if it doesn't fit anywhere then the place with the least overflow
  3692. // choices: Array
  3693. // Array of elements like: {corner: 'TL', pos: {x: 10, y: 20} }
  3694. // Above example says to put the top-left corner of the node at (10,20)
  3695. // layoutNode: Function(node, aroundNodeCorner, nodeCorner, size)
  3696. // for things like tooltip, they are displayed differently (and have different dimensions)
  3697. // based on their orientation relative to the parent. This adjusts the popup based on orientation.
  3698. // It also passes in the available size for the popup, which is useful for tooltips to
  3699. // tell them that their width is limited to a certain amount. layoutNode() may return a value expressing
  3700. // how much the popup had to be modified to fit into the available space. This is used to determine
  3701. // what the best placement is.
  3702. // aroundNodeCoords: Object
  3703. // Size of aroundNode, ex: {w: 200, h: 50}
  3704. // get {x: 10, y: 10, w: 100, h:100} type obj representing position of
  3705. // viewport over document
  3706. var view = Viewport.getEffectiveBox(node.ownerDocument);
  3707. // This won't work if the node is inside a <div style="position: relative">,
  3708. // so reattach it to win.doc.body. (Otherwise, the positioning will be wrong
  3709. // and also it might get cutoff)
  3710. if(!node.parentNode || String(node.parentNode.tagName).toLowerCase() != "body"){
  3711. win.body().appendChild(node);
  3712. }
  3713. var best = null;
  3714. array.some(choices, function(choice){
  3715. var corner = choice.corner;
  3716. var pos = choice.pos;
  3717. var overflow = 0;
  3718. // calculate amount of space available given specified position of node
  3719. var spaceAvailable = {
  3720. w: {
  3721. 'L': view.l + view.w - pos.x,
  3722. 'R': pos.x - view.l,
  3723. 'M': view.w
  3724. }[corner.charAt(1)],
  3725. h: {
  3726. 'T': view.t + view.h - pos.y,
  3727. 'B': pos.y - view.t,
  3728. 'M': view.h
  3729. }[corner.charAt(0)]
  3730. };
  3731. // Clear left/right position settings set earlier so they don't interfere with calculations,
  3732. // specifically when layoutNode() (a.k.a. Tooltip.orient()) measures natural width of Tooltip
  3733. var s = node.style;
  3734. s.left = s.right = "auto";
  3735. // configure node to be displayed in given position relative to button
  3736. // (need to do this in order to get an accurate size for the node, because
  3737. // a tooltip's size changes based on position, due to triangle)
  3738. if(layoutNode){
  3739. var res = layoutNode(node, choice.aroundCorner, corner, spaceAvailable, aroundNodeCoords);
  3740. overflow = typeof res == "undefined" ? 0 : res;
  3741. }
  3742. // get node's size
  3743. var style = node.style;
  3744. var oldDisplay = style.display;
  3745. var oldVis = style.visibility;
  3746. if(style.display == "none"){
  3747. style.visibility = "hidden";
  3748. style.display = "";
  3749. }
  3750. var bb = domGeometry.position(node);
  3751. style.display = oldDisplay;
  3752. style.visibility = oldVis;
  3753. // coordinates and size of node with specified corner placed at pos,
  3754. // and clipped by viewport
  3755. var
  3756. startXpos = {
  3757. 'L': pos.x,
  3758. 'R': pos.x - bb.w,
  3759. 'M': Math.max(view.l, Math.min(view.l + view.w, pos.x + (bb.w >> 1)) - bb.w) // M orientation is more flexible
  3760. }[corner.charAt(1)],
  3761. startYpos = {
  3762. 'T': pos.y,
  3763. 'B': pos.y - bb.h,
  3764. 'M': Math.max(view.t, Math.min(view.t + view.h, pos.y + (bb.h >> 1)) - bb.h)
  3765. }[corner.charAt(0)],
  3766. startX = Math.max(view.l, startXpos),
  3767. startY = Math.max(view.t, startYpos),
  3768. endX = Math.min(view.l + view.w, startXpos + bb.w),
  3769. endY = Math.min(view.t + view.h, startYpos + bb.h),
  3770. width = endX - startX,
  3771. height = endY - startY;
  3772. overflow += (bb.w - width) + (bb.h - height);
  3773. if(best == null || overflow < best.overflow){
  3774. best = {
  3775. corner: corner,
  3776. aroundCorner: choice.aroundCorner,
  3777. x: startX,
  3778. y: startY,
  3779. w: width,
  3780. h: height,
  3781. overflow: overflow,
  3782. spaceAvailable: spaceAvailable
  3783. };
  3784. }
  3785. return !overflow;
  3786. });
  3787. // In case the best position is not the last one we checked, need to call
  3788. // layoutNode() again.
  3789. if(best.overflow && layoutNode){
  3790. layoutNode(node, best.aroundCorner, best.corner, best.spaceAvailable, aroundNodeCoords);
  3791. }
  3792. // And then position the node. Do this last, after the layoutNode() above
  3793. // has sized the node, due to browser quirks when the viewport is scrolled
  3794. // (specifically that a Tooltip will shrink to fit as though the window was
  3795. // scrolled to the left).
  3796. var s = node.style;
  3797. s.top = best.y + "px";
  3798. s.left = best.x + "px";
  3799. s.right = "auto"; // needed for FF or else tooltip goes to far left
  3800. return best;
  3801. }
  3802. /*=====
  3803. dijit.place.__Position = function(){
  3804. // x: Integer
  3805. // horizontal coordinate in pixels, relative to document body
  3806. // y: Integer
  3807. // vertical coordinate in pixels, relative to document body
  3808. this.x = x;
  3809. this.y = y;
  3810. };
  3811. =====*/
  3812. /*=====
  3813. dijit.place.__Rectangle = function(){
  3814. // x: Integer
  3815. // horizontal offset in pixels, relative to document body
  3816. // y: Integer
  3817. // vertical offset in pixels, relative to document body
  3818. // w: Integer
  3819. // width in pixels. Can also be specified as "width" for backwards-compatibility.
  3820. // h: Integer
  3821. // height in pixels. Can also be specified as "height" from backwards-compatibility.
  3822. this.x = x;
  3823. this.y = y;
  3824. this.w = w;
  3825. this.h = h;
  3826. };
  3827. =====*/
  3828. return (dijit.place = {
  3829. // summary:
  3830. // Code to place a DOMNode relative to another DOMNode.
  3831. // Load using require(["dijit/place"], function(place){ ... }).
  3832. at: function(node, pos, corners, padding){
  3833. // summary:
  3834. // Positions one of the node's corners at specified position
  3835. // such that node is fully visible in viewport.
  3836. // description:
  3837. // NOTE: node is assumed to be absolutely or relatively positioned.
  3838. // node: DOMNode
  3839. // The node to position
  3840. // pos: dijit.place.__Position
  3841. // Object like {x: 10, y: 20}
  3842. // corners: String[]
  3843. // Array of Strings representing order to try corners in, like ["TR", "BL"].
  3844. // Possible values are:
  3845. // * "BL" - bottom left
  3846. // * "BR" - bottom right
  3847. // * "TL" - top left
  3848. // * "TR" - top right
  3849. // padding: dijit.place.__Position?
  3850. // optional param to set padding, to put some buffer around the element you want to position.
  3851. // example:
  3852. // Try to place node's top right corner at (10,20).
  3853. // If that makes node go (partially) off screen, then try placing
  3854. // bottom left corner at (10,20).
  3855. // | place(node, {x: 10, y: 20}, ["TR", "BL"])
  3856. var choices = array.map(corners, function(corner){
  3857. var c = { corner: corner, pos: {x:pos.x,y:pos.y} };
  3858. if(padding){
  3859. c.pos.x += corner.charAt(1) == 'L' ? padding.x : -padding.x;
  3860. c.pos.y += corner.charAt(0) == 'T' ? padding.y : -padding.y;
  3861. }
  3862. return c;
  3863. });
  3864. return _place(node, choices);
  3865. },
  3866. around: function(
  3867. /*DomNode*/ node,
  3868. /*DomNode || dijit.place.__Rectangle*/ anchor,
  3869. /*String[]*/ positions,
  3870. /*Boolean*/ leftToRight,
  3871. /*Function?*/ layoutNode){
  3872. // summary:
  3873. // Position node adjacent or kitty-corner to anchor
  3874. // such that it's fully visible in viewport.
  3875. //
  3876. // description:
  3877. // Place node such that corner of node touches a corner of
  3878. // aroundNode, and that node is fully visible.
  3879. //
  3880. // anchor:
  3881. // Either a DOMNode or a __Rectangle (object with x, y, width, height).
  3882. //
  3883. // positions:
  3884. // Ordered list of positions to try matching up.
  3885. // * before: places drop down to the left of the anchor node/widget, or to the right in the case
  3886. // of RTL scripts like Hebrew and Arabic; aligns either the top of the drop down
  3887. // with the top of the anchor, or the bottom of the drop down with bottom of the anchor.
  3888. // * after: places drop down to the right of the anchor node/widget, or to the left in the case
  3889. // of RTL scripts like Hebrew and Arabic; aligns either the top of the drop down
  3890. // with the top of the anchor, or the bottom of the drop down with bottom of the anchor.
  3891. // * before-centered: centers drop down to the left of the anchor node/widget, or to the right
  3892. // in the case of RTL scripts like Hebrew and Arabic
  3893. // * after-centered: centers drop down to the right of the anchor node/widget, or to the left
  3894. // in the case of RTL scripts like Hebrew and Arabic
  3895. // * above-centered: drop down is centered above anchor node
  3896. // * above: drop down goes above anchor node, left sides aligned
  3897. // * above-alt: drop down goes above anchor node, right sides aligned
  3898. // * below-centered: drop down is centered above anchor node
  3899. // * below: drop down goes below anchor node
  3900. // * below-alt: drop down goes below anchor node, right sides aligned
  3901. //
  3902. // layoutNode: Function(node, aroundNodeCorner, nodeCorner)
  3903. // For things like tooltip, they are displayed differently (and have different dimensions)
  3904. // based on their orientation relative to the parent. This adjusts the popup based on orientation.
  3905. //
  3906. // leftToRight:
  3907. // True if widget is LTR, false if widget is RTL. Affects the behavior of "above" and "below"
  3908. // positions slightly.
  3909. //
  3910. // example:
  3911. // | placeAroundNode(node, aroundNode, {'BL':'TL', 'TR':'BR'});
  3912. // This will try to position node such that node's top-left corner is at the same position
  3913. // as the bottom left corner of the aroundNode (ie, put node below
  3914. // aroundNode, with left edges aligned). If that fails it will try to put
  3915. // the bottom-right corner of node where the top right corner of aroundNode is
  3916. // (ie, put node above aroundNode, with right edges aligned)
  3917. //
  3918. // if around is a DOMNode (or DOMNode id), convert to coordinates
  3919. var aroundNodePos = (typeof anchor == "string" || "offsetWidth" in anchor)
  3920. ? domGeometry.position(anchor, true)
  3921. : anchor;
  3922. // Compute position and size of visible part of anchor (it may be partially hidden by ancestor nodes w/scrollbars)
  3923. if(anchor.parentNode){
  3924. // ignore nodes between position:relative and position:absolute
  3925. var sawPosAbsolute = domStyle.getComputedStyle(anchor).position == "absolute";
  3926. var parent = anchor.parentNode;
  3927. while(parent && parent.nodeType == 1 && parent.nodeName != "BODY"){ //ignoring the body will help performance
  3928. var parentPos = domGeometry.position(parent, true),
  3929. pcs = domStyle.getComputedStyle(parent);
  3930. if(/relative|absolute/.test(pcs.position)){
  3931. sawPosAbsolute = false;
  3932. }
  3933. if(!sawPosAbsolute && /hidden|auto|scroll/.test(pcs.overflow)){
  3934. var bottomYCoord = Math.min(aroundNodePos.y + aroundNodePos.h, parentPos.y + parentPos.h);
  3935. var rightXCoord = Math.min(aroundNodePos.x + aroundNodePos.w, parentPos.x + parentPos.w);
  3936. aroundNodePos.x = Math.max(aroundNodePos.x, parentPos.x);
  3937. aroundNodePos.y = Math.max(aroundNodePos.y, parentPos.y);
  3938. aroundNodePos.h = bottomYCoord - aroundNodePos.y;
  3939. aroundNodePos.w = rightXCoord - aroundNodePos.x;
  3940. }
  3941. if(pcs.position == "absolute"){
  3942. sawPosAbsolute = true;
  3943. }
  3944. parent = parent.parentNode;
  3945. }
  3946. }
  3947. var x = aroundNodePos.x,
  3948. y = aroundNodePos.y,
  3949. width = "w" in aroundNodePos ? aroundNodePos.w : (aroundNodePos.w = aroundNodePos.width),
  3950. height = "h" in aroundNodePos ? aroundNodePos.h : (kernel.deprecated("place.around: dijit.place.__Rectangle: { x:"+x+", y:"+y+", height:"+aroundNodePos.height+", width:"+width+" } has been deprecated. Please use { x:"+x+", y:"+y+", h:"+aroundNodePos.height+", w:"+width+" }", "", "2.0"), aroundNodePos.h = aroundNodePos.height);
  3951. // Convert positions arguments into choices argument for _place()
  3952. var choices = [];
  3953. function push(aroundCorner, corner){
  3954. choices.push({
  3955. aroundCorner: aroundCorner,
  3956. corner: corner,
  3957. pos: {
  3958. x: {
  3959. 'L': x,
  3960. 'R': x + width,
  3961. 'M': x + (width >> 1)
  3962. }[aroundCorner.charAt(1)],
  3963. y: {
  3964. 'T': y,
  3965. 'B': y + height,
  3966. 'M': y + (height >> 1)
  3967. }[aroundCorner.charAt(0)]
  3968. }
  3969. })
  3970. }
  3971. array.forEach(positions, function(pos){
  3972. var ltr = leftToRight;
  3973. switch(pos){
  3974. case "above-centered":
  3975. push("TM", "BM");
  3976. break;
  3977. case "below-centered":
  3978. push("BM", "TM");
  3979. break;
  3980. case "after-centered":
  3981. ltr = !ltr;
  3982. // fall through
  3983. case "before-centered":
  3984. push(ltr ? "ML" : "MR", ltr ? "MR" : "ML");
  3985. break;
  3986. case "after":
  3987. ltr = !ltr;
  3988. // fall through
  3989. case "before":
  3990. push(ltr ? "TL" : "TR", ltr ? "TR" : "TL");
  3991. push(ltr ? "BL" : "BR", ltr ? "BR" : "BL");
  3992. break;
  3993. case "below-alt":
  3994. ltr = !ltr;
  3995. // fall through
  3996. case "below":
  3997. // first try to align left borders, next try to align right borders (or reverse for RTL mode)
  3998. push(ltr ? "BL" : "BR", ltr ? "TL" : "TR");
  3999. push(ltr ? "BR" : "BL", ltr ? "TR" : "TL");
  4000. break;
  4001. case "above-alt":
  4002. ltr = !ltr;
  4003. // fall through
  4004. case "above":
  4005. // first try to align left borders, next try to align right borders (or reverse for RTL mode)
  4006. push(ltr ? "TL" : "TR", ltr ? "BL" : "BR");
  4007. push(ltr ? "TR" : "TL", ltr ? "BR" : "BL");
  4008. break;
  4009. default:
  4010. // To assist dijit/_base/place, accept arguments of type {aroundCorner: "BL", corner: "TL"}.
  4011. // Not meant to be used directly.
  4012. push(pos.aroundCorner, pos.corner);
  4013. }
  4014. });
  4015. var position = _place(node, choices, layoutNode, {w: width, h: height});
  4016. position.aroundNodePos = aroundNodePos;
  4017. return position;
  4018. }
  4019. });
  4020. });
  4021. },
  4022. 'dijit/_Widget':function(){
  4023. define("dijit/_Widget", [
  4024. "dojo/aspect", // aspect.around
  4025. "dojo/_base/config", // config.isDebug
  4026. "dojo/_base/connect", // connect.connect
  4027. "dojo/_base/declare", // declare
  4028. "dojo/_base/kernel", // kernel.deprecated
  4029. "dojo/_base/lang", // lang.hitch
  4030. "dojo/query",
  4031. "dojo/ready",
  4032. "./registry", // registry.byNode
  4033. "./_WidgetBase",
  4034. "./_OnDijitClickMixin",
  4035. "./_FocusMixin",
  4036. "dojo/uacss", // browser sniffing (included for back-compat; subclasses may be using)
  4037. "./hccss" // high contrast mode sniffing (included to set CSS classes on <body>, module ret value unused)
  4038. ], function(aspect, config, connect, declare, kernel, lang, query, ready,
  4039. registry, _WidgetBase, _OnDijitClickMixin, _FocusMixin){
  4040. /*=====
  4041. var _WidgetBase = dijit._WidgetBase;
  4042. var _OnDijitClickMixin = dijit._OnDijitClickMixin;
  4043. var _FocusMixin = dijit._FocusMixin;
  4044. =====*/
  4045. // module:
  4046. // dijit/_Widget
  4047. // summary:
  4048. // Old base for widgets. New widgets should extend _WidgetBase instead
  4049. function connectToDomNode(){
  4050. // summary:
  4051. // If user connects to a widget method === this function, then they will
  4052. // instead actually be connecting the equivalent event on this.domNode
  4053. }
  4054. // Trap dojo.connect() calls to connectToDomNode methods, and redirect to _Widget.on()
  4055. function aroundAdvice(originalConnect){
  4056. return function(obj, event, scope, method){
  4057. if(obj && typeof event == "string" && obj[event] == connectToDomNode){
  4058. return obj.on(event.substring(2).toLowerCase(), lang.hitch(scope, method));
  4059. }
  4060. return originalConnect.apply(connect, arguments);
  4061. };
  4062. }
  4063. aspect.around(connect, "connect", aroundAdvice);
  4064. if(kernel.connect){
  4065. aspect.around(kernel, "connect", aroundAdvice);
  4066. }
  4067. var _Widget = declare("dijit._Widget", [_WidgetBase, _OnDijitClickMixin, _FocusMixin], {
  4068. // summary:
  4069. // Base class for all Dijit widgets.
  4070. //
  4071. // Extends _WidgetBase, adding support for:
  4072. // - declaratively/programatically specifying widget initialization parameters like
  4073. // onMouseMove="foo" that call foo when this.domNode gets a mousemove event
  4074. // - ondijitclick
  4075. // Support new data-dojo-attach-event="ondijitclick: ..." that is triggered by a mouse click or a SPACE/ENTER keypress
  4076. // - focus related functions
  4077. // In particular, the onFocus()/onBlur() callbacks. Driven internally by
  4078. // dijit/_base/focus.js.
  4079. // - deprecated methods
  4080. // - onShow(), onHide(), onClose()
  4081. //
  4082. // Also, by loading code in dijit/_base, turns on:
  4083. // - browser sniffing (putting browser id like .dj_ie on <html> node)
  4084. // - high contrast mode sniffing (add .dijit_a11y class to <body> if machine is in high contrast mode)
  4085. ////////////////// DEFERRED CONNECTS ///////////////////
  4086. onClick: connectToDomNode,
  4087. /*=====
  4088. onClick: function(event){
  4089. // summary:
  4090. // Connect to this function to receive notifications of mouse click events.
  4091. // event:
  4092. // mouse Event
  4093. // tags:
  4094. // callback
  4095. },
  4096. =====*/
  4097. onDblClick: connectToDomNode,
  4098. /*=====
  4099. onDblClick: function(event){
  4100. // summary:
  4101. // Connect to this function to receive notifications of mouse double click events.
  4102. // event:
  4103. // mouse Event
  4104. // tags:
  4105. // callback
  4106. },
  4107. =====*/
  4108. onKeyDown: connectToDomNode,
  4109. /*=====
  4110. onKeyDown: function(event){
  4111. // summary:
  4112. // Connect to this function to receive notifications of keys being pressed down.
  4113. // event:
  4114. // key Event
  4115. // tags:
  4116. // callback
  4117. },
  4118. =====*/
  4119. onKeyPress: connectToDomNode,
  4120. /*=====
  4121. onKeyPress: function(event){
  4122. // summary:
  4123. // Connect to this function to receive notifications of printable keys being typed.
  4124. // event:
  4125. // key Event
  4126. // tags:
  4127. // callback
  4128. },
  4129. =====*/
  4130. onKeyUp: connectToDomNode,
  4131. /*=====
  4132. onKeyUp: function(event){
  4133. // summary:
  4134. // Connect to this function to receive notifications of keys being released.
  4135. // event:
  4136. // key Event
  4137. // tags:
  4138. // callback
  4139. },
  4140. =====*/
  4141. onMouseDown: connectToDomNode,
  4142. /*=====
  4143. onMouseDown: function(event){
  4144. // summary:
  4145. // Connect to this function to receive notifications of when the mouse button is pressed down.
  4146. // event:
  4147. // mouse Event
  4148. // tags:
  4149. // callback
  4150. },
  4151. =====*/
  4152. onMouseMove: connectToDomNode,
  4153. /*=====
  4154. onMouseMove: function(event){
  4155. // summary:
  4156. // Connect to this function to receive notifications of when the mouse moves over nodes contained within this widget.
  4157. // event:
  4158. // mouse Event
  4159. // tags:
  4160. // callback
  4161. },
  4162. =====*/
  4163. onMouseOut: connectToDomNode,
  4164. /*=====
  4165. onMouseOut: function(event){
  4166. // summary:
  4167. // Connect to this function to receive notifications of when the mouse moves off of nodes contained within this widget.
  4168. // event:
  4169. // mouse Event
  4170. // tags:
  4171. // callback
  4172. },
  4173. =====*/
  4174. onMouseOver: connectToDomNode,
  4175. /*=====
  4176. onMouseOver: function(event){
  4177. // summary:
  4178. // Connect to this function to receive notifications of when the mouse moves onto nodes contained within this widget.
  4179. // event:
  4180. // mouse Event
  4181. // tags:
  4182. // callback
  4183. },
  4184. =====*/
  4185. onMouseLeave: connectToDomNode,
  4186. /*=====
  4187. onMouseLeave: function(event){
  4188. // summary:
  4189. // Connect to this function to receive notifications of when the mouse moves off of this widget.
  4190. // event:
  4191. // mouse Event
  4192. // tags:
  4193. // callback
  4194. },
  4195. =====*/
  4196. onMouseEnter: connectToDomNode,
  4197. /*=====
  4198. onMouseEnter: function(event){
  4199. // summary:
  4200. // Connect to this function to receive notifications of when the mouse moves onto this widget.
  4201. // event:
  4202. // mouse Event
  4203. // tags:
  4204. // callback
  4205. },
  4206. =====*/
  4207. onMouseUp: connectToDomNode,
  4208. /*=====
  4209. onMouseUp: function(event){
  4210. // summary:
  4211. // Connect to this function to receive notifications of when the mouse button is released.
  4212. // event:
  4213. // mouse Event
  4214. // tags:
  4215. // callback
  4216. },
  4217. =====*/
  4218. constructor: function(params){
  4219. // extract parameters like onMouseMove that should connect directly to this.domNode
  4220. this._toConnect = {};
  4221. for(var name in params){
  4222. if(this[name] === connectToDomNode){
  4223. this._toConnect[name.replace(/^on/, "").toLowerCase()] = params[name];
  4224. delete params[name];
  4225. }
  4226. }
  4227. },
  4228. postCreate: function(){
  4229. this.inherited(arguments);
  4230. // perform connection from this.domNode to user specified handlers (ex: onMouseMove)
  4231. for(var name in this._toConnect){
  4232. this.on(name, this._toConnect[name]);
  4233. }
  4234. delete this._toConnect;
  4235. },
  4236. on: function(/*String*/ type, /*Function*/ func){
  4237. if(this[this._onMap(type)] === connectToDomNode){
  4238. // Use connect.connect() rather than on() to get handling for "onmouseenter" on non-IE, etc.
  4239. // Also, need to specify context as "this" rather than the default context of the DOMNode
  4240. return connect.connect(this.domNode, type.toLowerCase(), this, func);
  4241. }
  4242. return this.inherited(arguments);
  4243. },
  4244. _setFocusedAttr: function(val){
  4245. // Remove this method in 2.0 (or sooner), just here to set _focused == focused, for back compat
  4246. // (but since it's a private variable we aren't required to keep supporting it).
  4247. this._focused = val;
  4248. this._set("focused", val);
  4249. },
  4250. ////////////////// DEPRECATED METHODS ///////////////////
  4251. setAttribute: function(/*String*/ attr, /*anything*/ value){
  4252. // summary:
  4253. // Deprecated. Use set() instead.
  4254. // tags:
  4255. // deprecated
  4256. kernel.deprecated(this.declaredClass+"::setAttribute(attr, value) is deprecated. Use set() instead.", "", "2.0");
  4257. this.set(attr, value);
  4258. },
  4259. attr: function(/*String|Object*/name, /*Object?*/value){
  4260. // summary:
  4261. // Set or get properties on a widget instance.
  4262. // name:
  4263. // The property to get or set. If an object is passed here and not
  4264. // a string, its keys are used as names of attributes to be set
  4265. // and the value of the object as values to set in the widget.
  4266. // value:
  4267. // Optional. If provided, attr() operates as a setter. If omitted,
  4268. // the current value of the named property is returned.
  4269. // description:
  4270. // This method is deprecated, use get() or set() directly.
  4271. // Print deprecation warning but only once per calling function
  4272. if(config.isDebug){
  4273. var alreadyCalledHash = arguments.callee._ach || (arguments.callee._ach = {}),
  4274. caller = (arguments.callee.caller || "unknown caller").toString();
  4275. if(!alreadyCalledHash[caller]){
  4276. kernel.deprecated(this.declaredClass + "::attr() is deprecated. Use get() or set() instead, called from " +
  4277. caller, "", "2.0");
  4278. alreadyCalledHash[caller] = true;
  4279. }
  4280. }
  4281. var args = arguments.length;
  4282. if(args >= 2 || typeof name === "object"){ // setter
  4283. return this.set.apply(this, arguments);
  4284. }else{ // getter
  4285. return this.get(name);
  4286. }
  4287. },
  4288. getDescendants: function(){
  4289. // summary:
  4290. // Returns all the widgets contained by this, i.e., all widgets underneath this.containerNode.
  4291. // This method should generally be avoided as it returns widgets declared in templates, which are
  4292. // supposed to be internal/hidden, but it's left here for back-compat reasons.
  4293. kernel.deprecated(this.declaredClass+"::getDescendants() is deprecated. Use getChildren() instead.", "", "2.0");
  4294. return this.containerNode ? query('[widgetId]', this.containerNode).map(registry.byNode) : []; // dijit._Widget[]
  4295. },
  4296. ////////////////// MISCELLANEOUS METHODS ///////////////////
  4297. _onShow: function(){
  4298. // summary:
  4299. // Internal method called when this widget is made visible.
  4300. // See `onShow` for details.
  4301. this.onShow();
  4302. },
  4303. onShow: function(){
  4304. // summary:
  4305. // Called when this widget becomes the selected pane in a
  4306. // `dijit.layout.TabContainer`, `dijit.layout.StackContainer`,
  4307. // `dijit.layout.AccordionContainer`, etc.
  4308. //
  4309. // Also called to indicate display of a `dijit.Dialog`, `dijit.TooltipDialog`, or `dijit.TitlePane`.
  4310. // tags:
  4311. // callback
  4312. },
  4313. onHide: function(){
  4314. // summary:
  4315. // Called when another widget becomes the selected pane in a
  4316. // `dijit.layout.TabContainer`, `dijit.layout.StackContainer`,
  4317. // `dijit.layout.AccordionContainer`, etc.
  4318. //
  4319. // Also called to indicate hide of a `dijit.Dialog`, `dijit.TooltipDialog`, or `dijit.TitlePane`.
  4320. // tags:
  4321. // callback
  4322. },
  4323. onClose: function(){
  4324. // summary:
  4325. // Called when this widget is being displayed as a popup (ex: a Calendar popped
  4326. // up from a DateTextBox), and it is hidden.
  4327. // This is called from the dijit.popup code, and should not be called directly.
  4328. //
  4329. // Also used as a parameter for children of `dijit.layout.StackContainer` or subclasses.
  4330. // Callback if a user tries to close the child. Child will be closed if this function returns true.
  4331. // tags:
  4332. // extension
  4333. return true; // Boolean
  4334. }
  4335. });
  4336. // For back-compat, remove in 2.0.
  4337. if(!kernel.isAsync){
  4338. ready(0, function(){
  4339. var requires = ["dijit/_base"];
  4340. require(requires); // use indirection so modules not rolled into a build
  4341. });
  4342. }
  4343. return _Widget;
  4344. });
  4345. },
  4346. 'dojo/cache':function(){
  4347. define(["./_base/kernel", "./text"], function(dojo, text){
  4348. // module:
  4349. // dojo/cache
  4350. // summary:
  4351. // The module defines dojo.cache by loading dojo/text.
  4352. //dojo.cache is defined in dojo/text
  4353. return dojo.cache;
  4354. });
  4355. },
  4356. 'dijit/_FocusMixin':function(){
  4357. define([
  4358. "./focus",
  4359. "./_WidgetBase",
  4360. "dojo/_base/declare", // declare
  4361. "dojo/_base/lang" // lang.extend
  4362. ], function(focus, _WidgetBase, declare, lang){
  4363. /*=====
  4364. var _WidgetBase = dijit._WidgetBase;
  4365. =====*/
  4366. // module:
  4367. // dijit/_FocusMixin
  4368. // summary:
  4369. // Mixin to widget to provide _onFocus() and _onBlur() methods that
  4370. // fire when a widget or it's descendants get/lose focus
  4371. // We don't know where _FocusMixin will occur in the inheritance chain, but we need the _onFocus()/_onBlur() below
  4372. // to be last in the inheritance chain, so mixin to _WidgetBase.
  4373. lang.extend(_WidgetBase, {
  4374. // focused: [readonly] Boolean
  4375. // This widget or a widget it contains has focus, or is "active" because
  4376. // it was recently clicked.
  4377. focused: false,
  4378. onFocus: function(){
  4379. // summary:
  4380. // Called when the widget becomes "active" because
  4381. // it or a widget inside of it either has focus, or has recently
  4382. // been clicked.
  4383. // tags:
  4384. // callback
  4385. },
  4386. onBlur: function(){
  4387. // summary:
  4388. // Called when the widget stops being "active" because
  4389. // focus moved to something outside of it, or the user
  4390. // clicked somewhere outside of it, or the widget was
  4391. // hidden.
  4392. // tags:
  4393. // callback
  4394. },
  4395. _onFocus: function(){
  4396. // summary:
  4397. // This is where widgets do processing for when they are active,
  4398. // such as changing CSS classes. See onFocus() for more details.
  4399. // tags:
  4400. // protected
  4401. this.onFocus();
  4402. },
  4403. _onBlur: function(){
  4404. // summary:
  4405. // This is where widgets do processing for when they stop being active,
  4406. // such as changing CSS classes. See onBlur() for more details.
  4407. // tags:
  4408. // protected
  4409. this.onBlur();
  4410. }
  4411. });
  4412. return declare("dijit._FocusMixin", null, {
  4413. // summary:
  4414. // Mixin to widget to provide _onFocus() and _onBlur() methods that
  4415. // fire when a widget or it's descendants get/lose focus
  4416. // flag that I want _onFocus()/_onBlur() notifications from focus manager
  4417. _focusManager: focus
  4418. });
  4419. });
  4420. },
  4421. 'dijit/_OnDijitClickMixin':function(){
  4422. define("dijit/_OnDijitClickMixin", [
  4423. "dojo/on",
  4424. "dojo/_base/array", // array.forEach
  4425. "dojo/keys", // keys.ENTER keys.SPACE
  4426. "dojo/_base/declare", // declare
  4427. "dojo/_base/sniff", // has("ie")
  4428. "dojo/_base/unload", // unload.addOnWindowUnload
  4429. "dojo/_base/window" // win.doc.addEventListener win.doc.attachEvent win.doc.detachEvent
  4430. ], function(on, array, keys, declare, has, unload, win){
  4431. // module:
  4432. // dijit/_OnDijitClickMixin
  4433. // summary:
  4434. // Mixin so you can pass "ondijitclick" to this.connect() method,
  4435. // as a way to handle clicks by mouse, or by keyboard (SPACE/ENTER key)
  4436. // Keep track of where the last keydown event was, to help avoid generating
  4437. // spurious ondijitclick events when:
  4438. // 1. focus is on a <button> or <a>
  4439. // 2. user presses then releases the ENTER key
  4440. // 3. onclick handler fires and shifts focus to another node, with an ondijitclick handler
  4441. // 4. onkeyup event fires, causing the ondijitclick handler to fire
  4442. var lastKeyDownNode = null;
  4443. if(has("ie") < 9){
  4444. (function(){
  4445. var keydownCallback = function(evt){
  4446. lastKeyDownNode = evt.srcElement;
  4447. };
  4448. win.doc.attachEvent('onkeydown', keydownCallback);
  4449. unload.addOnWindowUnload(function(){
  4450. win.doc.detachEvent('onkeydown', keydownCallback);
  4451. });
  4452. })();
  4453. }else{
  4454. win.doc.addEventListener('keydown', function(evt){
  4455. lastKeyDownNode = evt.target;
  4456. }, true);
  4457. }
  4458. // Custom a11yclick (a.k.a. ondijitclick) event
  4459. var a11yclick = function(node, listener){
  4460. if(/input|button/i.test(node.nodeName)){
  4461. // pass through, the browser already generates click event on SPACE/ENTER key
  4462. return on(node, "click", listener);
  4463. }else{
  4464. // Don't fire the click event unless both the keydown and keyup occur on this node.
  4465. // Avoids problems where focus shifted to this node or away from the node on keydown,
  4466. // either causing this node to process a stray keyup event, or causing another node
  4467. // to get a stray keyup event.
  4468. function clickKey(/*Event*/ e){
  4469. return (e.keyCode == keys.ENTER || e.keyCode == keys.SPACE) &&
  4470. !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey;
  4471. }
  4472. var handles = [
  4473. on(node, "keypress", function(e){
  4474. //console.log(this.id + ": onkeydown, e.target = ", e.target, ", lastKeyDownNode was ", lastKeyDownNode, ", equality is ", (e.target === lastKeyDownNode));
  4475. if(clickKey(e)){
  4476. // needed on IE for when focus changes between keydown and keyup - otherwise dropdown menus do not work
  4477. lastKeyDownNode = e.target;
  4478. // Prevent viewport scrolling on space key in IE<9.
  4479. // (Reproducible on test_Button.html on any of the first dijit.form.Button examples)
  4480. // Do this onkeypress rather than onkeydown because onkeydown.preventDefault() will
  4481. // suppress the onkeypress event, breaking _HasDropDown
  4482. e.preventDefault();
  4483. }
  4484. }),
  4485. on(node, "keyup", function(e){
  4486. //console.log(this.id + ": onkeyup, e.target = ", e.target, ", lastKeyDownNode was ", lastKeyDownNode, ", equality is ", (e.target === lastKeyDownNode));
  4487. if(clickKey(e) && e.target == lastKeyDownNode){ // === breaks greasemonkey
  4488. //need reset here or have problems in FF when focus returns to trigger element after closing popup/alert
  4489. lastKeyDownNode = null;
  4490. listener.call(this, e);
  4491. }
  4492. }),
  4493. on(node, "click", function(e){
  4494. // and connect for mouse clicks too (or touch-clicks on mobile)
  4495. listener.call(this, e);
  4496. })
  4497. ];
  4498. return {
  4499. remove: function(){
  4500. array.forEach(handles, function(h){ h.remove(); });
  4501. }
  4502. };
  4503. }
  4504. };
  4505. return declare("dijit._OnDijitClickMixin", null, {
  4506. connect: function(
  4507. /*Object|null*/ obj,
  4508. /*String|Function*/ event,
  4509. /*String|Function*/ method){
  4510. // summary:
  4511. // Connects specified obj/event to specified method of this object
  4512. // and registers for disconnect() on widget destroy.
  4513. // description:
  4514. // Provide widget-specific analog to connect.connect, except with the
  4515. // implicit use of this widget as the target object.
  4516. // This version of connect also provides a special "ondijitclick"
  4517. // event which triggers on a click or space or enter keyup.
  4518. // Events connected with `this.connect` are disconnected upon
  4519. // destruction.
  4520. // returns:
  4521. // A handle that can be passed to `disconnect` in order to disconnect before
  4522. // the widget is destroyed.
  4523. // example:
  4524. // | var btn = new dijit.form.Button();
  4525. // | // when foo.bar() is called, call the listener we're going to
  4526. // | // provide in the scope of btn
  4527. // | btn.connect(foo, "bar", function(){
  4528. // | console.debug(this.toString());
  4529. // | });
  4530. // tags:
  4531. // protected
  4532. return this.inherited(arguments, [obj, event == "ondijitclick" ? a11yclick : event, method]);
  4533. }
  4534. });
  4535. });
  4536. },
  4537. 'dijit/focus':function(){
  4538. define("dijit/focus", [
  4539. "dojo/aspect",
  4540. "dojo/_base/declare", // declare
  4541. "dojo/dom", // domAttr.get dom.isDescendant
  4542. "dojo/dom-attr", // domAttr.get dom.isDescendant
  4543. "dojo/dom-construct", // connect to domConstruct.empty, domConstruct.destroy
  4544. "dojo/Evented",
  4545. "dojo/_base/lang", // lang.hitch
  4546. "dojo/on",
  4547. "dojo/domReady",
  4548. "dojo/_base/sniff", // has("ie")
  4549. "dojo/Stateful",
  4550. "dojo/_base/window", // win.body
  4551. "dojo/window", // winUtils.get
  4552. "./a11y", // a11y.isTabNavigable
  4553. "./registry", // registry.byId
  4554. "./main" // to set dijit.focus
  4555. ], function(aspect, declare, dom, domAttr, domConstruct, Evented, lang, on, domReady, has, Stateful, win, winUtils,
  4556. a11y, registry, dijit){
  4557. // module:
  4558. // dijit/focus
  4559. var FocusManager = declare([Stateful, Evented], {
  4560. // summary:
  4561. // Tracks the currently focused node, and which widgets are currently "active".
  4562. // Access via require(["dijit/focus"], function(focus){ ... }).
  4563. //
  4564. // A widget is considered active if it or a descendant widget has focus,
  4565. // or if a non-focusable node of this widget or a descendant was recently clicked.
  4566. //
  4567. // Call focus.watch("curNode", callback) to track the current focused DOMNode,
  4568. // or focus.watch("activeStack", callback) to track the currently focused stack of widgets.
  4569. //
  4570. // Call focus.on("widget-blur", func) or focus.on("widget-focus", ...) to monitor when
  4571. // when widgets become active/inactive
  4572. //
  4573. // Finally, focus(node) will focus a node, suppressing errors if the node doesn't exist.
  4574. // curNode: DomNode
  4575. // Currently focused item on screen
  4576. curNode: null,
  4577. // activeStack: dijit/_WidgetBase[]
  4578. // List of currently active widgets (focused widget and it's ancestors)
  4579. activeStack: [],
  4580. constructor: function(){
  4581. // Don't leave curNode/prevNode pointing to bogus elements
  4582. var check = lang.hitch(this, function(node){
  4583. if(dom.isDescendant(this.curNode, node)){
  4584. this.set("curNode", null);
  4585. }
  4586. if(dom.isDescendant(this.prevNode, node)){
  4587. this.set("prevNode", null);
  4588. }
  4589. });
  4590. aspect.before(domConstruct, "empty", check);
  4591. aspect.before(domConstruct, "destroy", check);
  4592. },
  4593. registerIframe: function(/*DomNode*/ iframe){
  4594. // summary:
  4595. // Registers listeners on the specified iframe so that any click
  4596. // or focus event on that iframe (or anything in it) is reported
  4597. // as a focus/click event on the `<iframe>` itself.
  4598. // description:
  4599. // Currently only used by editor.
  4600. // returns:
  4601. // Handle with remove() method to deregister.
  4602. return this.registerWin(iframe.contentWindow, iframe);
  4603. },
  4604. registerWin: function(/*Window?*/targetWindow, /*DomNode?*/ effectiveNode){
  4605. // summary:
  4606. // Registers listeners on the specified window (either the main
  4607. // window or an iframe's window) to detect when the user has clicked somewhere
  4608. // or focused somewhere.
  4609. // description:
  4610. // Users should call registerIframe() instead of this method.
  4611. // targetWindow:
  4612. // If specified this is the window associated with the iframe,
  4613. // i.e. iframe.contentWindow.
  4614. // effectiveNode:
  4615. // If specified, report any focus events inside targetWindow as
  4616. // an event on effectiveNode, rather than on evt.target.
  4617. // returns:
  4618. // Handle with remove() method to deregister.
  4619. // TODO: make this function private in 2.0; Editor/users should call registerIframe(),
  4620. // Listen for blur and focus events on targetWindow's document.
  4621. var _this = this,
  4622. body = targetWindow.document && targetWindow.document.body;
  4623. if(body){
  4624. var mdh = on(body, 'mousedown', function(evt){
  4625. _this._justMouseDowned = true;
  4626. // Use a 13 ms timeout to work-around Chrome resolving too fast and focusout
  4627. // events not seeing that a mousedown just happened when a popup closes.
  4628. // See https://bugs.dojotoolkit.org/ticket/17668
  4629. setTimeout(function(){ _this._justMouseDowned = false; }, 13);
  4630. // workaround weird IE bug where the click is on an orphaned node
  4631. // (first time clicking a Select/DropDownButton inside a TooltipDialog).
  4632. // actually, strangely this is happening on latest chrome too.
  4633. if(evt && evt.target && evt.target.parentNode == null){
  4634. return;
  4635. }
  4636. _this._onTouchNode(effectiveNode || evt.target, "mouse");
  4637. });
  4638. var fih = on(body, 'focusin', function(evt){
  4639. // When you refocus the browser window, IE gives an event with an empty srcElement
  4640. if(!evt.target.tagName) { return; }
  4641. // IE reports that nodes like <body> have gotten focus, even though they have tabIndex=-1,
  4642. // ignore those events
  4643. var tag = evt.target.tagName.toLowerCase();
  4644. if(tag == "#document" || tag == "body"){ return; }
  4645. if(a11y.isTabNavigable(evt.target)){
  4646. // If condition doesn't seem quite right, but it is correctly preventing focus events for
  4647. // clicks on disabled buttons.
  4648. _this._onFocusNode(effectiveNode || evt.target);
  4649. }else{
  4650. // Previous code called _onTouchNode() for any activate event on a non-focusable node. Can
  4651. // probably just ignore such an event as it will be handled by onmousedown handler above, but
  4652. // leaving the code for now.
  4653. _this._onTouchNode(effectiveNode || evt.target);
  4654. }
  4655. });
  4656. var foh = on(body, 'focusout', function(evt){
  4657. _this._onBlurNode(effectiveNode || evt.target);
  4658. });
  4659. return {
  4660. remove: function(){
  4661. mdh.remove();
  4662. fih.remove();
  4663. foh.remove();
  4664. mdh = fih = foh = null;
  4665. body = null; // prevent memory leak (apparent circular reference via closure)
  4666. }
  4667. };
  4668. }
  4669. },
  4670. _onBlurNode: function(/*DomNode*/ node){
  4671. // summary:
  4672. // Called when focus leaves a node.
  4673. // Usually ignored, _unless_ it *isn't* followed by touching another node,
  4674. // which indicates that we tabbed off the last field on the page,
  4675. // in which case every widget is marked inactive
  4676. // If the blur event isn't followed by a focus event, it means the user clicked on something unfocusable,
  4677. // so clear focus.
  4678. if(this._clearFocusTimer){
  4679. clearTimeout(this._clearFocusTimer);
  4680. }
  4681. this._clearFocusTimer = setTimeout(lang.hitch(this, function(){
  4682. this.set("prevNode", this.curNode);
  4683. this.set("curNode", null);
  4684. }), 0);
  4685. if(this._justMouseDowned){
  4686. // the mouse down caused a new widget to be marked as active; this blur event
  4687. // is coming late, so ignore it.
  4688. return;
  4689. }
  4690. // If the blur event isn't followed by a focus or touch event then mark all widgets as inactive.
  4691. if(this._clearActiveWidgetsTimer){
  4692. clearTimeout(this._clearActiveWidgetsTimer);
  4693. }
  4694. this._clearActiveWidgetsTimer = setTimeout(lang.hitch(this, function(){
  4695. delete this._clearActiveWidgetsTimer;
  4696. this._setStack([]);
  4697. }), 100);
  4698. },
  4699. _onTouchNode: function(/*DomNode*/ node, /*String*/ by){
  4700. // summary:
  4701. // Callback when node is focused or mouse-downed
  4702. // node:
  4703. // The node that was touched.
  4704. // by:
  4705. // "mouse" if the focus/touch was caused by a mouse down event
  4706. // ignore the recent blurNode event
  4707. if(this._clearActiveWidgetsTimer){
  4708. clearTimeout(this._clearActiveWidgetsTimer);
  4709. delete this._clearActiveWidgetsTimer;
  4710. }
  4711. // compute stack of active widgets (ex: ComboButton --> Menu --> MenuItem)
  4712. var newStack=[];
  4713. try{
  4714. while(node){
  4715. var popupParent = domAttr.get(node, "dijitPopupParent");
  4716. if(popupParent){
  4717. node=registry.byId(popupParent).domNode;
  4718. }else if(node.tagName && node.tagName.toLowerCase() == "body"){
  4719. // is this the root of the document or just the root of an iframe?
  4720. if(node === win.body()){
  4721. // node is the root of the main document
  4722. break;
  4723. }
  4724. // otherwise, find the iframe this node refers to (can't access it via parentNode,
  4725. // need to do this trick instead). window.frameElement is supported in IE/FF/Webkit
  4726. node=winUtils.get(node.ownerDocument).frameElement;
  4727. }else{
  4728. // if this node is the root node of a widget, then add widget id to stack,
  4729. // except ignore clicks on disabled widgets (actually focusing a disabled widget still works,
  4730. // to support MenuItem)
  4731. var id = node.getAttribute && node.getAttribute("widgetId"),
  4732. widget = id && registry.byId(id);
  4733. if(widget && !(by == "mouse" && widget.get("disabled"))){
  4734. newStack.unshift(id);
  4735. }
  4736. node=node.parentNode;
  4737. }
  4738. }
  4739. }catch(e){ /* squelch */ }
  4740. this._setStack(newStack, by);
  4741. },
  4742. _onFocusNode: function(/*DomNode*/ node){
  4743. // summary:
  4744. // Callback when node is focused
  4745. if(!node){
  4746. return;
  4747. }
  4748. if(node.nodeType == 9){
  4749. // Ignore focus events on the document itself. This is here so that
  4750. // (for example) clicking the up/down arrows of a spinner
  4751. // (which don't get focus) won't cause that widget to blur. (FF issue)
  4752. return;
  4753. }
  4754. // There was probably a blur event right before this event, but since we have a new focus, don't
  4755. // do anything with the blur
  4756. if(this._clearFocusTimer){
  4757. clearTimeout(this._clearFocusTimer);
  4758. delete this._clearFocusTimer;
  4759. }
  4760. this._onTouchNode(node);
  4761. if(node == this.curNode){ return; }
  4762. this.set("prevNode", this.curNode);
  4763. this.set("curNode", node);
  4764. },
  4765. _setStack: function(/*String[]*/ newStack, /*String*/ by){
  4766. // summary:
  4767. // The stack of active widgets has changed. Send out appropriate events and records new stack.
  4768. // newStack:
  4769. // array of widget id's, starting from the top (outermost) widget
  4770. // by:
  4771. // "mouse" if the focus/touch was caused by a mouse down event
  4772. var oldStack = this.activeStack, lastOldIdx = oldStack.length - 1, lastNewIdx = newStack.length - 1;
  4773. if(newStack[lastNewIdx] == oldStack[lastOldIdx]){
  4774. // no changes, return now to avoid spurious notifications about changes to activeStack
  4775. return;
  4776. }
  4777. this.set("activeStack", newStack);
  4778. var widget, i;
  4779. // for all elements that have gone out of focus, set focused=false
  4780. for(i = lastOldIdx; i >= 0 && oldStack[i] != newStack[i]; i--){
  4781. widget = registry.byId(oldStack[i]);
  4782. if(widget){
  4783. widget._hasBeenBlurred = true; // TODO: used by form widgets, should be moved there
  4784. widget.set("focused", false);
  4785. if(widget._focusManager == this){
  4786. widget._onBlur(by);
  4787. }
  4788. this.emit("widget-blur", widget, by);
  4789. }
  4790. }
  4791. // for all element that have come into focus, set focused=true
  4792. for(i++; i <= lastNewIdx; i++){
  4793. widget = registry.byId(newStack[i]);
  4794. if(widget){
  4795. widget.set("focused", true);
  4796. if(widget._focusManager == this){
  4797. widget._onFocus(by);
  4798. }
  4799. this.emit("widget-focus", widget, by);
  4800. }
  4801. }
  4802. },
  4803. focus: function(node){
  4804. // summary:
  4805. // Focus the specified node, suppressing errors if they occur
  4806. if(node){
  4807. try{ node.focus(); }catch(e){/*quiet*/}
  4808. }
  4809. }
  4810. });
  4811. var singleton = new FocusManager();
  4812. // register top window and all the iframes it contains
  4813. domReady(function(){
  4814. var handle = singleton.registerWin(winUtils.get(document));
  4815. if(has("ie")){
  4816. on(window, "unload", function(){
  4817. if(handle){ // because this gets called twice when doh.robot is running
  4818. handle.remove();
  4819. handle = null;
  4820. }
  4821. });
  4822. }
  4823. });
  4824. // Setup dijit.focus as a pointer to the singleton but also (for backwards compatibility)
  4825. // as a function to set focus. Remove for 2.0.
  4826. dijit.focus = function(node){
  4827. singleton.focus(node); // indirection here allows dijit/_base/focus.js to override behavior
  4828. };
  4829. for(var attr in singleton){
  4830. if(!/^_/.test(attr)){
  4831. dijit.focus[attr] = typeof singleton[attr] == "function" ? lang.hitch(singleton, attr) : singleton[attr];
  4832. }
  4833. }
  4834. singleton.watch(function(attr, oldVal, newVal){
  4835. dijit.focus[attr] = newVal;
  4836. });
  4837. return singleton;
  4838. });
  4839. },
  4840. 'dijit/_base/sniff':function(){
  4841. define("dijit/_base/sniff", [ "dojo/uacss" ], function(){
  4842. // module:
  4843. // dijit/_base/sniff
  4844. // summary:
  4845. // Back compatibility module, new code should require dojo/uacss directly instead of this module.
  4846. });
  4847. },
  4848. 'dijit/main':function(){
  4849. define("dijit/main", [
  4850. "dojo/_base/kernel"
  4851. ], function(dojo){
  4852. // module:
  4853. // dijit
  4854. // summary:
  4855. // The dijit package main module
  4856. return dojo.dijit;
  4857. });
  4858. },
  4859. 'dojo/date/stamp':function(){
  4860. define(["../_base/kernel", "../_base/lang", "../_base/array"], function(dojo, lang, array) {
  4861. // module:
  4862. // dojo/date/stamp
  4863. // summary:
  4864. // TODOC
  4865. lang.getObject("date.stamp", true, dojo);
  4866. // Methods to convert dates to or from a wire (string) format using well-known conventions
  4867. dojo.date.stamp.fromISOString = function(/*String*/formattedString, /*Number?*/defaultTime){
  4868. // summary:
  4869. // Returns a Date object given a string formatted according to a subset of the ISO-8601 standard.
  4870. //
  4871. // description:
  4872. // Accepts a string formatted according to a profile of ISO8601 as defined by
  4873. // [RFC3339](http://www.ietf.org/rfc/rfc3339.txt), except that partial input is allowed.
  4874. // Can also process dates as specified [by the W3C](http://www.w3.org/TR/NOTE-datetime)
  4875. // The following combinations are valid:
  4876. //
  4877. // * dates only
  4878. // | * yyyy
  4879. // | * yyyy-MM
  4880. // | * yyyy-MM-dd
  4881. // * times only, with an optional time zone appended
  4882. // | * THH:mm
  4883. // | * THH:mm:ss
  4884. // | * THH:mm:ss.SSS
  4885. // * and "datetimes" which could be any combination of the above
  4886. //
  4887. // timezones may be specified as Z (for UTC) or +/- followed by a time expression HH:mm
  4888. // Assumes the local time zone if not specified. Does not validate. Improperly formatted
  4889. // input may return null. Arguments which are out of bounds will be handled
  4890. // by the Date constructor (e.g. January 32nd typically gets resolved to February 1st)
  4891. // Only years between 100 and 9999 are supported.
  4892. //
  4893. // formattedString:
  4894. // A string such as 2005-06-30T08:05:00-07:00 or 2005-06-30 or T08:05:00
  4895. //
  4896. // defaultTime:
  4897. // Used for defaults for fields omitted in the formattedString.
  4898. // Uses 1970-01-01T00:00:00.0Z by default.
  4899. if(!dojo.date.stamp._isoRegExp){
  4900. dojo.date.stamp._isoRegExp =
  4901. //TODO: could be more restrictive and check for 00-59, etc.
  4902. /^(?:(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(.\d+)?)?((?:[+-](\d{2}):(\d{2}))|Z)?)?$/;
  4903. }
  4904. var match = dojo.date.stamp._isoRegExp.exec(formattedString),
  4905. result = null;
  4906. if(match){
  4907. match.shift();
  4908. if(match[1]){match[1]--;} // Javascript Date months are 0-based
  4909. if(match[6]){match[6] *= 1000;} // Javascript Date expects fractional seconds as milliseconds
  4910. if(defaultTime){
  4911. // mix in defaultTime. Relatively expensive, so use || operators for the fast path of defaultTime === 0
  4912. defaultTime = new Date(defaultTime);
  4913. array.forEach(array.map(["FullYear", "Month", "Date", "Hours", "Minutes", "Seconds", "Milliseconds"], function(prop){
  4914. return defaultTime["get" + prop]();
  4915. }), function(value, index){
  4916. match[index] = match[index] || value;
  4917. });
  4918. }
  4919. result = new Date(match[0]||1970, match[1]||0, match[2]||1, match[3]||0, match[4]||0, match[5]||0, match[6]||0); //TODO: UTC defaults
  4920. if(match[0] < 100){
  4921. result.setFullYear(match[0] || 1970);
  4922. }
  4923. var offset = 0,
  4924. zoneSign = match[7] && match[7].charAt(0);
  4925. if(zoneSign != 'Z'){
  4926. offset = ((match[8] || 0) * 60) + (Number(match[9]) || 0);
  4927. if(zoneSign != '-'){ offset *= -1; }
  4928. }
  4929. if(zoneSign){
  4930. offset -= result.getTimezoneOffset();
  4931. }
  4932. if(offset){
  4933. result.setTime(result.getTime() + offset * 60000);
  4934. }
  4935. }
  4936. return result; // Date or null
  4937. };
  4938. /*=====
  4939. dojo.date.stamp.__Options = function(){
  4940. // selector: String
  4941. // "date" or "time" for partial formatting of the Date object.
  4942. // Both date and time will be formatted by default.
  4943. // zulu: Boolean
  4944. // if true, UTC/GMT is used for a timezone
  4945. // milliseconds: Boolean
  4946. // if true, output milliseconds
  4947. this.selector = selector;
  4948. this.zulu = zulu;
  4949. this.milliseconds = milliseconds;
  4950. }
  4951. =====*/
  4952. dojo.date.stamp.toISOString = function(/*Date*/dateObject, /*dojo.date.stamp.__Options?*/options){
  4953. // summary:
  4954. // Format a Date object as a string according a subset of the ISO-8601 standard
  4955. //
  4956. // description:
  4957. // When options.selector is omitted, output follows [RFC3339](http://www.ietf.org/rfc/rfc3339.txt)
  4958. // The local time zone is included as an offset from GMT, except when selector=='time' (time without a date)
  4959. // Does not check bounds. Only years between 100 and 9999 are supported.
  4960. //
  4961. // dateObject:
  4962. // A Date object
  4963. var _ = function(n){ return (n < 10) ? "0" + n : n; };
  4964. options = options || {};
  4965. var formattedDate = [],
  4966. getter = options.zulu ? "getUTC" : "get",
  4967. date = "";
  4968. if(options.selector != "time"){
  4969. var year = dateObject[getter+"FullYear"]();
  4970. date = ["0000".substr((year+"").length)+year, _(dateObject[getter+"Month"]()+1), _(dateObject[getter+"Date"]())].join('-');
  4971. }
  4972. formattedDate.push(date);
  4973. if(options.selector != "date"){
  4974. var time = [_(dateObject[getter+"Hours"]()), _(dateObject[getter+"Minutes"]()), _(dateObject[getter+"Seconds"]())].join(':');
  4975. var millis = dateObject[getter+"Milliseconds"]();
  4976. if(options.milliseconds){
  4977. time += "."+ (millis < 100 ? "0" : "") + _(millis);
  4978. }
  4979. if(options.zulu){
  4980. time += "Z";
  4981. }else if(options.selector != "time"){
  4982. var timezoneOffset = dateObject.getTimezoneOffset();
  4983. var absOffset = Math.abs(timezoneOffset);
  4984. time += (timezoneOffset > 0 ? "-" : "+") +
  4985. _(Math.floor(absOffset/60)) + ":" + _(absOffset%60);
  4986. }
  4987. formattedDate.push(time);
  4988. }
  4989. return formattedDate.join('T'); // String
  4990. };
  4991. return dojo.date.stamp;
  4992. });
  4993. },
  4994. 'dijit/form/_FormWidget':function(){
  4995. define("dijit/form/_FormWidget", [
  4996. "dojo/_base/declare", // declare
  4997. "dojo/_base/kernel", // kernel.deprecated
  4998. "dojo/ready",
  4999. "../_Widget",
  5000. "../_CssStateMixin",
  5001. "../_TemplatedMixin",
  5002. "./_FormWidgetMixin"
  5003. ], function(declare, kernel, ready, _Widget, _CssStateMixin, _TemplatedMixin, _FormWidgetMixin){
  5004. /*=====
  5005. var _Widget = dijit._Widget;
  5006. var _TemplatedMixin = dijit._TemplatedMixin;
  5007. var _CssStateMixin = dijit._CssStateMixin;
  5008. var _FormWidgetMixin = dijit.form._FormWidgetMixin;
  5009. =====*/
  5010. // module:
  5011. // dijit/form/_FormWidget
  5012. // summary:
  5013. // FormWidget
  5014. // Back compat w/1.6, remove for 2.0
  5015. if(!kernel.isAsync){
  5016. ready(0, function(){
  5017. var requires = ["dijit/form/_FormValueWidget"];
  5018. require(requires); // use indirection so modules not rolled into a build
  5019. });
  5020. }
  5021. return declare("dijit.form._FormWidget", [_Widget, _TemplatedMixin, _CssStateMixin, _FormWidgetMixin], {
  5022. // summary:
  5023. // Base class for widgets corresponding to native HTML elements such as <checkbox> or <button>,
  5024. // which can be children of a <form> node or a `dijit.form.Form` widget.
  5025. //
  5026. // description:
  5027. // Represents a single HTML element.
  5028. // All these widgets should have these attributes just like native HTML input elements.
  5029. // You can set them during widget construction or afterwards, via `dijit._Widget.attr`.
  5030. //
  5031. // They also share some common methods.
  5032. setDisabled: function(/*Boolean*/ disabled){
  5033. // summary:
  5034. // Deprecated. Use set('disabled', ...) instead.
  5035. kernel.deprecated("setDisabled("+disabled+") is deprecated. Use set('disabled',"+disabled+") instead.", "", "2.0");
  5036. this.set('disabled', disabled);
  5037. },
  5038. setValue: function(/*String*/ value){
  5039. // summary:
  5040. // Deprecated. Use set('value', ...) instead.
  5041. kernel.deprecated("dijit.form._FormWidget:setValue("+value+") is deprecated. Use set('value',"+value+") instead.", "", "2.0");
  5042. this.set('value', value);
  5043. },
  5044. getValue: function(){
  5045. // summary:
  5046. // Deprecated. Use get('value') instead.
  5047. kernel.deprecated(this.declaredClass+"::getValue() is deprecated. Use get('value') instead.", "", "2.0");
  5048. return this.get('value');
  5049. },
  5050. postMixInProperties: function(){
  5051. // Setup name=foo string to be referenced from the template (but only if a name has been specified)
  5052. // Unfortunately we can't use _setNameAttr to set the name due to IE limitations, see #8484, #8660.
  5053. // Regarding escaping, see heading "Attribute values" in
  5054. // http://www.w3.org/TR/REC-html40/appendix/notes.html#h-B.3.2
  5055. this.nameAttrSetting = this.name ? ('name="' + this.name.replace(/'/g, "&quot;") + '"') : '';
  5056. this.inherited(arguments);
  5057. },
  5058. // Override automatic assigning type --> focusNode, it causes exception on IE.
  5059. // Instead, type must be specified as ${type} in the template, as part of the original DOM
  5060. _setTypeAttr: null
  5061. });
  5062. });
  5063. },
  5064. 'dijit/_base/typematic':function(){
  5065. define(["../typematic"], function(){
  5066. // for back-compat, just loads top level module
  5067. });
  5068. },
  5069. 'dijit/_base/popup':function(){
  5070. define("dijit/_base/popup", [
  5071. "dojo/dom-class", // domClass.contains
  5072. "../popup",
  5073. "../BackgroundIframe" // just loading for back-compat, in case client code is referencing it
  5074. ], function(domClass, popup){
  5075. // module:
  5076. // dijit/_base/popup
  5077. // summary:
  5078. // Old module for popups, new code should use dijit/popup directly
  5079. // Hack support for old API passing in node instead of a widget (to various methods)
  5080. var origCreateWrapper = popup._createWrapper;
  5081. popup._createWrapper = function(widget){
  5082. if(!widget.declaredClass){
  5083. // make fake widget to pass to new API
  5084. widget = {
  5085. _popupWrapper: (widget.parentNode && domClass.contains(widget.parentNode, "dijitPopup")) ?
  5086. widget.parentNode : null,
  5087. domNode: widget,
  5088. destroy: function(){}
  5089. };
  5090. }
  5091. return origCreateWrapper.call(this, widget);
  5092. };
  5093. // Support old format of orient parameter
  5094. var origOpen = popup.open;
  5095. popup.open = function(/*dijit.popup.__OpenArgs*/ args){
  5096. // Convert old hash structure (ex: {"BL": "TL", ...}) of orient to format compatible w/new popup.open() API.
  5097. // Don't do conversion for:
  5098. // - null parameter (that means to use the default positioning)
  5099. // - "R" or "L" strings used to indicate positioning for context menus (when there is no around node)
  5100. // - new format, ex: ["below", "above"]
  5101. // - return value from deprecated dijit.getPopupAroundAlignment() method,
  5102. // ex: ["below", "above"]
  5103. if(args.orient && typeof args.orient != "string" && !("length" in args.orient)){
  5104. var ary = [];
  5105. for(var key in args.orient){
  5106. ary.push({aroundCorner: key, corner: args.orient[key]});
  5107. }
  5108. args.orient = ary;
  5109. }
  5110. return origOpen.call(this, args);
  5111. };
  5112. return popup;
  5113. });
  5114. },
  5115. 'dijit/_TemplatedMixin':function(){
  5116. define("dijit/_TemplatedMixin", [
  5117. "dojo/_base/lang", // lang.getObject
  5118. "dojo/touch",
  5119. "./_WidgetBase",
  5120. "dojo/string", // string.substitute string.trim
  5121. "dojo/cache", // dojo.cache
  5122. "dojo/_base/array", // array.forEach
  5123. "dojo/_base/declare", // declare
  5124. "dojo/dom-construct", // domConstruct.destroy, domConstruct.toDom
  5125. "dojo/_base/sniff", // has("ie")
  5126. "dojo/_base/unload", // unload.addOnWindowUnload
  5127. "dojo/_base/window" // win.doc
  5128. ], function(lang, touch, _WidgetBase, string, cache, array, declare, domConstruct, has, unload, win) {
  5129. /*=====
  5130. var _WidgetBase = dijit._WidgetBase;
  5131. =====*/
  5132. // module:
  5133. // dijit/_TemplatedMixin
  5134. // summary:
  5135. // Mixin for widgets that are instantiated from a template
  5136. var _TemplatedMixin = declare("dijit._TemplatedMixin", null, {
  5137. // summary:
  5138. // Mixin for widgets that are instantiated from a template
  5139. // templateString: [protected] String
  5140. // A string that represents the widget template.
  5141. // Use in conjunction with dojo.cache() to load from a file.
  5142. templateString: null,
  5143. // templatePath: [protected deprecated] String
  5144. // Path to template (HTML file) for this widget relative to dojo.baseUrl.
  5145. // Deprecated: use templateString with require([... "dojo/text!..."], ...) instead
  5146. templatePath: null,
  5147. // skipNodeCache: [protected] Boolean
  5148. // If using a cached widget template nodes poses issues for a
  5149. // particular widget class, it can set this property to ensure
  5150. // that its template is always re-built from a string
  5151. _skipNodeCache: false,
  5152. // _earlyTemplatedStartup: Boolean
  5153. // A fallback to preserve the 1.0 - 1.3 behavior of children in
  5154. // templates having their startup called before the parent widget
  5155. // fires postCreate. Defaults to 'false', causing child widgets to
  5156. // have their .startup() called immediately before a parent widget
  5157. // .startup(), but always after the parent .postCreate(). Set to
  5158. // 'true' to re-enable to previous, arguably broken, behavior.
  5159. _earlyTemplatedStartup: false,
  5160. /*=====
  5161. // _attachPoints: [private] String[]
  5162. // List of widget attribute names associated with data-dojo-attach-point=... in the
  5163. // template, ex: ["containerNode", "labelNode"]
  5164. _attachPoints: [],
  5165. =====*/
  5166. /*=====
  5167. // _attachEvents: [private] Handle[]
  5168. // List of connections associated with data-dojo-attach-event=... in the
  5169. // template
  5170. _attachEvents: [],
  5171. =====*/
  5172. constructor: function(){
  5173. this._attachPoints = [];
  5174. this._attachEvents = [];
  5175. },
  5176. _stringRepl: function(tmpl){
  5177. // summary:
  5178. // Does substitution of ${foo} type properties in template string
  5179. // tags:
  5180. // private
  5181. var className = this.declaredClass, _this = this;
  5182. // Cache contains a string because we need to do property replacement
  5183. // do the property replacement
  5184. return string.substitute(tmpl, this, function(value, key){
  5185. if(key.charAt(0) == '!'){ value = lang.getObject(key.substr(1), false, _this); }
  5186. if(typeof value == "undefined"){ throw new Error(className+" template:"+key); } // a debugging aide
  5187. if(value == null){ return ""; }
  5188. // Substitution keys beginning with ! will skip the transform step,
  5189. // in case a user wishes to insert unescaped markup, e.g. ${!foo}
  5190. return key.charAt(0) == "!" ? value :
  5191. // Safer substitution, see heading "Attribute values" in
  5192. // http://www.w3.org/TR/REC-html40/appendix/notes.html#h-B.3.2
  5193. value.toString().replace(/"/g,"&quot;"); //TODO: add &amp? use encodeXML method?
  5194. }, this);
  5195. },
  5196. buildRendering: function(){
  5197. // summary:
  5198. // Construct the UI for this widget from a template, setting this.domNode.
  5199. // tags:
  5200. // protected
  5201. if(!this.templateString){
  5202. this.templateString = cache(this.templatePath, {sanitize: true});
  5203. }
  5204. // Lookup cached version of template, and download to cache if it
  5205. // isn't there already. Returns either a DomNode or a string, depending on
  5206. // whether or not the template contains ${foo} replacement parameters.
  5207. var cached = _TemplatedMixin.getCachedTemplate(this.templateString, this._skipNodeCache);
  5208. var node;
  5209. if(lang.isString(cached)){
  5210. node = domConstruct.toDom(this._stringRepl(cached));
  5211. if(node.nodeType != 1){
  5212. // Flag common problems such as templates with multiple top level nodes (nodeType == 11)
  5213. throw new Error("Invalid template: " + cached);
  5214. }
  5215. }else{
  5216. // if it's a node, all we have to do is clone it
  5217. node = cached.cloneNode(true);
  5218. }
  5219. this.domNode = node;
  5220. // Call down to _Widget.buildRendering() to get base classes assigned
  5221. // TODO: change the baseClass assignment to _setBaseClassAttr
  5222. this.inherited(arguments);
  5223. // recurse through the node, looking for, and attaching to, our
  5224. // attachment points and events, which should be defined on the template node.
  5225. this._attachTemplateNodes(node, function(n,p){ return n.getAttribute(p); });
  5226. this._beforeFillContent(); // hook for _WidgetsInTemplateMixin
  5227. this._fillContent(this.srcNodeRef);
  5228. },
  5229. _beforeFillContent: function(){
  5230. },
  5231. _fillContent: function(/*DomNode*/ source){
  5232. // summary:
  5233. // Relocate source contents to templated container node.
  5234. // this.containerNode must be able to receive children, or exceptions will be thrown.
  5235. // tags:
  5236. // protected
  5237. var dest = this.containerNode;
  5238. if(source && dest){
  5239. while(source.hasChildNodes()){
  5240. dest.appendChild(source.firstChild);
  5241. }
  5242. }
  5243. },
  5244. _attachTemplateNodes: function(rootNode, getAttrFunc){
  5245. // summary:
  5246. // Iterate through the template and attach functions and nodes accordingly.
  5247. // Alternately, if rootNode is an array of widgets, then will process data-dojo-attach-point
  5248. // etc. for those widgets.
  5249. // description:
  5250. // Map widget properties and functions to the handlers specified in
  5251. // the dom node and it's descendants. This function iterates over all
  5252. // nodes and looks for these properties:
  5253. // * dojoAttachPoint/data-dojo-attach-point
  5254. // * dojoAttachEvent/data-dojo-attach-event
  5255. // rootNode: DomNode|Widget[]
  5256. // the node to search for properties. All children will be searched.
  5257. // getAttrFunc: Function
  5258. // a function which will be used to obtain property for a given
  5259. // DomNode/Widget
  5260. // tags:
  5261. // private
  5262. var nodes = lang.isArray(rootNode) ? rootNode : (rootNode.all || rootNode.getElementsByTagName("*"));
  5263. var x = lang.isArray(rootNode) ? 0 : -1;
  5264. for(; x<nodes.length; x++){
  5265. var baseNode = (x == -1) ? rootNode : nodes[x];
  5266. if(this.widgetsInTemplate && (getAttrFunc(baseNode, "dojoType") || getAttrFunc(baseNode, "data-dojo-type"))){
  5267. continue;
  5268. }
  5269. // Process data-dojo-attach-point
  5270. var attachPoint = getAttrFunc(baseNode, "dojoAttachPoint") || getAttrFunc(baseNode, "data-dojo-attach-point");
  5271. if(attachPoint){
  5272. var point, points = attachPoint.split(/\s*,\s*/);
  5273. while((point = points.shift())){
  5274. if(lang.isArray(this[point])){
  5275. this[point].push(baseNode);
  5276. }else{
  5277. this[point]=baseNode;
  5278. }
  5279. this._attachPoints.push(point);
  5280. }
  5281. }
  5282. // Process data-dojo-attach-event
  5283. var attachEvent = getAttrFunc(baseNode, "dojoAttachEvent") || getAttrFunc(baseNode, "data-dojo-attach-event");
  5284. if(attachEvent){
  5285. // NOTE: we want to support attributes that have the form
  5286. // "domEvent: nativeEvent; ..."
  5287. var event, events = attachEvent.split(/\s*,\s*/);
  5288. var trim = lang.trim;
  5289. while((event = events.shift())){
  5290. if(event){
  5291. var thisFunc = null;
  5292. if(event.indexOf(":") != -1){
  5293. // oh, if only JS had tuple assignment
  5294. var funcNameArr = event.split(":");
  5295. event = trim(funcNameArr[0]);
  5296. thisFunc = trim(funcNameArr[1]);
  5297. }else{
  5298. event = trim(event);
  5299. }
  5300. if(!thisFunc){
  5301. thisFunc = event;
  5302. }
  5303. // Map "press", "move" and "release" to keys.touch, keys.move, keys.release
  5304. this._attachEvents.push(this.connect(baseNode, touch[event] || event, thisFunc));
  5305. }
  5306. }
  5307. }
  5308. }
  5309. },
  5310. destroyRendering: function(){
  5311. // Delete all attach points to prevent IE6 memory leaks.
  5312. array.forEach(this._attachPoints, function(point){
  5313. delete this[point];
  5314. }, this);
  5315. this._attachPoints = [];
  5316. // And same for event handlers
  5317. array.forEach(this._attachEvents, this.disconnect, this);
  5318. this._attachEvents = [];
  5319. this.inherited(arguments);
  5320. }
  5321. });
  5322. // key is templateString; object is either string or DOM tree
  5323. _TemplatedMixin._templateCache = {};
  5324. _TemplatedMixin.getCachedTemplate = function(templateString, alwaysUseString){
  5325. // summary:
  5326. // Static method to get a template based on the templatePath or
  5327. // templateString key
  5328. // templateString: String
  5329. // The template
  5330. // alwaysUseString: Boolean
  5331. // Don't cache the DOM tree for this template, even if it doesn't have any variables
  5332. // returns: Mixed
  5333. // Either string (if there are ${} variables that need to be replaced) or just
  5334. // a DOM tree (if the node can be cloned directly)
  5335. // is it already cached?
  5336. var tmplts = _TemplatedMixin._templateCache;
  5337. var key = templateString;
  5338. var cached = tmplts[key];
  5339. if(cached){
  5340. try{
  5341. // if the cached value is an innerHTML string (no ownerDocument) or a DOM tree created within the current document, then use the current cached value
  5342. if(!cached.ownerDocument || cached.ownerDocument == win.doc){
  5343. // string or node of the same document
  5344. return cached;
  5345. }
  5346. }catch(e){ /* squelch */ } // IE can throw an exception if cached.ownerDocument was reloaded
  5347. domConstruct.destroy(cached);
  5348. }
  5349. templateString = string.trim(templateString);
  5350. if(alwaysUseString || templateString.match(/\$\{([^\}]+)\}/g)){
  5351. // there are variables in the template so all we can do is cache the string
  5352. return (tmplts[key] = templateString); //String
  5353. }else{
  5354. // there are no variables in the template so we can cache the DOM tree
  5355. var node = domConstruct.toDom(templateString);
  5356. if(node.nodeType != 1){
  5357. throw new Error("Invalid template: " + templateString);
  5358. }
  5359. return (tmplts[key] = node); //Node
  5360. }
  5361. };
  5362. if(has("ie")){
  5363. unload.addOnWindowUnload(function(){
  5364. var cache = _TemplatedMixin._templateCache;
  5365. for(var key in cache){
  5366. var value = cache[key];
  5367. if(typeof value == "object"){ // value is either a string or a DOM node template
  5368. domConstruct.destroy(value);
  5369. }
  5370. delete cache[key];
  5371. }
  5372. });
  5373. }
  5374. // These arguments can be specified for widgets which are used in templates.
  5375. // Since any widget can be specified as sub widgets in template, mix it
  5376. // into the base widget class. (This is a hack, but it's effective.)
  5377. lang.extend(_WidgetBase,{
  5378. dojoAttachEvent: "",
  5379. dojoAttachPoint: ""
  5380. });
  5381. return _TemplatedMixin;
  5382. });
  5383. },
  5384. 'dijit/_base/wai':function(){
  5385. define("dijit/_base/wai", [
  5386. "dojo/dom-attr", // domAttr.attr
  5387. "dojo/_base/lang", // lang.mixin
  5388. "..", // export symbols to dijit
  5389. "../hccss" // not using this module directly, but loading it sets CSS flag on <html>
  5390. ], function(domAttr, lang, dijit){
  5391. // module:
  5392. // dijit/_base/wai
  5393. // summary:
  5394. // Deprecated methods for setting/getting wai roles and states.
  5395. // New code should call setAttribute()/getAttribute() directly.
  5396. //
  5397. // Also loads hccss to apply dijit_a11y class to root node if machine is in high-contrast mode.
  5398. lang.mixin(dijit, {
  5399. hasWaiRole: function(/*Element*/ elem, /*String?*/ role){
  5400. // summary:
  5401. // Determines if an element has a particular role.
  5402. // returns:
  5403. // True if elem has the specific role attribute and false if not.
  5404. // For backwards compatibility if role parameter not provided,
  5405. // returns true if has a role
  5406. var waiRole = this.getWaiRole(elem);
  5407. return role ? (waiRole.indexOf(role) > -1) : (waiRole.length > 0);
  5408. },
  5409. getWaiRole: function(/*Element*/ elem){
  5410. // summary:
  5411. // Gets the role for an element (which should be a wai role).
  5412. // returns:
  5413. // The role of elem or an empty string if elem
  5414. // does not have a role.
  5415. return lang.trim((domAttr.get(elem, "role") || "").replace("wairole:",""));
  5416. },
  5417. setWaiRole: function(/*Element*/ elem, /*String*/ role){
  5418. // summary:
  5419. // Sets the role on an element.
  5420. // description:
  5421. // Replace existing role attribute with new role.
  5422. domAttr.set(elem, "role", role);
  5423. },
  5424. removeWaiRole: function(/*Element*/ elem, /*String*/ role){
  5425. // summary:
  5426. // Removes the specified role from an element.
  5427. // Removes role attribute if no specific role provided (for backwards compat.)
  5428. var roleValue = domAttr.get(elem, "role");
  5429. if(!roleValue){ return; }
  5430. if(role){
  5431. var t = lang.trim((" " + roleValue + " ").replace(" " + role + " ", " "));
  5432. domAttr.set(elem, "role", t);
  5433. }else{
  5434. elem.removeAttribute("role");
  5435. }
  5436. },
  5437. hasWaiState: function(/*Element*/ elem, /*String*/ state){
  5438. // summary:
  5439. // Determines if an element has a given state.
  5440. // description:
  5441. // Checks for an attribute called "aria-"+state.
  5442. // returns:
  5443. // true if elem has a value for the given state and
  5444. // false if it does not.
  5445. return elem.hasAttribute ? elem.hasAttribute("aria-"+state) : !!elem.getAttribute("aria-"+state);
  5446. },
  5447. getWaiState: function(/*Element*/ elem, /*String*/ state){
  5448. // summary:
  5449. // Gets the value of a state on an element.
  5450. // description:
  5451. // Checks for an attribute called "aria-"+state.
  5452. // returns:
  5453. // The value of the requested state on elem
  5454. // or an empty string if elem has no value for state.
  5455. return elem.getAttribute("aria-"+state) || "";
  5456. },
  5457. setWaiState: function(/*Element*/ elem, /*String*/ state, /*String*/ value){
  5458. // summary:
  5459. // Sets a state on an element.
  5460. // description:
  5461. // Sets an attribute called "aria-"+state.
  5462. elem.setAttribute("aria-"+state, value);
  5463. },
  5464. removeWaiState: function(/*Element*/ elem, /*String*/ state){
  5465. // summary:
  5466. // Removes a state from an element.
  5467. // description:
  5468. // Sets an attribute called "aria-"+state.
  5469. elem.removeAttribute("aria-"+state);
  5470. }
  5471. });
  5472. return dijit;
  5473. });
  5474. },
  5475. 'dojo/window':function(){
  5476. define(["./_base/lang", "./_base/sniff", "./_base/window", "./dom", "./dom-geometry", "./dom-style", "./dom-construct"],
  5477. function(lang, has, baseWindow, dom, geom, style, domConstruct) {
  5478. // feature detection
  5479. /* not needed but included here for future reference
  5480. has.add("rtl-innerVerticalScrollBar-on-left", function(win, doc){
  5481. var body = baseWindow.body(doc),
  5482. scrollable = domConstruct.create('div', {
  5483. style: {overflow:'scroll', overflowX:'hidden', direction:'rtl', visibility:'hidden', position:'absolute', left:'0', width:'64px', height:'64px'}
  5484. }, body, "last"),
  5485. center = domConstruct.create('center', {
  5486. style: {overflow:'hidden', direction:'ltr'}
  5487. }, scrollable, "last"),
  5488. inner = domConstruct.create('div', {
  5489. style: {overflow:'visible', display:'inline' }
  5490. }, center, "last");
  5491. inner.innerHTML="&nbsp;";
  5492. var midPoint = Math.max(inner.offsetLeft, geom.position(inner).x);
  5493. var ret = midPoint >= 32;
  5494. center.removeChild(inner);
  5495. scrollable.removeChild(center);
  5496. body.removeChild(scrollable);
  5497. return ret;
  5498. });
  5499. */
  5500. has.add("rtl-adjust-position-for-verticalScrollBar", function(win, doc){
  5501. var body = baseWindow.body(doc),
  5502. scrollable = domConstruct.create('div', {
  5503. style: {overflow:'scroll', overflowX:'visible', direction:'rtl', visibility:'hidden', position:'absolute', left:'0', top:'0', width:'64px', height:'64px'}
  5504. }, body, "last"),
  5505. div = domConstruct.create('div', {
  5506. style: {overflow:'hidden', direction:'ltr'}
  5507. }, scrollable, "last"),
  5508. ret = geom.position(div).x != 0;
  5509. scrollable.removeChild(div);
  5510. body.removeChild(scrollable);
  5511. return ret;
  5512. });
  5513. has.add("position-fixed-support", function(win, doc){
  5514. // IE6, IE7+quirks, and some older mobile browsers don't support position:fixed
  5515. var body = baseWindow.body(doc),
  5516. outer = domConstruct.create('span', {
  5517. style: {visibility:'hidden', position:'fixed', left:'1px', top:'1px'}
  5518. }, body, "last"),
  5519. inner = domConstruct.create('span', {
  5520. style: {position:'fixed', left:'0', top:'0'}
  5521. }, outer, "last"),
  5522. ret = geom.position(inner).x != geom.position(outer).x;
  5523. outer.removeChild(inner);
  5524. body.removeChild(outer);
  5525. return ret;
  5526. });
  5527. // module:
  5528. // dojo/window
  5529. // summary:
  5530. // TODOC
  5531. var window = lang.getObject("dojo.window", true);
  5532. /*=====
  5533. dojo.window = {
  5534. // summary:
  5535. // TODO
  5536. };
  5537. window = dojo.window;
  5538. =====*/
  5539. window.getBox = function(){
  5540. // summary:
  5541. // Returns the dimensions and scroll position of the viewable area of a browser window
  5542. var
  5543. scrollRoot = (baseWindow.doc.compatMode == 'BackCompat') ? baseWindow.body() : baseWindow.doc.documentElement,
  5544. // get scroll position
  5545. scroll = geom.docScroll(), // scrollRoot.scrollTop/Left should work
  5546. w, h;
  5547. if(has("touch")){ // if(scrollbars not supported)
  5548. var uiWindow = baseWindow.doc.parentWindow || baseWindow.doc.defaultView; // use UI window, not dojo.global window. baseWindow.doc.parentWindow probably not needed since it's not defined for webkit
  5549. // on mobile, scrollRoot.clientHeight <= uiWindow.innerHeight <= scrollRoot.offsetHeight, return uiWindow.innerHeight
  5550. w = uiWindow.innerWidth || scrollRoot.clientWidth; // || scrollRoot.clientXXX probably never evaluated
  5551. h = uiWindow.innerHeight || scrollRoot.clientHeight;
  5552. }else{
  5553. // on desktops, scrollRoot.clientHeight <= scrollRoot.offsetHeight <= uiWindow.innerHeight, return scrollRoot.clientHeight
  5554. // uiWindow.innerWidth/Height includes the scrollbar and cannot be used
  5555. w = scrollRoot.clientWidth;
  5556. h = scrollRoot.clientHeight;
  5557. }
  5558. return {
  5559. l: scroll.x,
  5560. t: scroll.y,
  5561. w: w,
  5562. h: h
  5563. };
  5564. };
  5565. window.get = function(doc){
  5566. // summary:
  5567. // Get window object associated with document doc
  5568. // In some IE versions (at least 6.0), document.parentWindow does not return a
  5569. // reference to the real window object (maybe a copy), so we must fix it as well
  5570. // We use IE specific execScript to attach the real window reference to
  5571. // document._parentWindow for later use
  5572. if(has("ie") < 9 && window !== document.parentWindow){
  5573. /*
  5574. In IE 6, only the variable "window" can be used to connect events (others
  5575. may be only copies).
  5576. */
  5577. doc.parentWindow.execScript("document._parentWindow = window;", "Javascript");
  5578. //to prevent memory leak, unset it after use
  5579. //another possibility is to add an onUnload handler which seems overkill to me (liucougar)
  5580. var win = doc._parentWindow;
  5581. doc._parentWindow = null;
  5582. return win; // Window
  5583. }
  5584. return doc.parentWindow || doc.defaultView; // Window
  5585. };
  5586. window.scrollIntoView = function(/*DomNode*/ node, /*Object?*/ pos){
  5587. // summary:
  5588. // Scroll the passed node into view using minimal movement, if it is not already.
  5589. // Don't rely on node.scrollIntoView working just because the function is there since
  5590. // it forces the node to the page's bottom or top (and left or right in IE) without consideration for the minimal movement.
  5591. // WebKit's node.scrollIntoViewIfNeeded doesn't work either for inner scrollbars in right-to-left mode
  5592. // and when there's a fixed position scrollable element
  5593. try{ // catch unexpected/unrecreatable errors (#7808) since we can recover using a semi-acceptable native method
  5594. node = dom.byId(node);
  5595. var doc = node.ownerDocument || baseWindow.doc, // TODO: why baseWindow.doc? Isn't node.ownerDocument always defined?
  5596. body = baseWindow.body(doc),
  5597. html = doc.documentElement || body.parentNode,
  5598. isIE = has("ie"),
  5599. isWK = has("webkit");
  5600. // if an untested browser, then use the native method
  5601. if(node == body || node == html){ return; }
  5602. if(!(has("mozilla") || isIE || isWK || has("opera") || has("trident")) && ("scrollIntoView" in node)){
  5603. node.scrollIntoView(false); // short-circuit to native if possible
  5604. return;
  5605. }
  5606. var backCompat = doc.compatMode == 'BackCompat',
  5607. rootWidth = Math.min(body.clientWidth || html.clientWidth, html.clientWidth || body.clientWidth),
  5608. rootHeight = Math.min(body.clientHeight || html.clientHeight, html.clientHeight || body.clientHeight),
  5609. scrollRoot = (isWK || backCompat) ? body : html,
  5610. nodePos = pos || geom.position(node),
  5611. el = node.parentNode,
  5612. isFixed = function(el){
  5613. return (isIE <= 6 || (isIE == 7 && backCompat))
  5614. ? false
  5615. : (has("position-fixed-support") && (style.get(el, 'position').toLowerCase() == "fixed"));
  5616. },
  5617. self = this,
  5618. scrollElementBy = function(el, x, y){
  5619. if(el.tagName == "BODY" || el.tagName == "HTML"){
  5620. self.get(el.ownerDocument).scrollBy(x, y);
  5621. }else{
  5622. x && (el.scrollLeft += x);
  5623. y && (el.scrollTop += y);
  5624. }
  5625. };
  5626. if(isFixed(node)){ return; } // nothing to do
  5627. while(el){
  5628. if(el == body){ el = scrollRoot; }
  5629. var elPos = geom.position(el),
  5630. fixedPos = isFixed(el),
  5631. rtl = style.getComputedStyle(el).direction.toLowerCase() == "rtl";
  5632. if(el == scrollRoot){
  5633. elPos.w = rootWidth; elPos.h = rootHeight;
  5634. if(scrollRoot == html && (isIE || has("trident")) && rtl){ elPos.x += scrollRoot.offsetWidth-elPos.w; } // IE workaround where scrollbar causes negative x
  5635. if(elPos.x < 0 || !isIE || isIE >= 9 || has("trident")){ elPos.x = 0; } // older IE can have values > 0
  5636. if(elPos.y < 0 || !isIE || isIE >= 9 || has("trident")){ elPos.y = 0; }
  5637. }else{
  5638. var pb = geom.getPadBorderExtents(el);
  5639. elPos.w -= pb.w; elPos.h -= pb.h; elPos.x += pb.l; elPos.y += pb.t;
  5640. var clientSize = el.clientWidth,
  5641. scrollBarSize = elPos.w - clientSize;
  5642. if(clientSize > 0 && scrollBarSize > 0){
  5643. if(rtl && has("rtl-adjust-position-for-verticalScrollBar")){
  5644. elPos.x += scrollBarSize;
  5645. }
  5646. elPos.w = clientSize;
  5647. }
  5648. clientSize = el.clientHeight;
  5649. scrollBarSize = elPos.h - clientSize;
  5650. if(clientSize > 0 && scrollBarSize > 0){
  5651. elPos.h = clientSize;
  5652. }
  5653. }
  5654. if(fixedPos){ // bounded by viewport, not parents
  5655. if(elPos.y < 0){
  5656. elPos.h += elPos.y; elPos.y = 0;
  5657. }
  5658. if(elPos.x < 0){
  5659. elPos.w += elPos.x; elPos.x = 0;
  5660. }
  5661. if(elPos.y + elPos.h > rootHeight){
  5662. elPos.h = rootHeight - elPos.y;
  5663. }
  5664. if(elPos.x + elPos.w > rootWidth){
  5665. elPos.w = rootWidth - elPos.x;
  5666. }
  5667. }
  5668. // calculate overflow in all 4 directions
  5669. var l = nodePos.x - elPos.x, // beyond left: < 0
  5670. // t = nodePos.y - Math.max(elPos.y, 0), // beyond top: < 0
  5671. t = nodePos.y - elPos.y, // beyond top: < 0
  5672. r = l + nodePos.w - elPos.w, // beyond right: > 0
  5673. bot = t + nodePos.h - elPos.h; // beyond bottom: > 0
  5674. var s, old;
  5675. if(r * l > 0 && (!!el.scrollLeft || el == scrollRoot || el.scrollWidth > el.offsetHeight)){
  5676. s = Math[l < 0? "max" : "min"](l, r);
  5677. if(rtl && ((isIE == 8 && !backCompat) || isIE >= 9 || has("trident"))){ s = -s; }
  5678. old = el.scrollLeft;
  5679. scrollElementBy(el, s, 0);
  5680. s = el.scrollLeft - old;
  5681. nodePos.x -= s;
  5682. }
  5683. if(bot * t > 0 && (!!el.scrollTop || el == scrollRoot || el.scrollHeight > el.offsetHeight)){
  5684. s = Math.ceil(Math[t < 0? "max" : "min"](t, bot));
  5685. old = el.scrollTop;
  5686. scrollElementBy(el, 0, s);
  5687. s = el.scrollTop - old;
  5688. nodePos.y -= s;
  5689. }
  5690. el = (el != scrollRoot) && !fixedPos && el.parentNode;
  5691. }
  5692. }catch(error){
  5693. console.error('scrollIntoView: ' + error);
  5694. node.scrollIntoView(false);
  5695. }
  5696. };
  5697. return window;
  5698. });
  5699. },
  5700. 'dijit/popup':function(){
  5701. define("dijit/popup", [
  5702. "dojo/_base/array", // array.forEach array.some
  5703. "dojo/aspect",
  5704. "dojo/_base/connect", // connect._keypress
  5705. "dojo/_base/declare", // declare
  5706. "dojo/dom", // dom.isDescendant
  5707. "dojo/dom-attr", // domAttr.set
  5708. "dojo/dom-construct", // domConstruct.create domConstruct.destroy
  5709. "dojo/dom-geometry", // domGeometry.isBodyLtr
  5710. "dojo/dom-style", // domStyle.set
  5711. "dojo/_base/event", // event.stop
  5712. "dojo/has",
  5713. "dojo/keys",
  5714. "dojo/_base/lang", // lang.hitch
  5715. "dojo/on",
  5716. "dojo/_base/window", // win.body
  5717. "./place",
  5718. "./BackgroundIframe",
  5719. "." // dijit (defining dijit.popup to match API doc)
  5720. ], function(array, aspect, connect, declare, dom, domAttr, domConstruct, domGeometry, domStyle, event, has, keys, lang, on, win,
  5721. place, BackgroundIframe, dijit){
  5722. // module:
  5723. // dijit/popup
  5724. // summary:
  5725. // Used to show drop downs (ex: the select list of a ComboBox)
  5726. // or popups (ex: right-click context menus)
  5727. /*=====
  5728. dijit.popup.__OpenArgs = function(){
  5729. // popup: Widget
  5730. // widget to display
  5731. // parent: Widget
  5732. // the button etc. that is displaying this popup
  5733. // around: DomNode
  5734. // DOM node (typically a button); place popup relative to this node. (Specify this *or* "x" and "y" parameters.)
  5735. // x: Integer
  5736. // Absolute horizontal position (in pixels) to place node at. (Specify this *or* "around" parameter.)
  5737. // y: Integer
  5738. // Absolute vertical position (in pixels) to place node at. (Specify this *or* "around" parameter.)
  5739. // orient: Object|String
  5740. // When the around parameter is specified, orient should be a list of positions to try, ex:
  5741. // | [ "below", "above" ]
  5742. // For backwards compatibility it can also be an (ordered) hash of tuples of the form
  5743. // (around-node-corner, popup-node-corner), ex:
  5744. // | { "BL": "TL", "TL": "BL" }
  5745. // where BL means "bottom left" and "TL" means "top left", etc.
  5746. //
  5747. // dijit.popup.open() tries to position the popup according to each specified position, in order,
  5748. // until the popup appears fully within the viewport.
  5749. //
  5750. // The default value is ["below", "above"]
  5751. //
  5752. // When an (x,y) position is specified rather than an around node, orient is either
  5753. // "R" or "L". R (for right) means that it tries to put the popup to the right of the mouse,
  5754. // specifically positioning the popup's top-right corner at the mouse position, and if that doesn't
  5755. // fit in the viewport, then it tries, in order, the bottom-right corner, the top left corner,
  5756. // and the top-right corner.
  5757. // onCancel: Function
  5758. // callback when user has canceled the popup by
  5759. // 1. hitting ESC or
  5760. // 2. by using the popup widget's proprietary cancel mechanism (like a cancel button in a dialog);
  5761. // i.e. whenever popupWidget.onCancel() is called, args.onCancel is called
  5762. // onClose: Function
  5763. // callback whenever this popup is closed
  5764. // onExecute: Function
  5765. // callback when user "executed" on the popup/sub-popup by selecting a menu choice, etc. (top menu only)
  5766. // padding: dijit.__Position
  5767. // adding a buffer around the opening position. This is only useful when around is not set.
  5768. this.popup = popup;
  5769. this.parent = parent;
  5770. this.around = around;
  5771. this.x = x;
  5772. this.y = y;
  5773. this.orient = orient;
  5774. this.onCancel = onCancel;
  5775. this.onClose = onClose;
  5776. this.onExecute = onExecute;
  5777. this.padding = padding;
  5778. }
  5779. =====*/
  5780. /*=====
  5781. dijit.popup = {
  5782. // summary:
  5783. // Used to show drop downs (ex: the select list of a ComboBox)
  5784. // or popups (ex: right-click context menus).
  5785. //
  5786. // Access via require(["dijit/popup"], function(popup){ ... }).
  5787. moveOffScreen: function(widget){
  5788. // summary:
  5789. // Moves the popup widget off-screen.
  5790. // Do not use this method to hide popups when not in use, because
  5791. // that will create an accessibility issue: the offscreen popup is
  5792. // still in the tabbing order.
  5793. // widget: dijit._WidgetBase
  5794. // The widget
  5795. },
  5796. hide: function(widget){
  5797. // summary:
  5798. // Hide this popup widget (until it is ready to be shown).
  5799. // Initialization for widgets that will be used as popups
  5800. //
  5801. // Also puts widget inside a wrapper DIV (if not already in one)
  5802. //
  5803. // If popup widget needs to layout it should
  5804. // do so when it is made visible, and popup._onShow() is called.
  5805. // widget: dijit._WidgetBase
  5806. // The widget
  5807. },
  5808. open: function(args){
  5809. // summary:
  5810. // Popup the widget at the specified position
  5811. // example:
  5812. // opening at the mouse position
  5813. // | popup.open({popup: menuWidget, x: evt.pageX, y: evt.pageY});
  5814. // example:
  5815. // opening the widget as a dropdown
  5816. // | popup.open({parent: this, popup: menuWidget, around: this.domNode, onClose: function(){...}});
  5817. //
  5818. // Note that whatever widget called dijit.popup.open() should also listen to its own _onBlur callback
  5819. // (fired from _base/focus.js) to know that focus has moved somewhere else and thus the popup should be closed.
  5820. // args: dijit.popup.__OpenArgs
  5821. // Parameters
  5822. return {}; // Object specifying which position was chosen
  5823. },
  5824. close: function(popup){
  5825. // summary:
  5826. // Close specified popup and any popups that it parented.
  5827. // If no popup is specified, closes all popups.
  5828. // widget: dijit._WidgetBase?
  5829. // The widget, optional
  5830. }
  5831. };
  5832. =====*/
  5833. function destroyWrapper(){
  5834. // summary:
  5835. // Function to destroy wrapper when popup widget is destroyed.
  5836. // Left in this scope to avoid memory leak on IE8 on refresh page, see #15206.
  5837. if(this._popupWrapper){
  5838. domConstruct.destroy(this._popupWrapper);
  5839. delete this._popupWrapper;
  5840. }
  5841. }
  5842. var PopupManager = declare(null, {
  5843. // _stack: dijit._Widget[]
  5844. // Stack of currently popped up widgets.
  5845. // (someone opened _stack[0], and then it opened _stack[1], etc.)
  5846. _stack: [],
  5847. // _beginZIndex: Number
  5848. // Z-index of the first popup. (If first popup opens other
  5849. // popups they get a higher z-index.)
  5850. _beginZIndex: 1000,
  5851. _idGen: 1,
  5852. _createWrapper: function(/*Widget*/ widget){
  5853. // summary:
  5854. // Initialization for widgets that will be used as popups.
  5855. // Puts widget inside a wrapper DIV (if not already in one),
  5856. // and returns pointer to that wrapper DIV.
  5857. var wrapper = widget._popupWrapper,
  5858. node = widget.domNode;
  5859. if(!wrapper){
  5860. // Create wrapper <div> for when this widget [in the future] will be used as a popup.
  5861. // This is done early because of IE bugs where creating/moving DOM nodes causes focus
  5862. // to go wonky, see tests/robot/Toolbar.html to reproduce
  5863. wrapper = domConstruct.create("div", {
  5864. "class":"dijitPopup",
  5865. style:{ display: "none"},
  5866. role: "presentation"
  5867. }, win.body());
  5868. wrapper.appendChild(node);
  5869. var s = node.style;
  5870. s.display = "";
  5871. s.visibility = "";
  5872. s.position = "";
  5873. s.top = "0px";
  5874. widget._popupWrapper = wrapper;
  5875. aspect.after(widget, "destroy", destroyWrapper, true);
  5876. }
  5877. return wrapper;
  5878. },
  5879. moveOffScreen: function(/*Widget*/ widget){
  5880. // summary:
  5881. // Moves the popup widget off-screen.
  5882. // Do not use this method to hide popups when not in use, because
  5883. // that will create an accessibility issue: the offscreen popup is
  5884. // still in the tabbing order.
  5885. // Create wrapper if not already there
  5886. var wrapper = this._createWrapper(widget);
  5887. domStyle.set(wrapper, {
  5888. visibility: "hidden",
  5889. top: "-9999px", // prevent transient scrollbar causing misalign (#5776), and initial flash in upper left (#10111)
  5890. display: ""
  5891. });
  5892. },
  5893. hide: function(/*Widget*/ widget){
  5894. // summary:
  5895. // Hide this popup widget (until it is ready to be shown).
  5896. // Initialization for widgets that will be used as popups
  5897. //
  5898. // Also puts widget inside a wrapper DIV (if not already in one)
  5899. //
  5900. // If popup widget needs to layout it should
  5901. // do so when it is made visible, and popup._onShow() is called.
  5902. // Create wrapper if not already there
  5903. var wrapper = this._createWrapper(widget);
  5904. domStyle.set(wrapper, "display", "none");
  5905. },
  5906. getTopPopup: function(){
  5907. // summary:
  5908. // Compute the closest ancestor popup that's *not* a child of another popup.
  5909. // Ex: For a TooltipDialog with a button that spawns a tree of menus, find the popup of the button.
  5910. var stack = this._stack;
  5911. for(var pi=stack.length-1; pi > 0 && stack[pi].parent === stack[pi-1].widget; pi--){
  5912. /* do nothing, just trying to get right value for pi */
  5913. }
  5914. return stack[pi];
  5915. },
  5916. open: function(/*dijit.popup.__OpenArgs*/ args){
  5917. // summary:
  5918. // Popup the widget at the specified position
  5919. //
  5920. // example:
  5921. // opening at the mouse position
  5922. // | popup.open({popup: menuWidget, x: evt.pageX, y: evt.pageY});
  5923. //
  5924. // example:
  5925. // opening the widget as a dropdown
  5926. // | popup.open({parent: this, popup: menuWidget, around: this.domNode, onClose: function(){...}});
  5927. //
  5928. // Note that whatever widget called dijit.popup.open() should also listen to its own _onBlur callback
  5929. // (fired from _base/focus.js) to know that focus has moved somewhere else and thus the popup should be closed.
  5930. var stack = this._stack,
  5931. widget = args.popup,
  5932. orient = args.orient || ["below", "below-alt", "above", "above-alt"],
  5933. ltr = args.parent ? args.parent.isLeftToRight() : domGeometry.isBodyLtr(),
  5934. around = args.around,
  5935. id = (args.around && args.around.id) ? (args.around.id+"_dropdown") : ("popup_"+this._idGen++);
  5936. // If we are opening a new popup that isn't a child of a currently opened popup, then
  5937. // close currently opened popup(s). This should happen automatically when the old popups
  5938. // gets the _onBlur() event, except that the _onBlur() event isn't reliable on IE, see [22198].
  5939. while(stack.length && (!args.parent || !dom.isDescendant(args.parent.domNode, stack[stack.length-1].widget.domNode))){
  5940. this.close(stack[stack.length-1].widget);
  5941. }
  5942. // Get pointer to popup wrapper, and create wrapper if it doesn't exist
  5943. var wrapper = this._createWrapper(widget);
  5944. domAttr.set(wrapper, {
  5945. id: id,
  5946. style: {
  5947. zIndex: this._beginZIndex + stack.length
  5948. },
  5949. "class": "dijitPopup " + (widget.baseClass || widget["class"] || "").split(" ")[0] +"Popup",
  5950. dijitPopupParent: args.parent ? args.parent.id : ""
  5951. });
  5952. if(has("bgIframe") && !widget.bgIframe){
  5953. // setting widget.bgIframe triggers cleanup in _Widget.destroy()
  5954. widget.bgIframe = new BackgroundIframe(wrapper);
  5955. }
  5956. // position the wrapper node and make it visible
  5957. var best = around ?
  5958. place.around(wrapper, around, orient, ltr, widget.orient ? lang.hitch(widget, "orient") : null) :
  5959. place.at(wrapper, args, orient == 'R' ? ['TR','BR','TL','BL'] : ['TL','BL','TR','BR'], args.padding);
  5960. wrapper.style.display = "";
  5961. wrapper.style.visibility = "visible";
  5962. widget.domNode.style.visibility = "visible"; // counteract effects from _HasDropDown
  5963. var handlers = [];
  5964. // provide default escape and tab key handling
  5965. // (this will work for any widget, not just menu)
  5966. handlers.push(on(wrapper, connect._keypress, lang.hitch(this, function(evt){
  5967. if(evt.charOrCode == keys.ESCAPE && args.onCancel){
  5968. event.stop(evt);
  5969. args.onCancel();
  5970. }else if(evt.charOrCode === keys.TAB){
  5971. event.stop(evt);
  5972. var topPopup = this.getTopPopup();
  5973. if(topPopup && topPopup.onCancel){
  5974. topPopup.onCancel();
  5975. }
  5976. }
  5977. })));
  5978. // watch for cancel/execute events on the popup and notify the caller
  5979. // (for a menu, "execute" means clicking an item)
  5980. if(widget.onCancel && args.onCancel){
  5981. handlers.push(widget.on("cancel", args.onCancel));
  5982. }
  5983. handlers.push(widget.on(widget.onExecute ? "execute" : "change", lang.hitch(this, function(){
  5984. var topPopup = this.getTopPopup();
  5985. if(topPopup && topPopup.onExecute){
  5986. topPopup.onExecute();
  5987. }
  5988. })));
  5989. stack.push({
  5990. widget: widget,
  5991. parent: args.parent,
  5992. onExecute: args.onExecute,
  5993. onCancel: args.onCancel,
  5994. onClose: args.onClose,
  5995. handlers: handlers
  5996. });
  5997. if(widget.onOpen){
  5998. // TODO: in 2.0 standardize onShow() (used by StackContainer) and onOpen() (used here)
  5999. widget.onOpen(best);
  6000. }
  6001. return best;
  6002. },
  6003. close: function(/*Widget?*/ popup){
  6004. // summary:
  6005. // Close specified popup and any popups that it parented.
  6006. // If no popup is specified, closes all popups.
  6007. var stack = this._stack;
  6008. // Basically work backwards from the top of the stack closing popups
  6009. // until we hit the specified popup, but IIRC there was some issue where closing
  6010. // a popup would cause others to close too. Thus if we are trying to close B in [A,B,C]
  6011. // closing C might close B indirectly and then the while() condition will run where stack==[A]...
  6012. // so the while condition is constructed defensively.
  6013. while((popup && array.some(stack, function(elem){return elem.widget == popup;})) ||
  6014. (!popup && stack.length)){
  6015. var top = stack.pop(),
  6016. widget = top.widget,
  6017. onClose = top.onClose;
  6018. if(widget.onClose){
  6019. // TODO: in 2.0 standardize onHide() (used by StackContainer) and onClose() (used here)
  6020. widget.onClose();
  6021. }
  6022. var h;
  6023. while(h = top.handlers.pop()){ h.remove(); }
  6024. // Hide the widget and it's wrapper unless it has already been destroyed in above onClose() etc.
  6025. if(widget && widget.domNode){
  6026. this.hide(widget);
  6027. }
  6028. if(onClose){
  6029. onClose();
  6030. }
  6031. }
  6032. }
  6033. });
  6034. return (dijit.popup = new PopupManager());
  6035. });
  6036. },
  6037. 'dijit/_base/window':function(){
  6038. define("dijit/_base/window", [
  6039. "dojo/window", // windowUtils.get
  6040. ".." // export symbol to dijit
  6041. ], function(windowUtils, dijit){
  6042. // module:
  6043. // dijit/_base/window
  6044. // summary:
  6045. // Back compatibility module, new code should use windowUtils directly instead of using this module.
  6046. dijit.getDocumentWindow = function(doc){
  6047. return windowUtils.get(doc);
  6048. };
  6049. });
  6050. },
  6051. 'dijit/_WidgetBase':function(){
  6052. define("dijit/_WidgetBase", [
  6053. "require", // require.toUrl
  6054. "dojo/_base/array", // array.forEach array.map
  6055. "dojo/aspect",
  6056. "dojo/_base/config", // config.blankGif
  6057. "dojo/_base/connect", // connect.connect
  6058. "dojo/_base/declare", // declare
  6059. "dojo/dom", // dom.byId
  6060. "dojo/dom-attr", // domAttr.set domAttr.remove
  6061. "dojo/dom-class", // domClass.add domClass.replace
  6062. "dojo/dom-construct", // domConstruct.create domConstruct.destroy domConstruct.place
  6063. "dojo/dom-geometry", // isBodyLtr
  6064. "dojo/dom-style", // domStyle.set, domStyle.get
  6065. "dojo/_base/kernel",
  6066. "dojo/_base/lang", // mixin(), isArray(), etc.
  6067. "dojo/on",
  6068. "dojo/ready",
  6069. "dojo/Stateful", // Stateful
  6070. "dojo/topic",
  6071. "dojo/_base/window", // win.doc.createTextNode
  6072. "./registry" // registry.getUniqueId(), registry.findWidgets()
  6073. ], function(require, array, aspect, config, connect, declare,
  6074. dom, domAttr, domClass, domConstruct, domGeometry, domStyle, kernel,
  6075. lang, on, ready, Stateful, topic, win, registry){
  6076. /*=====
  6077. var Stateful = dojo.Stateful;
  6078. =====*/
  6079. // module:
  6080. // dijit/_WidgetBase
  6081. // summary:
  6082. // Future base class for all Dijit widgets.
  6083. // For back-compat, remove in 2.0.
  6084. if(!kernel.isAsync){
  6085. ready(0, function(){
  6086. var requires = ["dijit/_base/manager"];
  6087. require(requires); // use indirection so modules not rolled into a build
  6088. });
  6089. }
  6090. // Nested hash listing attributes for each tag, all strings in lowercase.
  6091. // ex: {"div": {"style": true, "tabindex" true}, "form": { ...
  6092. var tagAttrs = {};
  6093. function getAttrs(obj){
  6094. var ret = {};
  6095. for(var attr in obj){
  6096. ret[attr.toLowerCase()] = true;
  6097. }
  6098. return ret;
  6099. }
  6100. function nonEmptyAttrToDom(attr){
  6101. // summary:
  6102. // Returns a setter function that copies the attribute to this.domNode,
  6103. // or removes the attribute from this.domNode, depending on whether the
  6104. // value is defined or not.
  6105. return function(val){
  6106. domAttr[val ? "set" : "remove"](this.domNode, attr, val);
  6107. this._set(attr, val);
  6108. };
  6109. }
  6110. function isEqual(a, b){
  6111. // summary:
  6112. // Function that determines whether two values are identical,
  6113. // taking into account that NaN is not normally equal to itself
  6114. // in JS.
  6115. return a === b || (/* a is NaN */ a !== a && /* b is NaN */ b !== b);
  6116. }
  6117. return declare("dijit._WidgetBase", Stateful, {
  6118. // summary:
  6119. // Future base class for all Dijit widgets.
  6120. // description:
  6121. // Future base class for all Dijit widgets.
  6122. // _Widget extends this class adding support for various features needed by desktop.
  6123. //
  6124. // Provides stubs for widget lifecycle methods for subclasses to extend, like postMixInProperties(), buildRendering(),
  6125. // postCreate(), startup(), and destroy(), and also public API methods like set(), get(), and watch().
  6126. //
  6127. // Widgets can provide custom setters/getters for widget attributes, which are called automatically by set(name, value).
  6128. // For an attribute XXX, define methods _setXXXAttr() and/or _getXXXAttr().
  6129. //
  6130. // _setXXXAttr can also be a string/hash/array mapping from a widget attribute XXX to the widget's DOMNodes:
  6131. //
  6132. // - DOM node attribute
  6133. // | _setFocusAttr: {node: "focusNode", type: "attribute"}
  6134. // | _setFocusAttr: "focusNode" (shorthand)
  6135. // | _setFocusAttr: "" (shorthand, maps to this.domNode)
  6136. // Maps this.focus to this.focusNode.focus, or (last example) this.domNode.focus
  6137. //
  6138. // - DOM node innerHTML
  6139. // | _setTitleAttr: { node: "titleNode", type: "innerHTML" }
  6140. // Maps this.title to this.titleNode.innerHTML
  6141. //
  6142. // - DOM node innerText
  6143. // | _setTitleAttr: { node: "titleNode", type: "innerText" }
  6144. // Maps this.title to this.titleNode.innerText
  6145. //
  6146. // - DOM node CSS class
  6147. // | _setMyClassAttr: { node: "domNode", type: "class" }
  6148. // Maps this.myClass to this.domNode.className
  6149. //
  6150. // If the value of _setXXXAttr is an array, then each element in the array matches one of the
  6151. // formats of the above list.
  6152. //
  6153. // If the custom setter is null, no action is performed other than saving the new value
  6154. // in the widget (in this).
  6155. //
  6156. // If no custom setter is defined for an attribute, then it will be copied
  6157. // to this.focusNode (if the widget defines a focusNode), or this.domNode otherwise.
  6158. // That's only done though for attributes that match DOMNode attributes (title,
  6159. // alt, aria-labelledby, etc.)
  6160. // id: [const] String
  6161. // A unique, opaque ID string that can be assigned by users or by the
  6162. // system. If the developer passes an ID which is known not to be
  6163. // unique, the specified ID is ignored and the system-generated ID is
  6164. // used instead.
  6165. id: "",
  6166. _setIdAttr: "domNode", // to copy to this.domNode even for auto-generated id's
  6167. // lang: [const] String
  6168. // Rarely used. Overrides the default Dojo locale used to render this widget,
  6169. // as defined by the [HTML LANG](http://www.w3.org/TR/html401/struct/dirlang.html#adef-lang) attribute.
  6170. // Value must be among the list of locales specified during by the Dojo bootstrap,
  6171. // formatted according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt) (like en-us).
  6172. lang: "",
  6173. // set on domNode even when there's a focus node. but don't set lang="", since that's invalid.
  6174. _setLangAttr: nonEmptyAttrToDom("lang"),
  6175. // dir: [const] String
  6176. // Bi-directional support, as defined by the [HTML DIR](http://www.w3.org/TR/html401/struct/dirlang.html#adef-dir)
  6177. // attribute. Either left-to-right "ltr" or right-to-left "rtl". If undefined, widgets renders in page's
  6178. // default direction.
  6179. dir: "",
  6180. // set on domNode even when there's a focus node. but don't set dir="", since that's invalid.
  6181. _setDirAttr: nonEmptyAttrToDom("dir"), // to set on domNode even when there's a focus node
  6182. // textDir: String
  6183. // Bi-directional support, the main variable which is responsible for the direction of the text.
  6184. // The text direction can be different than the GUI direction by using this parameter in creation
  6185. // of a widget.
  6186. // Allowed values:
  6187. // 1. "ltr"
  6188. // 2. "rtl"
  6189. // 3. "auto" - contextual the direction of a text defined by first strong letter.
  6190. // By default is as the page direction.
  6191. textDir: "",
  6192. // class: String
  6193. // HTML class attribute
  6194. "class": "",
  6195. _setClassAttr: { node: "domNode", type: "class" },
  6196. // style: String||Object
  6197. // HTML style attributes as cssText string or name/value hash
  6198. style: "",
  6199. // title: String
  6200. // HTML title attribute.
  6201. //
  6202. // For form widgets this specifies a tooltip to display when hovering over
  6203. // the widget (just like the native HTML title attribute).
  6204. //
  6205. // For TitlePane or for when this widget is a child of a TabContainer, AccordionContainer,
  6206. // etc., it's used to specify the tab label, accordion pane title, etc.
  6207. title: "",
  6208. // tooltip: String
  6209. // When this widget's title attribute is used to for a tab label, accordion pane title, etc.,
  6210. // this specifies the tooltip to appear when the mouse is hovered over that text.
  6211. tooltip: "",
  6212. // baseClass: [protected] String
  6213. // Root CSS class of the widget (ex: dijitTextBox), used to construct CSS classes to indicate
  6214. // widget state.
  6215. baseClass: "",
  6216. // srcNodeRef: [readonly] DomNode
  6217. // pointer to original DOM node
  6218. srcNodeRef: null,
  6219. // domNode: [readonly] DomNode
  6220. // This is our visible representation of the widget! Other DOM
  6221. // Nodes may by assigned to other properties, usually through the
  6222. // template system's data-dojo-attach-point syntax, but the domNode
  6223. // property is the canonical "top level" node in widget UI.
  6224. domNode: null,
  6225. // containerNode: [readonly] DomNode
  6226. // Designates where children of the source DOM node will be placed.
  6227. // "Children" in this case refers to both DOM nodes and widgets.
  6228. // For example, for myWidget:
  6229. //
  6230. // | <div data-dojo-type=myWidget>
  6231. // | <b> here's a plain DOM node
  6232. // | <span data-dojo-type=subWidget>and a widget</span>
  6233. // | <i> and another plain DOM node </i>
  6234. // | </div>
  6235. //
  6236. // containerNode would point to:
  6237. //
  6238. // | <b> here's a plain DOM node
  6239. // | <span data-dojo-type=subWidget>and a widget</span>
  6240. // | <i> and another plain DOM node </i>
  6241. //
  6242. // In templated widgets, "containerNode" is set via a
  6243. // data-dojo-attach-point assignment.
  6244. //
  6245. // containerNode must be defined for any widget that accepts innerHTML
  6246. // (like ContentPane or BorderContainer or even Button), and conversely
  6247. // is null for widgets that don't, like TextBox.
  6248. containerNode: null,
  6249. /*=====
  6250. // _started: Boolean
  6251. // startup() has completed.
  6252. _started: false,
  6253. =====*/
  6254. // attributeMap: [protected] Object
  6255. // Deprecated. Instead of attributeMap, widget should have a _setXXXAttr attribute
  6256. // for each XXX attribute to be mapped to the DOM.
  6257. //
  6258. // attributeMap sets up a "binding" between attributes (aka properties)
  6259. // of the widget and the widget's DOM.
  6260. // Changes to widget attributes listed in attributeMap will be
  6261. // reflected into the DOM.
  6262. //
  6263. // For example, calling set('title', 'hello')
  6264. // on a TitlePane will automatically cause the TitlePane's DOM to update
  6265. // with the new title.
  6266. //
  6267. // attributeMap is a hash where the key is an attribute of the widget,
  6268. // and the value reflects a binding to a:
  6269. //
  6270. // - DOM node attribute
  6271. // | focus: {node: "focusNode", type: "attribute"}
  6272. // Maps this.focus to this.focusNode.focus
  6273. //
  6274. // - DOM node innerHTML
  6275. // | title: { node: "titleNode", type: "innerHTML" }
  6276. // Maps this.title to this.titleNode.innerHTML
  6277. //
  6278. // - DOM node innerText
  6279. // | title: { node: "titleNode", type: "innerText" }
  6280. // Maps this.title to this.titleNode.innerText
  6281. //
  6282. // - DOM node CSS class
  6283. // | myClass: { node: "domNode", type: "class" }
  6284. // Maps this.myClass to this.domNode.className
  6285. //
  6286. // If the value is an array, then each element in the array matches one of the
  6287. // formats of the above list.
  6288. //
  6289. // There are also some shorthands for backwards compatibility:
  6290. // - string --> { node: string, type: "attribute" }, for example:
  6291. // | "focusNode" ---> { node: "focusNode", type: "attribute" }
  6292. // - "" --> { node: "domNode", type: "attribute" }
  6293. attributeMap: {},
  6294. // _blankGif: [protected] String
  6295. // Path to a blank 1x1 image.
  6296. // Used by <img> nodes in templates that really get their image via CSS background-image.
  6297. _blankGif: config.blankGif || require.toUrl("dojo/resources/blank.gif"),
  6298. //////////// INITIALIZATION METHODS ///////////////////////////////////////
  6299. postscript: function(/*Object?*/params, /*DomNode|String*/srcNodeRef){
  6300. // summary:
  6301. // Kicks off widget instantiation. See create() for details.
  6302. // tags:
  6303. // private
  6304. this.create(params, srcNodeRef);
  6305. },
  6306. create: function(/*Object?*/params, /*DomNode|String?*/srcNodeRef){
  6307. // summary:
  6308. // Kick off the life-cycle of a widget
  6309. // params:
  6310. // Hash of initialization parameters for widget, including
  6311. // scalar values (like title, duration etc.) and functions,
  6312. // typically callbacks like onClick.
  6313. // srcNodeRef:
  6314. // If a srcNodeRef (DOM node) is specified:
  6315. // - use srcNodeRef.innerHTML as my contents
  6316. // - if this is a behavioral widget then apply behavior
  6317. // to that srcNodeRef
  6318. // - otherwise, replace srcNodeRef with my generated DOM
  6319. // tree
  6320. // description:
  6321. // Create calls a number of widget methods (postMixInProperties, buildRendering, postCreate,
  6322. // etc.), some of which of you'll want to override. See http://dojotoolkit.org/reference-guide/dijit/_WidgetBase.html
  6323. // for a discussion of the widget creation lifecycle.
  6324. //
  6325. // Of course, adventurous developers could override create entirely, but this should
  6326. // only be done as a last resort.
  6327. // tags:
  6328. // private
  6329. // store pointer to original DOM tree
  6330. this.srcNodeRef = dom.byId(srcNodeRef);
  6331. // For garbage collection. An array of listener handles returned by this.connect() / this.subscribe()
  6332. this._connects = [];
  6333. // For widgets internal to this widget, invisible to calling code
  6334. this._supportingWidgets = [];
  6335. // this is here for back-compat, remove in 2.0 (but check NodeList-instantiate.html test)
  6336. if(this.srcNodeRef && (typeof this.srcNodeRef.id == "string")){ this.id = this.srcNodeRef.id; }
  6337. // mix in our passed parameters
  6338. if(params){
  6339. this.params = params;
  6340. lang.mixin(this, params);
  6341. }
  6342. this.postMixInProperties();
  6343. // generate an id for the widget if one wasn't specified
  6344. // (be sure to do this before buildRendering() because that function might
  6345. // expect the id to be there.)
  6346. if(!this.id){
  6347. this.id = registry.getUniqueId(this.declaredClass.replace(/\./g,"_"));
  6348. }
  6349. registry.add(this);
  6350. this.buildRendering();
  6351. if(this.domNode){
  6352. // Copy attributes listed in attributeMap into the [newly created] DOM for the widget.
  6353. // Also calls custom setters for all attributes with custom setters.
  6354. this._applyAttributes();
  6355. // If srcNodeRef was specified, then swap out original srcNode for this widget's DOM tree.
  6356. // For 2.0, move this after postCreate(). postCreate() shouldn't depend on the
  6357. // widget being attached to the DOM since it isn't when a widget is created programmatically like
  6358. // new MyWidget({}). See #11635.
  6359. var source = this.srcNodeRef;
  6360. if(source && source.parentNode && this.domNode !== source){
  6361. source.parentNode.replaceChild(this.domNode, source);
  6362. }
  6363. }
  6364. if(this.domNode){
  6365. // Note: for 2.0 may want to rename widgetId to dojo._scopeName + "_widgetId",
  6366. // assuming that dojo._scopeName even exists in 2.0
  6367. this.domNode.setAttribute("widgetId", this.id);
  6368. }
  6369. this.postCreate();
  6370. // If srcNodeRef has been processed and removed from the DOM (e.g. TemplatedWidget) then delete it to allow GC.
  6371. if(this.srcNodeRef && !this.srcNodeRef.parentNode){
  6372. delete this.srcNodeRef;
  6373. }
  6374. this._created = true;
  6375. },
  6376. _applyAttributes: function(){
  6377. // summary:
  6378. // Step during widget creation to copy widget attributes to the
  6379. // DOM according to attributeMap and _setXXXAttr objects, and also to call
  6380. // custom _setXXXAttr() methods.
  6381. //
  6382. // Skips over blank/false attribute values, unless they were explicitly specified
  6383. // as parameters to the widget, since those are the default anyway,
  6384. // and setting tabIndex="" is different than not setting tabIndex at all.
  6385. //
  6386. // For backwards-compatibility reasons attributeMap overrides _setXXXAttr when
  6387. // _setXXXAttr is a hash/string/array, but _setXXXAttr as a functions override attributeMap.
  6388. // tags:
  6389. // private
  6390. // Get list of attributes where this.set(name, value) will do something beyond
  6391. // setting this[name] = value. Specifically, attributes that have:
  6392. // - associated _setXXXAttr() method/hash/string/array
  6393. // - entries in attributeMap.
  6394. var ctor = this.constructor,
  6395. list = ctor._setterAttrs;
  6396. if(!list){
  6397. list = (ctor._setterAttrs = []);
  6398. for(var attr in this.attributeMap){
  6399. list.push(attr);
  6400. }
  6401. var proto = ctor.prototype;
  6402. for(var fxName in proto){
  6403. if(fxName in this.attributeMap){ continue; }
  6404. var setterName = "_set" + fxName.replace(/^[a-z]|-[a-zA-Z]/g, function(c){ return c.charAt(c.length-1).toUpperCase(); }) + "Attr";
  6405. if(setterName in proto){
  6406. list.push(fxName);
  6407. }
  6408. }
  6409. }
  6410. // Call this.set() for each attribute that was either specified as parameter to constructor,
  6411. // or was found above and has a default non-null value. For correlated attributes like value and displayedValue, the one
  6412. // specified as a parameter should take precedence, so apply attributes in this.params last.
  6413. // Particularly important for new DateTextBox({displayedValue: ...}) since DateTextBox's default value is
  6414. // NaN and thus is not ignored like a default value of "".
  6415. array.forEach(list, function(attr){
  6416. if(this.params && attr in this.params){
  6417. // skip this one, do it below
  6418. }else if(this[attr]){
  6419. this.set(attr, this[attr]);
  6420. }
  6421. }, this);
  6422. for(var param in this.params){
  6423. this.set(param, this[param]);
  6424. }
  6425. },
  6426. postMixInProperties: function(){
  6427. // summary:
  6428. // Called after the parameters to the widget have been read-in,
  6429. // but before the widget template is instantiated. Especially
  6430. // useful to set properties that are referenced in the widget
  6431. // template.
  6432. // tags:
  6433. // protected
  6434. },
  6435. buildRendering: function(){
  6436. // summary:
  6437. // Construct the UI for this widget, setting this.domNode.
  6438. // Most widgets will mixin `dijit._TemplatedMixin`, which implements this method.
  6439. // tags:
  6440. // protected
  6441. if(!this.domNode){
  6442. // Create root node if it wasn't created by _Templated
  6443. this.domNode = this.srcNodeRef || domConstruct.create('div');
  6444. }
  6445. // baseClass is a single class name or occasionally a space-separated list of names.
  6446. // Add those classes to the DOMNode. If RTL mode then also add with Rtl suffix.
  6447. // TODO: make baseClass custom setter
  6448. if(this.baseClass){
  6449. var classes = this.baseClass.split(" ");
  6450. if(!this.isLeftToRight()){
  6451. classes = classes.concat( array.map(classes, function(name){ return name+"Rtl"; }));
  6452. }
  6453. domClass.add(this.domNode, classes);
  6454. }
  6455. },
  6456. postCreate: function(){
  6457. // summary:
  6458. // Processing after the DOM fragment is created
  6459. // description:
  6460. // Called after the DOM fragment has been created, but not necessarily
  6461. // added to the document. Do not include any operations which rely on
  6462. // node dimensions or placement.
  6463. // tags:
  6464. // protected
  6465. },
  6466. startup: function(){
  6467. // summary:
  6468. // Processing after the DOM fragment is added to the document
  6469. // description:
  6470. // Called after a widget and its children have been created and added to the page,
  6471. // and all related widgets have finished their create() cycle, up through postCreate().
  6472. // This is useful for composite widgets that need to control or layout sub-widgets.
  6473. // Many layout widgets can use this as a wiring phase.
  6474. if(this._started){ return; }
  6475. this._started = true;
  6476. array.forEach(this.getChildren(), function(obj){
  6477. if(!obj._started && !obj._destroyed && lang.isFunction(obj.startup)){
  6478. obj.startup();
  6479. obj._started = true;
  6480. }
  6481. });
  6482. },
  6483. //////////// DESTROY FUNCTIONS ////////////////////////////////
  6484. destroyRecursive: function(/*Boolean?*/ preserveDom){
  6485. // summary:
  6486. // Destroy this widget and its descendants
  6487. // description:
  6488. // This is the generic "destructor" function that all widget users
  6489. // should call to cleanly discard with a widget. Once a widget is
  6490. // destroyed, it is removed from the manager object.
  6491. // preserveDom:
  6492. // If true, this method will leave the original DOM structure
  6493. // alone of descendant Widgets. Note: This will NOT work with
  6494. // dijit._Templated widgets.
  6495. this._beingDestroyed = true;
  6496. this.destroyDescendants(preserveDom);
  6497. this.destroy(preserveDom);
  6498. },
  6499. destroy: function(/*Boolean*/ preserveDom){
  6500. // summary:
  6501. // Destroy this widget, but not its descendants.
  6502. // This method will, however, destroy internal widgets such as those used within a template.
  6503. // preserveDom: Boolean
  6504. // If true, this method will leave the original DOM structure alone.
  6505. // Note: This will not yet work with _Templated widgets
  6506. this._beingDestroyed = true;
  6507. this.uninitialize();
  6508. // remove this.connect() and this.subscribe() listeners
  6509. var c;
  6510. while((c = this._connects.pop())){
  6511. c.remove();
  6512. }
  6513. // destroy widgets created as part of template, etc.
  6514. var w;
  6515. while((w = this._supportingWidgets.pop())){
  6516. if(w.destroyRecursive){
  6517. w.destroyRecursive();
  6518. }else if(w.destroy){
  6519. w.destroy();
  6520. }
  6521. }
  6522. this.destroyRendering(preserveDom);
  6523. registry.remove(this.id);
  6524. this._destroyed = true;
  6525. },
  6526. destroyRendering: function(/*Boolean?*/ preserveDom){
  6527. // summary:
  6528. // Destroys the DOM nodes associated with this widget
  6529. // preserveDom:
  6530. // If true, this method will leave the original DOM structure alone
  6531. // during tear-down. Note: this will not work with _Templated
  6532. // widgets yet.
  6533. // tags:
  6534. // protected
  6535. if(this.bgIframe){
  6536. this.bgIframe.destroy(preserveDom);
  6537. delete this.bgIframe;
  6538. }
  6539. if(this.domNode){
  6540. if(preserveDom){
  6541. domAttr.remove(this.domNode, "widgetId");
  6542. }else{
  6543. domConstruct.destroy(this.domNode);
  6544. }
  6545. delete this.domNode;
  6546. }
  6547. if(this.srcNodeRef){
  6548. if(!preserveDom){
  6549. domConstruct.destroy(this.srcNodeRef);
  6550. }
  6551. delete this.srcNodeRef;
  6552. }
  6553. },
  6554. destroyDescendants: function(/*Boolean?*/ preserveDom){
  6555. // summary:
  6556. // Recursively destroy the children of this widget and their
  6557. // descendants.
  6558. // preserveDom:
  6559. // If true, the preserveDom attribute is passed to all descendant
  6560. // widget's .destroy() method. Not for use with _Templated
  6561. // widgets.
  6562. // get all direct descendants and destroy them recursively
  6563. array.forEach(this.getChildren(), function(widget){
  6564. if(widget.destroyRecursive){
  6565. widget.destroyRecursive(preserveDom);
  6566. }
  6567. });
  6568. },
  6569. uninitialize: function(){
  6570. // summary:
  6571. // Stub function. Override to implement custom widget tear-down
  6572. // behavior.
  6573. // tags:
  6574. // protected
  6575. return false;
  6576. },
  6577. ////////////////// GET/SET, CUSTOM SETTERS, ETC. ///////////////////
  6578. _setStyleAttr: function(/*String||Object*/ value){
  6579. // summary:
  6580. // Sets the style attribute of the widget according to value,
  6581. // which is either a hash like {height: "5px", width: "3px"}
  6582. // or a plain string
  6583. // description:
  6584. // Determines which node to set the style on based on style setting
  6585. // in attributeMap.
  6586. // tags:
  6587. // protected
  6588. var mapNode = this.domNode;
  6589. // Note: technically we should revert any style setting made in a previous call
  6590. // to his method, but that's difficult to keep track of.
  6591. if(lang.isObject(value)){
  6592. domStyle.set(mapNode, value);
  6593. }else{
  6594. if(mapNode.style.cssText){
  6595. mapNode.style.cssText += "; " + value;
  6596. }else{
  6597. mapNode.style.cssText = value;
  6598. }
  6599. }
  6600. this._set("style", value);
  6601. },
  6602. _attrToDom: function(/*String*/ attr, /*String*/ value, /*Object?*/ commands){
  6603. // summary:
  6604. // Reflect a widget attribute (title, tabIndex, duration etc.) to
  6605. // the widget DOM, as specified by commands parameter.
  6606. // If commands isn't specified then it's looked up from attributeMap.
  6607. // Note some attributes like "type"
  6608. // cannot be processed this way as they are not mutable.
  6609. //
  6610. // tags:
  6611. // private
  6612. commands = arguments.length >= 3 ? commands : this.attributeMap[attr];
  6613. array.forEach(lang.isArray(commands) ? commands : [commands], function(command){
  6614. // Get target node and what we are doing to that node
  6615. var mapNode = this[command.node || command || "domNode"]; // DOM node
  6616. var type = command.type || "attribute"; // class, innerHTML, innerText, or attribute
  6617. switch(type){
  6618. case "attribute":
  6619. if(lang.isFunction(value)){ // functions execute in the context of the widget
  6620. value = lang.hitch(this, value);
  6621. }
  6622. // Get the name of the DOM node attribute; usually it's the same
  6623. // as the name of the attribute in the widget (attr), but can be overridden.
  6624. // Also maps handler names to lowercase, like onSubmit --> onsubmit
  6625. var attrName = command.attribute ? command.attribute :
  6626. (/^on[A-Z][a-zA-Z]*$/.test(attr) ? attr.toLowerCase() : attr);
  6627. domAttr.set(mapNode, attrName, value);
  6628. break;
  6629. case "innerText":
  6630. mapNode.innerHTML = "";
  6631. mapNode.appendChild(win.doc.createTextNode(value));
  6632. break;
  6633. case "innerHTML":
  6634. mapNode.innerHTML = value;
  6635. break;
  6636. case "class":
  6637. domClass.replace(mapNode, value, this[attr]);
  6638. break;
  6639. }
  6640. }, this);
  6641. },
  6642. get: function(name){
  6643. // summary:
  6644. // Get a property from a widget.
  6645. // name:
  6646. // The property to get.
  6647. // description:
  6648. // Get a named property from a widget. The property may
  6649. // potentially be retrieved via a getter method. If no getter is defined, this
  6650. // just retrieves the object's property.
  6651. //
  6652. // For example, if the widget has properties `foo` and `bar`
  6653. // and a method named `_getFooAttr()`, calling:
  6654. // `myWidget.get("foo")` would be equivalent to calling
  6655. // `widget._getFooAttr()` and `myWidget.get("bar")`
  6656. // would be equivalent to the expression
  6657. // `widget.bar2`
  6658. var names = this._getAttrNames(name);
  6659. return this[names.g] ? this[names.g]() : this[name];
  6660. },
  6661. set: function(name, value){
  6662. // summary:
  6663. // Set a property on a widget
  6664. // name:
  6665. // The property to set.
  6666. // value:
  6667. // The value to set in the property.
  6668. // description:
  6669. // Sets named properties on a widget which may potentially be handled by a
  6670. // setter in the widget.
  6671. //
  6672. // For example, if the widget has properties `foo` and `bar`
  6673. // and a method named `_setFooAttr()`, calling
  6674. // `myWidget.set("foo", "Howdy!")` would be equivalent to calling
  6675. // `widget._setFooAttr("Howdy!")` and `myWidget.set("bar", 3)`
  6676. // would be equivalent to the statement `widget.bar = 3;`
  6677. //
  6678. // set() may also be called with a hash of name/value pairs, ex:
  6679. //
  6680. // | myWidget.set({
  6681. // | foo: "Howdy",
  6682. // | bar: 3
  6683. // | });
  6684. //
  6685. // This is equivalent to calling `set(foo, "Howdy")` and `set(bar, 3)`
  6686. if(typeof name === "object"){
  6687. for(var x in name){
  6688. this.set(x, name[x]);
  6689. }
  6690. return this;
  6691. }
  6692. var names = this._getAttrNames(name),
  6693. setter = this[names.s];
  6694. if(lang.isFunction(setter)){
  6695. // use the explicit setter
  6696. var result = setter.apply(this, Array.prototype.slice.call(arguments, 1));
  6697. }else{
  6698. // Mapping from widget attribute to DOMNode attribute/value/etc.
  6699. // Map according to:
  6700. // 1. attributeMap setting, if one exists (TODO: attributeMap deprecated, remove in 2.0)
  6701. // 2. _setFooAttr: {...} type attribute in the widget (if one exists)
  6702. // 3. apply to focusNode or domNode if standard attribute name, excluding funcs like onClick.
  6703. // Checks if an attribute is a "standard attribute" by whether the DOMNode JS object has a similar
  6704. // attribute name (ex: accept-charset attribute matches jsObject.acceptCharset).
  6705. // Note also that Tree.focusNode() is a function not a DOMNode, so test for that.
  6706. var defaultNode = this.focusNode && !lang.isFunction(this.focusNode) ? "focusNode" : "domNode",
  6707. tag = this[defaultNode].tagName,
  6708. attrsForTag = tagAttrs[tag] || (tagAttrs[tag] = getAttrs(this[defaultNode])),
  6709. map = name in this.attributeMap ? this.attributeMap[name] :
  6710. names.s in this ? this[names.s] :
  6711. ((names.l in attrsForTag && typeof value != "function") ||
  6712. /^aria-|^data-|^role$/.test(name)) ? defaultNode : null;
  6713. if(map != null){
  6714. this._attrToDom(name, value, map);
  6715. }
  6716. this._set(name, value);
  6717. }
  6718. return result || this;
  6719. },
  6720. _attrPairNames: {}, // shared between all widgets
  6721. _getAttrNames: function(name){
  6722. // summary:
  6723. // Helper function for get() and set().
  6724. // Caches attribute name values so we don't do the string ops every time.
  6725. // tags:
  6726. // private
  6727. var apn = this._attrPairNames;
  6728. if(apn[name]){ return apn[name]; }
  6729. var uc = name.replace(/^[a-z]|-[a-zA-Z]/g, function(c){ return c.charAt(c.length-1).toUpperCase(); });
  6730. return (apn[name] = {
  6731. n: name+"Node",
  6732. s: "_set"+uc+"Attr", // converts dashes to camel case, ex: accept-charset --> _setAcceptCharsetAttr
  6733. g: "_get"+uc+"Attr",
  6734. l: uc.toLowerCase() // lowercase name w/out dashes, ex: acceptcharset
  6735. });
  6736. },
  6737. _set: function(/*String*/ name, /*anything*/ value){
  6738. // summary:
  6739. // Helper function to set new value for specified attribute, and call handlers
  6740. // registered with watch() if the value has changed.
  6741. var oldValue = this[name];
  6742. this[name] = value;
  6743. if(this._watchCallbacks && this._created && !isEqual(value, oldValue)){
  6744. this._watchCallbacks(name, oldValue, value);
  6745. }
  6746. },
  6747. on: function(/*String*/ type, /*Function*/ func){
  6748. // summary:
  6749. // Call specified function when event occurs, ex: myWidget.on("click", function(){ ... }).
  6750. // description:
  6751. // Call specified function when event `type` occurs, ex: `myWidget.on("click", function(){ ... })`.
  6752. // Note that the function is not run in any particular scope, so if (for example) you want it to run in the
  6753. // widget's scope you must do `myWidget.on("click", lang.hitch(myWidget, func))`.
  6754. return aspect.after(this, this._onMap(type), func, true);
  6755. },
  6756. _onMap: function(/*String*/ type){
  6757. // summary:
  6758. // Maps on() type parameter (ex: "mousemove") to method name (ex: "onMouseMove")
  6759. var ctor = this.constructor, map = ctor._onMap;
  6760. if(!map){
  6761. map = (ctor._onMap = {});
  6762. for(var attr in ctor.prototype){
  6763. if(/^on/.test(attr)){
  6764. map[attr.replace(/^on/, "").toLowerCase()] = attr;
  6765. }
  6766. }
  6767. }
  6768. return map[type.toLowerCase()]; // String
  6769. },
  6770. toString: function(){
  6771. // summary:
  6772. // Returns a string that represents the widget
  6773. // description:
  6774. // When a widget is cast to a string, this method will be used to generate the
  6775. // output. Currently, it does not implement any sort of reversible
  6776. // serialization.
  6777. return '[Widget ' + this.declaredClass + ', ' + (this.id || 'NO ID') + ']'; // String
  6778. },
  6779. getChildren: function(){
  6780. // summary:
  6781. // Returns all the widgets contained by this, i.e., all widgets underneath this.containerNode.
  6782. // Does not return nested widgets, nor widgets that are part of this widget's template.
  6783. return this.containerNode ? registry.findWidgets(this.containerNode) : []; // dijit._Widget[]
  6784. },
  6785. getParent: function(){
  6786. // summary:
  6787. // Returns the parent widget of this widget
  6788. return registry.getEnclosingWidget(this.domNode.parentNode);
  6789. },
  6790. connect: function(
  6791. /*Object|null*/ obj,
  6792. /*String|Function*/ event,
  6793. /*String|Function*/ method){
  6794. // summary:
  6795. // Connects specified obj/event to specified method of this object
  6796. // and registers for disconnect() on widget destroy.
  6797. // description:
  6798. // Provide widget-specific analog to dojo.connect, except with the
  6799. // implicit use of this widget as the target object.
  6800. // Events connected with `this.connect` are disconnected upon
  6801. // destruction.
  6802. // returns:
  6803. // A handle that can be passed to `disconnect` in order to disconnect before
  6804. // the widget is destroyed.
  6805. // example:
  6806. // | var btn = new dijit.form.Button();
  6807. // | // when foo.bar() is called, call the listener we're going to
  6808. // | // provide in the scope of btn
  6809. // | btn.connect(foo, "bar", function(){
  6810. // | console.debug(this.toString());
  6811. // | });
  6812. // tags:
  6813. // protected
  6814. var handle = connect.connect(obj, event, this, method);
  6815. this._connects.push(handle);
  6816. return handle; // _Widget.Handle
  6817. },
  6818. disconnect: function(handle){
  6819. // summary:
  6820. // Disconnects handle created by `connect`.
  6821. // Also removes handle from this widget's list of connects.
  6822. // tags:
  6823. // protected
  6824. var i = array.indexOf(this._connects, handle);
  6825. if(i != -1){
  6826. handle.remove();
  6827. this._connects.splice(i, 1);
  6828. }
  6829. },
  6830. subscribe: function(t, method){
  6831. // summary:
  6832. // Subscribes to the specified topic and calls the specified method
  6833. // of this object and registers for unsubscribe() on widget destroy.
  6834. // description:
  6835. // Provide widget-specific analog to dojo.subscribe, except with the
  6836. // implicit use of this widget as the target object.
  6837. // t: String
  6838. // The topic
  6839. // method: Function
  6840. // The callback
  6841. // example:
  6842. // | var btn = new dijit.form.Button();
  6843. // | // when /my/topic is published, this button changes its label to
  6844. // | // be the parameter of the topic.
  6845. // | btn.subscribe("/my/topic", function(v){
  6846. // | this.set("label", v);
  6847. // | });
  6848. // tags:
  6849. // protected
  6850. var handle = topic.subscribe(t, lang.hitch(this, method));
  6851. this._connects.push(handle);
  6852. return handle; // _Widget.Handle
  6853. },
  6854. unsubscribe: function(/*Object*/ handle){
  6855. // summary:
  6856. // Unsubscribes handle created by this.subscribe.
  6857. // Also removes handle from this widget's list of subscriptions
  6858. // tags:
  6859. // protected
  6860. this.disconnect(handle);
  6861. },
  6862. isLeftToRight: function(){
  6863. // summary:
  6864. // Return this widget's explicit or implicit orientation (true for LTR, false for RTL)
  6865. // tags:
  6866. // protected
  6867. return this.dir ? (this.dir == "ltr") : domGeometry.isBodyLtr(); //Boolean
  6868. },
  6869. isFocusable: function(){
  6870. // summary:
  6871. // Return true if this widget can currently be focused
  6872. // and false if not
  6873. return this.focus && (domStyle.get(this.domNode, "display") != "none");
  6874. },
  6875. placeAt: function(/* String|DomNode|_Widget */reference, /* String?|Int? */position){
  6876. // summary:
  6877. // Place this widget's domNode reference somewhere in the DOM based
  6878. // on standard domConstruct.place conventions, or passing a Widget reference that
  6879. // contains and addChild member.
  6880. //
  6881. // description:
  6882. // A convenience function provided in all _Widgets, providing a simple
  6883. // shorthand mechanism to put an existing (or newly created) Widget
  6884. // somewhere in the dom, and allow chaining.
  6885. //
  6886. // reference:
  6887. // The String id of a domNode, a domNode reference, or a reference to a Widget possessing
  6888. // an addChild method.
  6889. //
  6890. // position:
  6891. // If passed a string or domNode reference, the position argument
  6892. // accepts a string just as domConstruct.place does, one of: "first", "last",
  6893. // "before", or "after".
  6894. //
  6895. // If passed a _Widget reference, and that widget reference has an ".addChild" method,
  6896. // it will be called passing this widget instance into that method, supplying the optional
  6897. // position index passed.
  6898. //
  6899. // returns:
  6900. // dijit._Widget
  6901. // Provides a useful return of the newly created dijit._Widget instance so you
  6902. // can "chain" this function by instantiating, placing, then saving the return value
  6903. // to a variable.
  6904. //
  6905. // example:
  6906. // | // create a Button with no srcNodeRef, and place it in the body:
  6907. // | var button = new dijit.form.Button({ label:"click" }).placeAt(win.body());
  6908. // | // now, 'button' is still the widget reference to the newly created button
  6909. // | button.on("click", function(e){ console.log('click'); }));
  6910. //
  6911. // example:
  6912. // | // create a button out of a node with id="src" and append it to id="wrapper":
  6913. // | var button = new dijit.form.Button({},"src").placeAt("wrapper");
  6914. //
  6915. // example:
  6916. // | // place a new button as the first element of some div
  6917. // | var button = new dijit.form.Button({ label:"click" }).placeAt("wrapper","first");
  6918. //
  6919. // example:
  6920. // | // create a contentpane and add it to a TabContainer
  6921. // | var tc = dijit.byId("myTabs");
  6922. // | new dijit.layout.ContentPane({ href:"foo.html", title:"Wow!" }).placeAt(tc)
  6923. if(reference.declaredClass && reference.addChild){
  6924. reference.addChild(this, position);
  6925. }else{
  6926. domConstruct.place(this.domNode, reference, position);
  6927. }
  6928. return this;
  6929. },
  6930. getTextDir: function(/*String*/ text,/*String*/ originalDir){
  6931. // summary:
  6932. // Return direction of the text.
  6933. // The function overridden in the _BidiSupport module,
  6934. // its main purpose is to calculate the direction of the
  6935. // text, if was defined by the programmer through textDir.
  6936. // tags:
  6937. // protected.
  6938. return originalDir;
  6939. },
  6940. applyTextDir: function(/*===== element, text =====*/){
  6941. // summary:
  6942. // The function overridden in the _BidiSupport module,
  6943. // originally used for setting element.dir according to this.textDir.
  6944. // In this case does nothing.
  6945. // element: DOMNode
  6946. // text: String
  6947. // tags:
  6948. // protected.
  6949. },
  6950. defer: function(fcn, delay){
  6951. // summary:
  6952. // Wrapper to setTimeout to avoid deferred functions executing
  6953. // after the originating widget has been destroyed.
  6954. // Returns an object handle with a remove method (that returns null) (replaces clearTimeout).
  6955. // fcn: function reference
  6956. // delay: Optional number (defaults to 0)
  6957. // tags:
  6958. // protected.
  6959. var timer = setTimeout(lang.hitch(this,
  6960. function(){
  6961. if(!timer){ return; }
  6962. timer = null;
  6963. if(!this._destroyed){
  6964. lang.hitch(this, fcn)();
  6965. }
  6966. }),
  6967. delay || 0
  6968. );
  6969. return {
  6970. remove: function(){
  6971. if(timer){
  6972. clearTimeout(timer);
  6973. timer = null;
  6974. }
  6975. return null; // so this works well: handle = handle.remove();
  6976. }
  6977. };
  6978. }
  6979. });
  6980. });
  6981. }}});
  6982. define("dijit/dijit", [
  6983. ".",
  6984. "./_base",
  6985. "dojo/parser",
  6986. "./_Widget",
  6987. "./_TemplatedMixin",
  6988. "./_Container",
  6989. "./layout/_LayoutWidget",
  6990. "./form/_FormWidget",
  6991. "./form/_FormValueWidget"
  6992. ], function(dijit){
  6993. // module:
  6994. // dijit/dijit
  6995. // summary:
  6996. // A roll-up for common dijit methods
  6997. // All the stuff in _base (these are the function that are guaranteed available without an explicit dojo.require)
  6998. // And some other stuff that we tend to pull in all the time anyway
  6999. return dijit;
  7000. });