dojo.js.uncompressed.js 372 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407
  1. /*
  2. Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.
  3. Available via Academic Free License >= 2.1 OR the modified BSD license.
  4. see: http://dojotoolkit.org/license for details
  5. */
  6. /*
  7. This is an optimized version of Dojo, built for deployment and not for
  8. development. To get sources and documentation, please visit:
  9. http://dojotoolkit.org
  10. */
  11. ;(function(){
  12. /*
  13. dojo, dijit, and dojox must always be the first three, and in that order.
  14. djConfig.scopeMap = [
  15. ["dojo", "fojo"],
  16. ["dijit", "fijit"],
  17. ["dojox", "fojox"]
  18. ]
  19. */
  20. /**Build will replace this comment with a scoped djConfig **/
  21. //The null below can be relaced by a build-time value used instead of djConfig.scopeMap.
  22. var sMap = null;
  23. //See if new scopes need to be defined.
  24. if((sMap || (typeof djConfig != "undefined" && djConfig.scopeMap)) && (typeof window != "undefined")){
  25. var scopeDef = "", scopePrefix = "", scopeSuffix = "", scopeMap = {}, scopeMapRev = {};
  26. sMap = sMap || djConfig.scopeMap;
  27. for(var i = 0; i < sMap.length; i++){
  28. //Make local variables, then global variables that use the locals.
  29. var newScope = sMap[i];
  30. scopeDef += "var " + newScope[0] + " = {}; " + newScope[1] + " = " + newScope[0] + ";" + newScope[1] + "._scopeName = '" + newScope[1] + "';";
  31. scopePrefix += (i == 0 ? "" : ",") + newScope[0];
  32. scopeSuffix += (i == 0 ? "" : ",") + newScope[1];
  33. scopeMap[newScope[0]] = newScope[1];
  34. scopeMapRev[newScope[1]] = newScope[0];
  35. }
  36. eval(scopeDef + "dojo._scopeArgs = [" + scopeSuffix + "];");
  37. dojo._scopePrefixArgs = scopePrefix;
  38. dojo._scopePrefix = "(function(" + scopePrefix + "){";
  39. dojo._scopeSuffix = "})(" + scopeSuffix + ")";
  40. dojo._scopeMap = scopeMap;
  41. dojo._scopeMapRev = scopeMapRev;
  42. }
  43. /*=====
  44. // note:
  45. // 'djConfig' does not exist under 'dojo.*' so that it can be set before the
  46. // 'dojo' variable exists.
  47. // note:
  48. // Setting any of these variables *after* the library has loaded does
  49. // nothing at all.
  50. djConfig = {
  51. // summary:
  52. // Application code can set the global 'djConfig' prior to loading
  53. // the library to override certain global settings for how dojo works.
  54. //
  55. // isDebug: Boolean
  56. // Defaults to `false`. If set to `true`, ensures that Dojo provides
  57. // extended debugging feedback via Firebug. If Firebug is not available
  58. // on your platform, setting `isDebug` to `true` will force Dojo to
  59. // pull in (and display) the version of Firebug Lite which is
  60. // integrated into the Dojo distribution, thereby always providing a
  61. // debugging/logging console when `isDebug` is enabled. Note that
  62. // Firebug's `console.*` methods are ALWAYS defined by Dojo. If
  63. // `isDebug` is false and you are on a platform without Firebug, these
  64. // methods will be defined as no-ops.
  65. isDebug: false,
  66. // debugAtAllCosts: Boolean
  67. // Defaults to `false`. If set to `true`, this triggers an alternate
  68. // mode of the package system in which dependencies are detected and
  69. // only then are resources evaluated in dependency order via
  70. // `<script>` tag inclusion. This may double-request resources and
  71. // cause problems with scripts which expect `dojo.require()` to
  72. // preform synchronously. `debugAtAllCosts` can be an invaluable
  73. // debugging aid, but when using it, ensure that all code which
  74. // depends on Dojo modules is wrapped in `dojo.addOnLoad()` handlers.
  75. // Due to the somewhat unpredictable side-effects of using
  76. // `debugAtAllCosts`, it is strongly recommended that you enable this
  77. // flag as a last resort. `debugAtAllCosts` has no effect when loading
  78. // resources across domains. For usage information, see the
  79. // [Dojo Book](http://dojotoolkit.org/book/book-dojo/part-4-meta-dojo-making-your-dojo-code-run-faster-and-better/debugging-facilities/deb)
  80. debugAtAllCosts: false,
  81. // locale: String
  82. // The locale to assume for loading localized resources in this page,
  83. // specified according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt).
  84. // Must be specified entirely in lowercase, e.g. `en-us` and `zh-cn`.
  85. // See the documentation for `dojo.i18n` and `dojo.requireLocalization`
  86. // for details on loading localized resources. If no locale is specified,
  87. // Dojo assumes the locale of the user agent, according to `navigator.userLanguage`
  88. // or `navigator.language` properties.
  89. locale: undefined,
  90. // extraLocale: Array
  91. // No default value. Specifies additional locales whose
  92. // resources should also be loaded alongside the default locale when
  93. // calls to `dojo.requireLocalization()` are processed.
  94. extraLocale: undefined,
  95. // baseUrl: String
  96. // The directory in which `dojo.js` is located. Under normal
  97. // conditions, Dojo auto-detects the correct location from which it
  98. // was loaded. You may need to manually configure `baseUrl` in cases
  99. // where you have renamed `dojo.js` or in which `<base>` tags confuse
  100. // some browsers (e.g. IE 6). The variable `dojo.baseUrl` is assigned
  101. // either the value of `djConfig.baseUrl` if one is provided or the
  102. // auto-detected root if not. Other modules are located relative to
  103. // this path. The path should end in a slash.
  104. baseUrl: undefined,
  105. // modulePaths: Object
  106. // A map of module names to paths relative to `dojo.baseUrl`. The
  107. // key/value pairs correspond directly to the arguments which
  108. // `dojo.registerModulePath` accepts. Specifiying
  109. // `djConfig.modulePaths = { "foo": "../../bar" }` is the equivalent
  110. // of calling `dojo.registerModulePath("foo", "../../bar");`. Multiple
  111. // modules may be configured via `djConfig.modulePaths`.
  112. modulePaths: {},
  113. // afterOnLoad: Boolean
  114. // Indicates Dojo was added to the page after the page load. In this case
  115. // Dojo will not wait for the page DOMContentLoad/load events and fire
  116. // its dojo.addOnLoad callbacks after making sure all outstanding
  117. // dojo.required modules have loaded. Only works with a built dojo.js,
  118. // it does not work the dojo.js directly from source control.
  119. afterOnLoad: false,
  120. // addOnLoad: Function or Array
  121. // Adds a callback via dojo.addOnLoad. Useful when Dojo is added after
  122. // the page loads and djConfig.afterOnLoad is true. Supports the same
  123. // arguments as dojo.addOnLoad. When using a function reference, use
  124. // `djConfig.addOnLoad = function(){};`. For object with function name use
  125. // `djConfig.addOnLoad = [myObject, "functionName"];` and for object with
  126. // function reference use
  127. // `djConfig.addOnLoad = [myObject, function(){}];`
  128. addOnLoad: null,
  129. // require: Array
  130. // An array of module names to be loaded immediately after dojo.js has been included
  131. // in a page.
  132. require: [],
  133. // defaultDuration: Array
  134. // Default duration, in milliseconds, for wipe and fade animations within dijits.
  135. // Assigned to dijit.defaultDuration.
  136. defaultDuration: 200,
  137. // dojoBlankHtmlUrl: String
  138. // Used by some modules to configure an empty iframe. Used by dojo.io.iframe and
  139. // dojo.back, and dijit popup support in IE where an iframe is needed to make sure native
  140. // controls do not bleed through the popups. Normally this configuration variable
  141. // does not need to be set, except when using cross-domain/CDN Dojo builds.
  142. // Save dojo/resources/blank.html to your domain and set `djConfig.dojoBlankHtmlUrl`
  143. // to the path on your domain your copy of blank.html.
  144. dojoBlankHtmlUrl: undefined,
  145. // ioPublish: Boolean?
  146. // Set this to true to enable publishing of topics for the different phases of
  147. // IO operations. Publishing is done via dojo.publish. See dojo.__IoPublish for a list
  148. // of topics that are published.
  149. ioPublish: false,
  150. // useCustomLogger: Anything?
  151. // If set to a value that evaluates to true such as a string or array and
  152. // isDebug is true and Firebug is not available or running, then it bypasses
  153. // the creation of Firebug Lite allowing you to define your own console object.
  154. useCustomLogger: undefined,
  155. // transparentColor: Array
  156. // Array containing the r, g, b components used as transparent color in dojo.Color;
  157. // if undefined, [255,255,255] (white) will be used.
  158. transparentColor: undefined,
  159. // skipIeDomLoaded: Boolean
  160. // For IE only, skip the DOMContentLoaded hack used. Sometimes it can cause an Operation
  161. // Aborted error if the rest of the page triggers script defers before the DOM is ready.
  162. // If this is config value is set to true, then dojo.addOnLoad callbacks will not be
  163. // triggered until the page load event, which is after images and iframes load. If you
  164. // want to trigger the callbacks sooner, you can put a script block in the bottom of
  165. // your HTML that calls dojo._loadInit();. If you are using multiversion support, change
  166. // "dojo." to the appropriate scope name for dojo.
  167. skipIeDomLoaded: false
  168. }
  169. =====*/
  170. (function(){
  171. // firebug stubs
  172. if(typeof this["loadFirebugConsole"] == "function"){
  173. // for Firebug 1.2
  174. this["loadFirebugConsole"]();
  175. }else{
  176. this.console = this.console || {};
  177. // Be careful to leave 'log' always at the end
  178. var cn = [
  179. "assert", "count", "debug", "dir", "dirxml", "error", "group",
  180. "groupEnd", "info", "profile", "profileEnd", "time", "timeEnd",
  181. "trace", "warn", "log"
  182. ];
  183. var i = 0, tn;
  184. while((tn=cn[i++])){
  185. if(!console[tn]){
  186. (function(){
  187. var tcn = tn+"";
  188. console[tcn] = ('log' in console) ? function(){
  189. var a = Array.apply({}, arguments);
  190. a.unshift(tcn+":");
  191. console["log"](a.join(" "));
  192. } : function(){}
  193. console[tcn]._fake = true;
  194. })();
  195. }
  196. }
  197. }
  198. //TODOC: HOW TO DOC THIS?
  199. // dojo is the root variable of (almost all) our public symbols -- make sure it is defined.
  200. if(typeof dojo == "undefined"){
  201. dojo = {
  202. _scopeName: "dojo",
  203. _scopePrefix: "",
  204. _scopePrefixArgs: "",
  205. _scopeSuffix: "",
  206. _scopeMap: {},
  207. _scopeMapRev: {}
  208. };
  209. }
  210. var d = dojo;
  211. //Need placeholders for dijit and dojox for scoping code.
  212. if(typeof dijit == "undefined"){
  213. dijit = {_scopeName: "dijit"};
  214. }
  215. if(typeof dojox == "undefined"){
  216. dojox = {_scopeName: "dojox"};
  217. }
  218. if(!d._scopeArgs){
  219. d._scopeArgs = [dojo, dijit, dojox];
  220. }
  221. /*=====
  222. dojo.global = {
  223. // summary:
  224. // Alias for the global scope
  225. // (e.g. the window object in a browser).
  226. // description:
  227. // Refer to 'dojo.global' rather than referring to window to ensure your
  228. // code runs correctly in contexts other than web browsers (e.g. Rhino on a server).
  229. }
  230. =====*/
  231. d.global = this;
  232. d.config =/*===== djConfig = =====*/{
  233. isDebug: false,
  234. debugAtAllCosts: false
  235. };
  236. // FIXME: 2.0, drop djConfig support. Use dojoConfig exclusively for global config.
  237. var cfg = typeof djConfig != "undefined" ? djConfig :
  238. typeof dojoConfig != "undefined" ? dojoConfig : null;
  239. if(cfg){
  240. for(var c in cfg){
  241. d.config[c] = cfg[c];
  242. }
  243. }
  244. /*=====
  245. // Override locale setting, if specified
  246. dojo.locale = {
  247. // summary: the locale as defined by Dojo (read-only)
  248. };
  249. =====*/
  250. dojo.locale = d.config.locale;
  251. var rev = "$Rev: 31ff515 $".match(/[0-9a-f]{7,}/);
  252. /*=====
  253. dojo.version = function(){
  254. // summary:
  255. // Version number of the Dojo Toolkit
  256. // major: Integer
  257. // Major version. If total version is "1.2.0beta1", will be 1
  258. // minor: Integer
  259. // Minor version. If total version is "1.2.0beta1", will be 2
  260. // patch: Integer
  261. // Patch version. If total version is "1.2.0beta1", will be 0
  262. // flag: String
  263. // Descriptor flag. If total version is "1.2.0beta1", will be "beta1"
  264. // revision: Number
  265. // The SVN rev from which dojo was pulled
  266. this.major = 0;
  267. this.minor = 0;
  268. this.patch = 0;
  269. this.flag = "";
  270. this.revision = 0;
  271. }
  272. =====*/
  273. dojo.version = {
  274. major: 1, minor: 6, patch: 4, flag: "-20220428-IBM",
  275. revision: rev ? rev[0] : NaN,
  276. toString: function(){
  277. with(d.version){
  278. return major + "." + minor + "." + patch + flag + " (" + revision + ")"; // String
  279. }
  280. }
  281. }
  282. // Register with the OpenAjax hub
  283. if(typeof OpenAjax != "undefined"){
  284. OpenAjax.hub.registerLibrary(dojo._scopeName, "http://dojotoolkit.org", d.version.toString());
  285. }
  286. var extraNames, extraLen, empty = {};
  287. for(var i in {toString: 1}){ extraNames = []; break; }
  288. dojo._extraNames = extraNames = extraNames || ["hasOwnProperty", "valueOf", "isPrototypeOf",
  289. "propertyIsEnumerable", "toLocaleString", "toString", "constructor"];
  290. extraLen = extraNames.length;
  291. dojo._mixin = function(/*Object*/ target, /*Object*/ source){
  292. // summary:
  293. // Adds all properties and methods of source to target. This addition
  294. // is "prototype extension safe", so that instances of objects
  295. // will not pass along prototype defaults.
  296. var name, s, i;
  297. for(name in source){
  298. // the "tobj" condition avoid copying properties in "source"
  299. // inherited from Object.prototype. For example, if target has a custom
  300. // toString() method, don't overwrite it with the toString() method
  301. // that source inherited from Object.prototype
  302. s = source[name];
  303. if(!(name in target) || (target[name] !== s && (!(name in empty) || empty[name] !== s))){
  304. target[name] = s;
  305. }
  306. }
  307. // IE doesn't recognize some custom functions in for..in
  308. if(extraLen && source){
  309. for(i = 0; i < extraLen; ++i){
  310. name = extraNames[i];
  311. s = source[name];
  312. if(!(name in target) || (target[name] !== s && (!(name in empty) || empty[name] !== s))){
  313. target[name] = s;
  314. }
  315. }
  316. }
  317. return target; // Object
  318. }
  319. dojo.mixin = function(/*Object*/obj, /*Object...*/props){
  320. // summary:
  321. // Adds all properties and methods of props to obj and returns the
  322. // (now modified) obj.
  323. // description:
  324. // `dojo.mixin` can mix multiple source objects into a
  325. // destination object which is then returned. Unlike regular
  326. // `for...in` iteration, `dojo.mixin` is also smart about avoiding
  327. // extensions which other toolkits may unwisely add to the root
  328. // object prototype
  329. // obj:
  330. // The object to mix properties into. Also the return value.
  331. // props:
  332. // One or more objects whose values are successively copied into
  333. // obj. If more than one of these objects contain the same value,
  334. // the one specified last in the function call will "win".
  335. // example:
  336. // make a shallow copy of an object
  337. // | var copy = dojo.mixin({}, source);
  338. // example:
  339. // many class constructors often take an object which specifies
  340. // values to be configured on the object. In this case, it is
  341. // often simplest to call `dojo.mixin` on the `this` object:
  342. // | dojo.declare("acme.Base", null, {
  343. // | constructor: function(properties){
  344. // | // property configuration:
  345. // | dojo.mixin(this, properties);
  346. // |
  347. // | console.log(this.quip);
  348. // | // ...
  349. // | },
  350. // | quip: "I wasn't born yesterday, you know - I've seen movies.",
  351. // | // ...
  352. // | });
  353. // |
  354. // | // create an instance of the class and configure it
  355. // | var b = new acme.Base({quip: "That's what it does!" });
  356. // example:
  357. // copy in properties from multiple objects
  358. // | var flattened = dojo.mixin(
  359. // | {
  360. // | name: "Frylock",
  361. // | braces: true
  362. // | },
  363. // | {
  364. // | name: "Carl Brutanananadilewski"
  365. // | }
  366. // | );
  367. // |
  368. // | // will print "Carl Brutanananadilewski"
  369. // | console.log(flattened.name);
  370. // | // will print "true"
  371. // | console.log(flattened.braces);
  372. if(!obj){ obj = {}; }
  373. for(var i=1, l=arguments.length; i<l; i++){
  374. d._mixin(obj, arguments[i]);
  375. }
  376. return obj; // Object
  377. }
  378. dojo._getProp = function(/*Array*/parts, /*Boolean*/create, /*Object*/context){
  379. if(!context){
  380. if(parts[0] && d._scopeMap[parts[0]]) {
  381. // Voodoo code from the old days where "dojo" or "dijit" maps to some special object
  382. // rather than just window.dojo
  383. context = d._scopeMap[parts.shift()][1];
  384. }else{
  385. context = d.global;
  386. }
  387. }
  388. try{
  389. for(var i = 0; i < parts.length; i++){
  390. var p = parts[i];
  391. // Fix for prototype pollution CVE-2021-23450
  392. if (p === '__proto__' || p === 'constructor') {
  393. return;
  394. }
  395. if(!(p in context)){
  396. if(create){
  397. context[p] = {};
  398. }else{
  399. return; // return undefined
  400. }
  401. }
  402. context = context[p];
  403. }
  404. return context; // mixed
  405. }catch(e){
  406. // "p in context" throws an exception when context is a number, boolean, etc. rather than an object,
  407. // so in that corner case just return undefined (by having no return statement)
  408. }
  409. }
  410. dojo.setObject = function(/*String*/name, /*Object*/value, /*Object?*/context){
  411. // summary:
  412. // Set a property from a dot-separated string, such as "A.B.C"
  413. // description:
  414. // Useful for longer api chains where you have to test each object in
  415. // the chain, or when you have an object reference in string format.
  416. // Objects are created as needed along `path`. Returns the passed
  417. // value if setting is successful or `undefined` if not.
  418. // name:
  419. // Path to a property, in the form "A.B.C".
  420. // context:
  421. // Optional. Object to use as root of path. Defaults to
  422. // `dojo.global`.
  423. // example:
  424. // set the value of `foo.bar.baz`, regardless of whether
  425. // intermediate objects already exist:
  426. // | dojo.setObject("foo.bar.baz", value);
  427. // example:
  428. // without `dojo.setObject`, we often see code like this:
  429. // | // ensure that intermediate objects are available
  430. // | if(!obj["parent"]){ obj.parent = {}; }
  431. // | if(!obj.parent["child"]){ obj.parent.child= {}; }
  432. // | // now we can safely set the property
  433. // | obj.parent.child.prop = "some value";
  434. // wheras with `dojo.setObject`, we can shorten that to:
  435. // | dojo.setObject("parent.child.prop", "some value", obj);
  436. var parts=name.split("."), p=parts.pop(), obj=d._getProp(parts, true, context);
  437. return obj && p ? (obj[p]=value) : undefined; // Object
  438. }
  439. dojo.getObject = function(/*String*/name, /*Boolean?*/create, /*Object?*/context){
  440. // summary:
  441. // Get a property from a dot-separated string, such as "A.B.C"
  442. // description:
  443. // Useful for longer api chains where you have to test each object in
  444. // the chain, or when you have an object reference in string format.
  445. // name:
  446. // Path to an property, in the form "A.B.C".
  447. // create:
  448. // Optional. Defaults to `false`. If `true`, Objects will be
  449. // created at any point along the 'path' that is undefined.
  450. // context:
  451. // Optional. Object to use as root of path. Defaults to
  452. // 'dojo.global'. Null may be passed.
  453. return !name ? context : d._getProp(name.split("."), create, context); // Object
  454. }
  455. dojo.exists = function(/*String*/name, /*Object?*/obj){
  456. // summary:
  457. // determine if an object supports a given method
  458. // description:
  459. // useful for longer api chains where you have to test each object in
  460. // the chain. Useful for object and method detection.
  461. // name:
  462. // Path to an object, in the form "A.B.C".
  463. // obj:
  464. // Object to use as root of path. Defaults to
  465. // 'dojo.global'. Null may be passed.
  466. // example:
  467. // | // define an object
  468. // | var foo = {
  469. // | bar: { }
  470. // | };
  471. // |
  472. // | // search the global scope
  473. // | dojo.exists("foo.bar"); // true
  474. // | dojo.exists("foo.bar.baz"); // false
  475. // |
  476. // | // search from a particular scope
  477. // | dojo.exists("bar", foo); // true
  478. // | dojo.exists("bar.baz", foo); // false
  479. return d.getObject(name, false, obj) !== undefined; // Boolean
  480. }
  481. dojo["eval"] = function(/*String*/ scriptFragment){
  482. // summary:
  483. // A legacy method created for use exclusively by internal Dojo methods. Do not use
  484. // this method directly, the behavior of this eval will differ from the normal
  485. // browser eval.
  486. // description:
  487. // Placed in a separate function to minimize size of trapped
  488. // exceptions. Calling eval() directly from some other scope may
  489. // complicate tracebacks on some platforms.
  490. // returns:
  491. // The result of the evaluation. Often `undefined`
  492. return d.global.eval ? d.global.eval(scriptFragment) : eval(scriptFragment); // Object
  493. }
  494. /*=====
  495. dojo.deprecated = function(behaviour, extra, removal){
  496. // summary:
  497. // Log a debug message to indicate that a behavior has been
  498. // deprecated.
  499. // behaviour: String
  500. // The API or behavior being deprecated. Usually in the form
  501. // of "myApp.someFunction()".
  502. // extra: String?
  503. // Text to append to the message. Often provides advice on a
  504. // new function or facility to achieve the same goal during
  505. // the deprecation period.
  506. // removal: String?
  507. // Text to indicate when in the future the behavior will be
  508. // removed. Usually a version number.
  509. // example:
  510. // | dojo.deprecated("myApp.getTemp()", "use myApp.getLocaleTemp() instead", "1.0");
  511. }
  512. dojo.experimental = function(moduleName, extra){
  513. // summary: Marks code as experimental.
  514. // description:
  515. // This can be used to mark a function, file, or module as
  516. // experimental. Experimental code is not ready to be used, and the
  517. // APIs are subject to change without notice. Experimental code may be
  518. // completed deleted without going through the normal deprecation
  519. // process.
  520. // moduleName: String
  521. // The name of a module, or the name of a module file or a specific
  522. // function
  523. // extra: String?
  524. // some additional message for the user
  525. // example:
  526. // | dojo.experimental("dojo.data.Result");
  527. // example:
  528. // | dojo.experimental("dojo.weather.toKelvin()", "PENDING approval from NOAA");
  529. }
  530. =====*/
  531. //Real functions declared in dojo._firebug.firebug.
  532. d.deprecated = d.experimental = function(){};
  533. })();
  534. // vim:ai:ts=4:noet
  535. /*
  536. * loader.js - A bootstrap module. Runs before the hostenv_*.js file. Contains
  537. * all of the package loading methods.
  538. */
  539. (function(){
  540. var d = dojo, currentModule;
  541. d.mixin(d, {
  542. _loadedModules: {},
  543. _inFlightCount: 0,
  544. _hasResource: {},
  545. _modulePrefixes: {
  546. dojo: { name: "dojo", value: "." },
  547. // dojox: { name: "dojox", value: "../dojox" },
  548. // dijit: { name: "dijit", value: "../dijit" },
  549. doh: { name: "doh", value: "../util/doh" },
  550. tests: { name: "tests", value: "tests" }
  551. },
  552. _moduleHasPrefix: function(/*String*/module){
  553. // summary: checks to see if module has been established
  554. var mp = d._modulePrefixes;
  555. return !!(mp[module] && mp[module].value); // Boolean
  556. },
  557. _getModulePrefix: function(/*String*/module){
  558. // summary: gets the prefix associated with module
  559. var mp = d._modulePrefixes;
  560. if(d._moduleHasPrefix(module)){
  561. return mp[module].value; // String
  562. }
  563. return module; // String
  564. },
  565. _loadedUrls: [],
  566. //WARNING:
  567. // This variable is referenced by packages outside of bootstrap:
  568. // FloatingPane.js and undo/browser.js
  569. _postLoad: false,
  570. //Egad! Lots of test files push on this directly instead of using dojo.addOnLoad.
  571. _loaders: [],
  572. _unloaders: [],
  573. _loadNotifying: false
  574. });
  575. dojo._loadPath = function(/*String*/relpath, /*String?*/module, /*Function?*/cb){
  576. // summary:
  577. // Load a Javascript module given a relative path
  578. //
  579. // description:
  580. // Loads and interprets the script located at relpath, which is
  581. // relative to the script root directory. If the script is found but
  582. // its interpretation causes a runtime exception, that exception is
  583. // not caught by us, so the caller will see it. We return a true
  584. // value if and only if the script is found.
  585. //
  586. // relpath:
  587. // A relative path to a script (no leading '/', and typically ending
  588. // in '.js').
  589. // module:
  590. // A module whose existance to check for after loading a path. Can be
  591. // used to determine success or failure of the load.
  592. // cb:
  593. // a callback function to pass the result of evaluating the script
  594. var uri = ((relpath.charAt(0) == '/' || relpath.match(/^\w+:/)) ? "" : d.baseUrl) + relpath;
  595. try{
  596. currentModule = module;
  597. return !module ? d._loadUri(uri, cb) : d._loadUriAndCheck(uri, module, cb); // Boolean
  598. }catch(e){
  599. console.error(e);
  600. return false; // Boolean
  601. }finally{
  602. currentModule = null;
  603. }
  604. }
  605. dojo._loadUri = function(/*String*/uri, /*Function?*/cb){
  606. // summary:
  607. // Loads JavaScript from a URI
  608. // description:
  609. // Reads the contents of the URI, and evaluates the contents. This is
  610. // used to load modules as well as resource bundles. Returns true if
  611. // it succeeded. Returns false if the URI reading failed. Throws if
  612. // the evaluation throws.
  613. // uri: a uri which points at the script to be loaded
  614. // cb:
  615. // a callback function to process the result of evaluating the script
  616. // as an expression, typically used by the resource bundle loader to
  617. // load JSON-style resources
  618. if(d._loadedUrls[uri]){
  619. return true; // Boolean
  620. }
  621. d._inFlightCount++; // block addOnLoad calls that arrive while we're busy downloading
  622. var contents = d._getText(uri, true);
  623. if(contents){ // not 404, et al
  624. d._loadedUrls[uri] = true;
  625. d._loadedUrls.push(uri);
  626. if(cb){
  627. //conditional to support script-inject i18n bundle format
  628. contents = /^define\(/.test(contents) ? contents : '('+contents+')';
  629. }else{
  630. //Only do the scoping if no callback. If a callback is specified,
  631. //it is most likely the i18n bundle stuff.
  632. contents = d._scopePrefix + contents + d._scopeSuffix;
  633. }
  634. if(!d.isIE){ contents += "\r\n//@ sourceURL=" + uri; } // debugging assist for Firebug
  635. var value = d["eval"](contents);
  636. if(cb){ cb(value); }
  637. }
  638. // Check to see if we need to call _callLoaded() due to an addOnLoad() that arrived while we were busy downloading
  639. if(--d._inFlightCount == 0 && d._postLoad && d._loaders.length){
  640. // We shouldn't be allowed to get here but Firefox allows an event
  641. // (mouse, keybd, async xhrGet) to interrupt a synchronous xhrGet.
  642. // If the current script block contains multiple require() statements, then after each
  643. // require() returns, inFlightCount == 0, but we want to hold the _callLoaded() until
  644. // all require()s are done since the out-of-sequence addOnLoad() presumably needs them all.
  645. // setTimeout allows the next require() to start (if needed), and then we check this again.
  646. setTimeout(function(){
  647. // If inFlightCount > 0, then multiple require()s are running sequentially and
  648. // the next require() started after setTimeout() was executed but before we got here.
  649. if(d._inFlightCount == 0){
  650. d._callLoaded();
  651. }
  652. }, 0);
  653. }
  654. return !!contents; // Boolean: contents? true : false
  655. }
  656. // FIXME: probably need to add logging to this method
  657. dojo._loadUriAndCheck = function(/*String*/uri, /*String*/moduleName, /*Function?*/cb){
  658. // summary: calls loadUri then findModule and returns true if both succeed
  659. var ok = false;
  660. try{
  661. ok = d._loadUri(uri, cb);
  662. }catch(e){
  663. console.error("failed loading " + uri + " with error: " + e);
  664. }
  665. return !!(ok && d._loadedModules[moduleName]); // Boolean
  666. }
  667. dojo.loaded = function(){
  668. // summary:
  669. // signal fired when initial environment and package loading is
  670. // complete. You should use dojo.addOnLoad() instead of doing a
  671. // direct dojo.connect() to this method in order to handle
  672. // initialization tasks that require the environment to be
  673. // initialized. In a browser host, declarative widgets will
  674. // be constructed when this function finishes runing.
  675. d._loadNotifying = true;
  676. d._postLoad = true;
  677. var mll = d._loaders;
  678. //Clear listeners so new ones can be added
  679. //For other xdomain package loads after the initial load.
  680. d._loaders = [];
  681. for(var x = 0; x < mll.length; x++){
  682. mll[x]();
  683. }
  684. d._loadNotifying = false;
  685. //Make sure nothing else got added to the onload queue
  686. //after this first run. If something did, and we are not waiting for any
  687. //more inflight resources, run again.
  688. if(d._postLoad && d._inFlightCount == 0 && mll.length){
  689. d._callLoaded();
  690. }
  691. }
  692. dojo.unloaded = function(){
  693. // summary:
  694. // signal fired by impending environment destruction. You should use
  695. // dojo.addOnUnload() instead of doing a direct dojo.connect() to this
  696. // method to perform page/application cleanup methods. See
  697. // dojo.addOnUnload for more info.
  698. var mll = d._unloaders;
  699. while(mll.length){
  700. (mll.pop())();
  701. }
  702. }
  703. d._onto = function(arr, obj, fn){
  704. if(!fn){
  705. arr.push(obj);
  706. }else if(fn){
  707. var func = (typeof fn == "string") ? obj[fn] : fn;
  708. arr.push(function(){ func.call(obj); });
  709. }
  710. }
  711. dojo.ready = dojo.addOnLoad = function(/*Object*/obj, /*String|Function?*/functionName){
  712. // summary:
  713. // Registers a function to be triggered after the DOM and dojo.require() calls
  714. // have finished loading.
  715. //
  716. // description:
  717. // Registers a function to be triggered after the DOM has finished
  718. // loading and `dojo.require` modules have loaded. Widgets declared in markup
  719. // have been instantiated if `djConfig.parseOnLoad` is true when this fires.
  720. //
  721. // Images and CSS files may or may not have finished downloading when
  722. // the specified function is called. (Note that widgets' CSS and HTML
  723. // code is guaranteed to be downloaded before said widgets are
  724. // instantiated, though including css resouces BEFORE any script elements
  725. // is highly recommended).
  726. //
  727. // example:
  728. // Register an anonymous function to run when everything is ready
  729. // | dojo.addOnLoad(function(){ doStuff(); });
  730. //
  731. // example:
  732. // Register a function to run when everything is ready by pointer:
  733. // | var init = function(){ doStuff(); }
  734. // | dojo.addOnLoad(init);
  735. //
  736. // example:
  737. // Register a function to run scoped to `object`, either by name or anonymously:
  738. // | dojo.addOnLoad(object, "functionName");
  739. // | dojo.addOnLoad(object, function(){ doStuff(); });
  740. d._onto(d._loaders, obj, functionName);
  741. //Added for xdomain loading. dojo.addOnLoad is used to
  742. //indicate callbacks after doing some dojo.require() statements.
  743. //In the xdomain case, if all the requires are loaded (after initial
  744. //page load), then immediately call any listeners.
  745. if(d._postLoad && d._inFlightCount == 0 && !d._loadNotifying){
  746. d._callLoaded();
  747. }
  748. }
  749. //Support calling dojo.addOnLoad via djConfig.addOnLoad. Support all the
  750. //call permutations of dojo.addOnLoad. Mainly useful when dojo is added
  751. //to the page after the page has loaded.
  752. var dca = d.config.addOnLoad;
  753. if(dca){
  754. d.addOnLoad[(dca instanceof Array ? "apply" : "call")](d, dca);
  755. }
  756. dojo._modulesLoaded = function(){
  757. if(d._postLoad){ return; }
  758. if(d._inFlightCount > 0){
  759. console.warn("files still in flight!");
  760. return;
  761. }
  762. d._callLoaded();
  763. }
  764. dojo._callLoaded = function(){
  765. // The "object" check is for IE, and the other opera check fixes an
  766. // issue in Opera where it could not find the body element in some
  767. // widget test cases. For 0.9, maybe route all browsers through the
  768. // setTimeout (need protection still for non-browser environments
  769. // though). This might also help the issue with FF 2.0 and freezing
  770. // issues where we try to do sync xhr while background css images are
  771. // being loaded (trac #2572)? Consider for 0.9.
  772. if(typeof setTimeout == "object" || (d.config.useXDomain && d.isOpera)){
  773. setTimeout(
  774. d.isAIR ? function(){ d.loaded(); } : d._scopeName + ".loaded();",
  775. 0);
  776. }else{
  777. d.loaded();
  778. }
  779. }
  780. dojo._getModuleSymbols = function(/*String*/modulename){
  781. // summary:
  782. // Converts a module name in dotted JS notation to an array
  783. // representing the path in the source tree
  784. var syms = modulename.split(".");
  785. for(var i = syms.length; i>0; i--){
  786. var parentModule = syms.slice(0, i).join(".");
  787. if(i == 1 && !d._moduleHasPrefix(parentModule)){
  788. // Support default module directory (sibling of dojo) for top-level modules
  789. syms[0] = "../" + syms[0];
  790. }else{
  791. var parentModulePath = d._getModulePrefix(parentModule);
  792. if(parentModulePath != parentModule){
  793. syms.splice(0, i, parentModulePath);
  794. break;
  795. }
  796. }
  797. }
  798. return syms; // Array
  799. }
  800. dojo._global_omit_module_check = false;
  801. dojo.loadInit = function(/*Function*/init){
  802. // summary:
  803. // Executes a function that needs to be executed for the loader's dojo.requireIf
  804. // resolutions to work. This is needed mostly for the xdomain loader case where
  805. // a function needs to be executed to set up the possible values for a dojo.requireIf
  806. // call.
  807. // init:
  808. // a function reference. Executed immediately.
  809. // description: This function is mainly a marker for the xdomain loader to know parts of
  810. // code that needs be executed outside the function wrappper that is placed around modules.
  811. // The init function could be executed more than once, and it should make no assumptions
  812. // on what is loaded, or what modules are available. Only the functionality in Dojo Base
  813. // is allowed to be used. Avoid using this method. For a valid use case,
  814. // see the source for dojox.gfx.
  815. init();
  816. }
  817. dojo._loadModule = dojo.require = function(/*String*/moduleName, /*Boolean?*/omitModuleCheck){
  818. // summary:
  819. // loads a Javascript module from the appropriate URI
  820. //
  821. // moduleName: String
  822. // module name to load, using periods for separators,
  823. // e.g. "dojo.date.locale". Module paths are de-referenced by dojo's
  824. // internal mapping of locations to names and are disambiguated by
  825. // longest prefix. See `dojo.registerModulePath()` for details on
  826. // registering new modules.
  827. //
  828. // omitModuleCheck: Boolean?
  829. // if `true`, omitModuleCheck skips the step of ensuring that the
  830. // loaded file actually defines the symbol it is referenced by.
  831. // For example if it called as `dojo.require("a.b.c")` and the
  832. // file located at `a/b/c.js` does not define an object `a.b.c`,
  833. // and exception will be throws whereas no exception is raised
  834. // when called as `dojo.require("a.b.c", true)`
  835. //
  836. // description:
  837. // Modules are loaded via dojo.require by using one of two loaders: the normal loader
  838. // and the xdomain loader. The xdomain loader is used when dojo was built with a
  839. // custom build that specified loader=xdomain and the module lives on a modulePath
  840. // that is a whole URL, with protocol and a domain. The versions of Dojo that are on
  841. // the Google and AOL CDNs use the xdomain loader.
  842. //
  843. // If the module is loaded via the xdomain loader, it is an asynchronous load, since
  844. // the module is added via a dynamically created script tag. This
  845. // means that dojo.require() can return before the module has loaded. However, this
  846. // should only happen in the case where you do dojo.require calls in the top-level
  847. // HTML page, or if you purposely avoid the loader checking for dojo.require
  848. // dependencies in your module by using a syntax like dojo["require"] to load the module.
  849. //
  850. // Sometimes it is useful to not have the loader detect the dojo.require calls in the
  851. // module so that you can dynamically load the modules as a result of an action on the
  852. // page, instead of right at module load time.
  853. //
  854. // Also, for script blocks in an HTML page, the loader does not pre-process them, so
  855. // it does not know to download the modules before the dojo.require calls occur.
  856. //
  857. // So, in those two cases, when you want on-the-fly module loading or for script blocks
  858. // in the HTML page, special care must be taken if the dojo.required code is loaded
  859. // asynchronously. To make sure you can execute code that depends on the dojo.required
  860. // modules, be sure to add the code that depends on the modules in a dojo.addOnLoad()
  861. // callback. dojo.addOnLoad waits for all outstanding modules to finish loading before
  862. // executing.
  863. //
  864. // This type of syntax works with both xdomain and normal loaders, so it is good
  865. // practice to always use this idiom for on-the-fly code loading and in HTML script
  866. // blocks. If at some point you change loaders and where the code is loaded from,
  867. // it will all still work.
  868. //
  869. // More on how dojo.require
  870. // `dojo.require("A.B")` first checks to see if symbol A.B is
  871. // defined. If it is, it is simply returned (nothing to do).
  872. //
  873. // If it is not defined, it will look for `A/B.js` in the script root
  874. // directory.
  875. //
  876. // `dojo.require` throws an exception if it cannot find a file
  877. // to load, or if the symbol `A.B` is not defined after loading.
  878. //
  879. // It returns the object `A.B`, but note the caveats above about on-the-fly loading and
  880. // HTML script blocks when the xdomain loader is loading a module.
  881. //
  882. // `dojo.require()` does nothing about importing symbols into
  883. // the current namespace. It is presumed that the caller will
  884. // take care of that.
  885. //
  886. // example:
  887. // To use dojo.require in conjunction with dojo.ready:
  888. //
  889. // | dojo.require("foo");
  890. // | dojo.require("bar");
  891. // | dojo.addOnLoad(function(){
  892. // | //you can now safely do something with foo and bar
  893. // | });
  894. //
  895. // example:
  896. // For example, to import all symbols into a local block, you might write:
  897. //
  898. // | with (dojo.require("A.B")) {
  899. // | ...
  900. // | }
  901. //
  902. // And to import just the leaf symbol to a local variable:
  903. //
  904. // | var B = dojo.require("A.B");
  905. // | ...
  906. //
  907. // returns:
  908. // the required namespace object
  909. omitModuleCheck = d._global_omit_module_check || omitModuleCheck;
  910. //Check if it is already loaded.
  911. var module = d._loadedModules[moduleName];
  912. if(module){
  913. return module;
  914. }
  915. // convert periods to slashes
  916. var relpath = d._getModuleSymbols(moduleName).join("/") + '.js';
  917. var modArg = !omitModuleCheck ? moduleName : null;
  918. var ok = d._loadPath(relpath, modArg);
  919. if(!ok && !omitModuleCheck){
  920. throw new Error("Could not load '" + moduleName + "'; last tried '" + relpath + "'");
  921. }
  922. // check that the symbol was defined
  923. // Don't bother if we're doing xdomain (asynchronous) loading.
  924. if(!omitModuleCheck && !d._isXDomain){
  925. // pass in false so we can give better error
  926. module = d._loadedModules[moduleName];
  927. if(!module){
  928. throw new Error("symbol '" + moduleName + "' is not defined after loading '" + relpath + "'");
  929. }
  930. }
  931. return module;
  932. }
  933. dojo.provide = function(/*String*/ resourceName){
  934. // summary:
  935. // Register a resource with the package system. Works in conjunction with `dojo.require`
  936. //
  937. // description:
  938. // Each javascript source file is called a resource. When a
  939. // resource is loaded by the browser, `dojo.provide()` registers
  940. // that it has been loaded.
  941. //
  942. // Each javascript source file must have at least one
  943. // `dojo.provide()` call at the top of the file, corresponding to
  944. // the file name. For example, `js/dojo/foo.js` must have
  945. // `dojo.provide("dojo.foo");` before any calls to
  946. // `dojo.require()` are made.
  947. //
  948. // For backwards compatibility reasons, in addition to registering
  949. // the resource, `dojo.provide()` also ensures that the javascript
  950. // object for the module exists. For example,
  951. // `dojo.provide("dojox.data.FlickrStore")`, in addition to
  952. // registering that `FlickrStore.js` is a resource for the
  953. // `dojox.data` module, will ensure that the `dojox.data`
  954. // javascript object exists, so that calls like
  955. // `dojo.data.foo = function(){ ... }` don't fail.
  956. //
  957. // In the case of a build where multiple javascript source files
  958. // are combined into one bigger file (similar to a .lib or .jar
  959. // file), that file may contain multiple dojo.provide() calls, to
  960. // note that it includes multiple resources.
  961. //
  962. // resourceName: String
  963. // A dot-sperated string identifying a resource.
  964. //
  965. // example:
  966. // Safely create a `my` object, and make dojo.require("my.CustomModule") work
  967. // | dojo.provide("my.CustomModule");
  968. //Make sure we have a string.
  969. resourceName = resourceName + "";
  970. return (d._loadedModules[resourceName] = d.getObject(resourceName, true)); // Object
  971. }
  972. //Start of old bootstrap2:
  973. dojo.platformRequire = function(/*Object*/modMap){
  974. // summary:
  975. // require one or more modules based on which host environment
  976. // Dojo is currently operating in
  977. // description:
  978. // This method takes a "map" of arrays which one can use to
  979. // optionally load dojo modules. The map is indexed by the
  980. // possible dojo.name_ values, with two additional values:
  981. // "default" and "common". The items in the "default" array will
  982. // be loaded if none of the other items have been choosen based on
  983. // dojo.name_, set by your host environment. The items in the
  984. // "common" array will *always* be loaded, regardless of which
  985. // list is chosen.
  986. // example:
  987. // | dojo.platformRequire({
  988. // | browser: [
  989. // | "foo.sample", // simple module
  990. // | "foo.test",
  991. // | ["foo.bar.baz", true] // skip object check in _loadModule (dojo.require)
  992. // | ],
  993. // | default: [ "foo.sample._base" ],
  994. // | common: [ "important.module.common" ]
  995. // | });
  996. var common = modMap.common || [];
  997. var result = common.concat(modMap[d._name] || modMap["default"] || []);
  998. for(var x=0; x<result.length; x++){
  999. var curr = result[x];
  1000. if(curr.constructor == Array){
  1001. d._loadModule.apply(d, curr);
  1002. }else{
  1003. d._loadModule(curr);
  1004. }
  1005. }
  1006. }
  1007. dojo.requireIf = function(/*Boolean*/ condition, /*String*/ resourceName){
  1008. // summary:
  1009. // If the condition is true then call `dojo.require()` for the specified
  1010. // resource
  1011. //
  1012. // example:
  1013. // | dojo.requireIf(dojo.isBrowser, "my.special.Module");
  1014. if(condition === true){
  1015. // FIXME: why do we support chained require()'s here? does the build system?
  1016. var args = [];
  1017. for(var i = 1; i < arguments.length; i++){
  1018. args.push(arguments[i]);
  1019. }
  1020. d.require.apply(d, args);
  1021. }
  1022. }
  1023. dojo.requireAfterIf = d.requireIf;
  1024. dojo.registerModulePath = function(/*String*/module, /*String*/prefix){
  1025. // summary:
  1026. // Maps a module name to a path
  1027. // description:
  1028. // An unregistered module is given the default path of ../[module],
  1029. // relative to Dojo root. For example, module acme is mapped to
  1030. // ../acme. If you want to use a different module name, use
  1031. // dojo.registerModulePath.
  1032. // example:
  1033. // If your dojo.js is located at this location in the web root:
  1034. // | /myapp/js/dojo/dojo/dojo.js
  1035. // and your modules are located at:
  1036. // | /myapp/js/foo/bar.js
  1037. // | /myapp/js/foo/baz.js
  1038. // | /myapp/js/foo/thud/xyzzy.js
  1039. // Your application can tell Dojo to locate the "foo" namespace by calling:
  1040. // | dojo.registerModulePath("foo", "../../foo");
  1041. // At which point you can then use dojo.require() to load the
  1042. // modules (assuming they provide() the same things which are
  1043. // required). The full code might be:
  1044. // | <script type="text/javascript"
  1045. // | src="/myapp/js/dojo/dojo/dojo.js"></script>
  1046. // | <script type="text/javascript">
  1047. // | dojo.registerModulePath("foo", "../../foo");
  1048. // | dojo.require("foo.bar");
  1049. // | dojo.require("foo.baz");
  1050. // | dojo.require("foo.thud.xyzzy");
  1051. // | </script>
  1052. d._modulePrefixes[module] = { name: module, value: prefix };
  1053. };
  1054. dojo.requireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale, /*String?*/availableFlatLocales){
  1055. // summary:
  1056. // Declares translated resources and loads them if necessary, in the
  1057. // same style as dojo.require. Contents of the resource bundle are
  1058. // typically strings, but may be any name/value pair, represented in
  1059. // JSON format. See also `dojo.i18n.getLocalization`.
  1060. //
  1061. // description:
  1062. // Load translated resource bundles provided underneath the "nls"
  1063. // directory within a package. Translated resources may be located in
  1064. // different packages throughout the source tree.
  1065. //
  1066. // Each directory is named for a locale as specified by RFC 3066,
  1067. // (http://www.ietf.org/rfc/rfc3066.txt), normalized in lowercase.
  1068. // Note that the two bundles in the example do not define all the
  1069. // same variants. For a given locale, bundles will be loaded for
  1070. // that locale and all more general locales above it, including a
  1071. // fallback at the root directory. For example, a declaration for
  1072. // the "de-at" locale will first load `nls/de-at/bundleone.js`,
  1073. // then `nls/de/bundleone.js` and finally `nls/bundleone.js`. The
  1074. // data will be flattened into a single Object so that lookups
  1075. // will follow this cascading pattern. An optional build step can
  1076. // preload the bundles to avoid data redundancy and the multiple
  1077. // network hits normally required to load these resources.
  1078. //
  1079. // moduleName:
  1080. // name of the package containing the "nls" directory in which the
  1081. // bundle is found
  1082. //
  1083. // bundleName:
  1084. // bundle name, i.e. the filename without the '.js' suffix. Using "nls" as a
  1085. // a bundle name is not supported, since "nls" is the name of the folder
  1086. // that holds bundles. Using "nls" as the bundle name will cause problems
  1087. // with the custom build.
  1088. //
  1089. // locale:
  1090. // the locale to load (optional) By default, the browser's user
  1091. // locale as defined by dojo.locale
  1092. //
  1093. // availableFlatLocales:
  1094. // A comma-separated list of the available, flattened locales for this
  1095. // bundle. This argument should only be set by the build process.
  1096. //
  1097. // example:
  1098. // A particular widget may define one or more resource bundles,
  1099. // structured in a program as follows, where moduleName is
  1100. // mycode.mywidget and bundleNames available include bundleone and
  1101. // bundletwo:
  1102. // | ...
  1103. // | mycode/
  1104. // | mywidget/
  1105. // | nls/
  1106. // | bundleone.js (the fallback translation, English in this example)
  1107. // | bundletwo.js (also a fallback translation)
  1108. // | de/
  1109. // | bundleone.js
  1110. // | bundletwo.js
  1111. // | de-at/
  1112. // | bundleone.js
  1113. // | en/
  1114. // | (empty; use the fallback translation)
  1115. // | en-us/
  1116. // | bundleone.js
  1117. // | en-gb/
  1118. // | bundleone.js
  1119. // | es/
  1120. // | bundleone.js
  1121. // | bundletwo.js
  1122. // | ...etc
  1123. // | ...
  1124. //
  1125. d.require("dojo.i18n");
  1126. d.i18n._requireLocalization.apply(d.hostenv, arguments);
  1127. };
  1128. var ore = new RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$"),
  1129. ire = new RegExp("^((([^\\[:]+):)?([^@]+)@)?(\\[([^\\]]+)\\]|([^\\[:]*))(:([0-9]+))?$");
  1130. dojo._Url = function(/*dojo._Url|String...*/){
  1131. // summary:
  1132. // Constructor to create an object representing a URL.
  1133. // It is marked as private, since we might consider removing
  1134. // or simplifying it.
  1135. // description:
  1136. // Each argument is evaluated in order relative to the next until
  1137. // a canonical uri is produced. To get an absolute Uri relative to
  1138. // the current document use:
  1139. // new dojo._Url(document.baseURI, url)
  1140. var n = null,
  1141. _a = arguments,
  1142. uri = [_a[0]];
  1143. // resolve uri components relative to each other
  1144. for(var i = 1; i<_a.length; i++){
  1145. if(!_a[i]){ continue; }
  1146. // Safari doesn't support this.constructor so we have to be explicit
  1147. // FIXME: Tracked (and fixed) in Webkit bug 3537.
  1148. // http://bugs.webkit.org/show_bug.cgi?id=3537
  1149. var relobj = new d._Url(_a[i]+""),
  1150. uriobj = new d._Url(uri[0]+"");
  1151. if(
  1152. relobj.path == "" &&
  1153. !relobj.scheme &&
  1154. !relobj.authority &&
  1155. !relobj.query
  1156. ){
  1157. if(relobj.fragment != n){
  1158. uriobj.fragment = relobj.fragment;
  1159. }
  1160. relobj = uriobj;
  1161. }else if(!relobj.scheme){
  1162. relobj.scheme = uriobj.scheme;
  1163. if(!relobj.authority){
  1164. relobj.authority = uriobj.authority;
  1165. if(relobj.path.charAt(0) != "/"){
  1166. var path = uriobj.path.substring(0,
  1167. uriobj.path.lastIndexOf("/") + 1) + relobj.path;
  1168. var segs = path.split("/");
  1169. for(var j = 0; j < segs.length; j++){
  1170. if(segs[j] == "."){
  1171. // flatten "./" references
  1172. if(j == segs.length - 1){
  1173. segs[j] = "";
  1174. }else{
  1175. segs.splice(j, 1);
  1176. j--;
  1177. }
  1178. }else if(j > 0 && !(j == 1 && segs[0] == "") &&
  1179. segs[j] == ".." && segs[j-1] != ".."){
  1180. // flatten "../" references
  1181. if(j == (segs.length - 1)){
  1182. segs.splice(j, 1);
  1183. segs[j - 1] = "";
  1184. }else{
  1185. segs.splice(j - 1, 2);
  1186. j -= 2;
  1187. }
  1188. }
  1189. }
  1190. relobj.path = segs.join("/");
  1191. }
  1192. }
  1193. }
  1194. uri = [];
  1195. if(relobj.scheme){
  1196. uri.push(relobj.scheme, ":");
  1197. }
  1198. if(relobj.authority){
  1199. uri.push("//", relobj.authority);
  1200. }
  1201. uri.push(relobj.path);
  1202. if(relobj.query){
  1203. uri.push("?", relobj.query);
  1204. }
  1205. if(relobj.fragment){
  1206. uri.push("#", relobj.fragment);
  1207. }
  1208. }
  1209. this.uri = uri.join("");
  1210. // break the uri into its main components
  1211. var r = this.uri.match(ore);
  1212. this.scheme = r[2] || (r[1] ? "" : n);
  1213. this.authority = r[4] || (r[3] ? "" : n);
  1214. this.path = r[5]; // can never be undefined
  1215. this.query = r[7] || (r[6] ? "" : n);
  1216. this.fragment = r[9] || (r[8] ? "" : n);
  1217. if(this.authority != n){
  1218. // server based naming authority
  1219. r = this.authority.match(ire);
  1220. this.user = r[3] || n;
  1221. this.password = r[4] || n;
  1222. this.host = r[6] || r[7]; // ipv6 || ipv4
  1223. this.port = r[9] || n;
  1224. }
  1225. }
  1226. dojo._Url.prototype.toString = function(){ return this.uri; };
  1227. dojo.moduleUrl = function(/*String*/module, /*dojo._Url||String*/url){
  1228. // summary:
  1229. // Returns a `dojo._Url` object relative to a module.
  1230. // example:
  1231. // | var pngPath = dojo.moduleUrl("acme","images/small.png");
  1232. // | console.dir(pngPath); // list the object properties
  1233. // | // create an image and set it's source to pngPath's value:
  1234. // | var img = document.createElement("img");
  1235. // | // NOTE: we assign the string representation of the url object
  1236. // | img.src = pngPath.toString();
  1237. // | // add our image to the document
  1238. // | dojo.body().appendChild(img);
  1239. // example:
  1240. // you may de-reference as far as you like down the package
  1241. // hierarchy. This is sometimes handy to avoid lenghty relative
  1242. // urls or for building portable sub-packages. In this example,
  1243. // the `acme.widget` and `acme.util` directories may be located
  1244. // under different roots (see `dojo.registerModulePath`) but the
  1245. // the modules which reference them can be unaware of their
  1246. // relative locations on the filesystem:
  1247. // | // somewhere in a configuration block
  1248. // | dojo.registerModulePath("acme.widget", "../../acme/widget");
  1249. // | dojo.registerModulePath("acme.util", "../../util");
  1250. // |
  1251. // | // ...
  1252. // |
  1253. // | // code in a module using acme resources
  1254. // | var tmpltPath = dojo.moduleUrl("acme.widget","templates/template.html");
  1255. // | var dataPath = dojo.moduleUrl("acme.util","resources/data.json");
  1256. var loc = d._getModuleSymbols(module).join('/');
  1257. if(!loc){ return null; }
  1258. if(loc.lastIndexOf("/") != loc.length-1){
  1259. loc += "/";
  1260. }
  1261. //If the path is an absolute path (starts with a / or is on another
  1262. //domain/xdomain) then don't add the baseUrl.
  1263. var colonIndex = loc.indexOf(":");
  1264. if(loc.charAt(0) != "/" && (colonIndex == -1 || colonIndex > loc.indexOf("/"))){
  1265. loc = d.baseUrl + loc;
  1266. }
  1267. return new d._Url(loc, url); // dojo._Url
  1268. };
  1269. })();
  1270. /*=====
  1271. dojo.isBrowser = {
  1272. // example:
  1273. // | if(dojo.isBrowser){ ... }
  1274. };
  1275. dojo.isFF = {
  1276. // example:
  1277. // | if(dojo.isFF > 1){ ... }
  1278. };
  1279. dojo.isIE = {
  1280. // example:
  1281. // | if(dojo.isIE > 6){
  1282. // | // we are IE7
  1283. // | }
  1284. };
  1285. dojo.isSafari = {
  1286. // example:
  1287. // | if(dojo.isSafari){ ... }
  1288. // example:
  1289. // Detect iPhone:
  1290. // | if(dojo.isSafari && navigator.userAgent.indexOf("iPhone") != -1){
  1291. // | // we are iPhone. Note, iPod touch reports "iPod" above and fails this test.
  1292. // | }
  1293. };
  1294. dojo = {
  1295. // isBrowser: Boolean
  1296. // True if the client is a web-browser
  1297. isBrowser: true,
  1298. // isFF: Number | undefined
  1299. // Version as a Number if client is FireFox. undefined otherwise. Corresponds to
  1300. // major detected FireFox version (1.5, 2, 3, etc.)
  1301. isFF: 2,
  1302. // isIE: Number | undefined
  1303. // Version as a Number if client is MSIE(PC). undefined otherwise. Corresponds to
  1304. // major detected IE version (6, 7, 8, etc.)
  1305. isIE: 6,
  1306. // isKhtml: Number | undefined
  1307. // Version as a Number if client is a KHTML browser. undefined otherwise. Corresponds to major
  1308. // detected version.
  1309. isKhtml: 0,
  1310. // isWebKit: Number | undefined
  1311. // Version as a Number if client is a WebKit-derived browser (Konqueror,
  1312. // Safari, Chrome, etc.). undefined otherwise.
  1313. isWebKit: 0,
  1314. // isMozilla: Number | undefined
  1315. // Version as a Number if client is a Mozilla-based browser (Firefox,
  1316. // SeaMonkey). undefined otherwise. Corresponds to major detected version.
  1317. isMozilla: 0,
  1318. // isOpera: Number | undefined
  1319. // Version as a Number if client is Opera. undefined otherwise. Corresponds to
  1320. // major detected version.
  1321. isOpera: 0,
  1322. // isSafari: Number | undefined
  1323. // Version as a Number if client is Safari or iPhone. undefined otherwise.
  1324. isSafari: 0,
  1325. // isChrome: Number | undefined
  1326. // Version as a Number if client is Chrome browser. undefined otherwise.
  1327. isChrome: 0
  1328. // isMac: Boolean
  1329. // True if the client runs on Mac
  1330. }
  1331. =====*/
  1332. if(typeof window != 'undefined'){
  1333. dojo.isBrowser = true;
  1334. dojo._name = "browser";
  1335. // attempt to figure out the path to dojo if it isn't set in the config
  1336. (function(){
  1337. var d = dojo;
  1338. // this is a scope protection closure. We set browser versions and grab
  1339. // the URL we were loaded from here.
  1340. // grab the node we were loaded from
  1341. if(document && document.getElementsByTagName){
  1342. var scripts = document.getElementsByTagName("script");
  1343. var rePkg = /dojo(\.xd)?\.js(\W|$)/i;
  1344. for(var i = 0; i < scripts.length; i++){
  1345. var src = scripts[i].getAttribute("src");
  1346. if(!src){ continue; }
  1347. var m = src.match(rePkg);
  1348. if(m){
  1349. // find out where we came from
  1350. if(!d.config.baseUrl){
  1351. d.config.baseUrl = src.substring(0, m.index);
  1352. }
  1353. // and find out if we need to modify our behavior
  1354. var cfg = (scripts[i].getAttribute("djConfig") || scripts[i].getAttribute("data-dojo-config"));
  1355. if(cfg){
  1356. var cfgo = eval("({ "+cfg+" })");
  1357. for(var x in cfgo){
  1358. dojo.config[x] = cfgo[x];
  1359. }
  1360. }
  1361. break; // "first Dojo wins"
  1362. }
  1363. }
  1364. }
  1365. d.baseUrl = d.config.baseUrl;
  1366. // fill in the rendering support information in dojo.render.*
  1367. var n = navigator;
  1368. var dua = n.userAgent,
  1369. dav = n.appVersion,
  1370. tv = parseFloat(dav);
  1371. if(dua.indexOf("Opera") >= 0){ d.isOpera = tv; }
  1372. if(dua.indexOf("AdobeAIR") >= 0){ d.isAIR = 1; }
  1373. d.isKhtml = (dav.indexOf("Konqueror") >= 0) ? tv : 0;
  1374. d.isWebKit = parseFloat(dua.split("WebKit/")[1]) || undefined;
  1375. d.isChrome = parseFloat(dua.split("Chrome/")[1]) || undefined;
  1376. d.isMac = dav.indexOf("Macintosh") >= 0;
  1377. // safari detection derived from:
  1378. // http://developer.apple.com/internet/safari/faq.html#anchor2
  1379. // http://developer.apple.com/internet/safari/uamatrix.html
  1380. var index = Math.max(dav.indexOf("WebKit"), dav.indexOf("Safari"), 0);
  1381. if(index && !dojo.isChrome){
  1382. // try to grab the explicit Safari version first. If we don't get
  1383. // one, look for less than 419.3 as the indication that we're on something
  1384. // "Safari 2-ish".
  1385. d.isSafari = parseFloat(dav.split("Version/")[1]);
  1386. if(!d.isSafari || parseFloat(dav.substr(index + 7)) <= 419.3){
  1387. d.isSafari = 2;
  1388. }
  1389. }
  1390. if(dua.indexOf("Gecko") >= 0 && !d.isKhtml && !d.isWebKit){ d.isMozilla = d.isMoz = tv; }
  1391. if(d.isMoz){
  1392. //We really need to get away from this. Consider a sane isGecko approach for the future.
  1393. d.isFF = parseFloat(dua.split("Firefox/")[1] || dua.split("Minefield/")[1]) || undefined;
  1394. }
  1395. if(document.all && !d.isOpera){
  1396. d.isIE = parseFloat(dav.split("MSIE ")[1]) || undefined;
  1397. //In cases where the page has an HTTP header or META tag with
  1398. //X-UA-Compatible, then it is in emulation mode.
  1399. //Make sure isIE reflects the desired version.
  1400. //document.documentMode of 5 means quirks mode.
  1401. //Only switch the value if documentMode's major version
  1402. //is different from isIE's major version.
  1403. var mode = document.documentMode;
  1404. if(mode && mode != 5 && Math.floor(d.isIE) != mode){
  1405. d.isIE = mode;
  1406. }
  1407. }
  1408. //Workaround to get local file loads of dojo to work on IE 7
  1409. //by forcing to not use native xhr.
  1410. if(dojo.isIE && window.location.protocol === "file:"){
  1411. dojo.config.ieForceActiveXXhr=true;
  1412. }
  1413. d.isQuirks = document.compatMode == "BackCompat";
  1414. // TODO: is the HTML LANG attribute relevant?
  1415. d.locale = dojo.config.locale || (d.isIE ? n.userLanguage : n.language).toLowerCase();
  1416. // These are in order of decreasing likelihood; this will change in time.
  1417. d._XMLHTTP_PROGIDS = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'];
  1418. d._xhrObj = function(){
  1419. // summary:
  1420. // does the work of portably generating a new XMLHTTPRequest object.
  1421. var http, last_e;
  1422. if(!dojo.isIE || !dojo.config.ieForceActiveXXhr){
  1423. try{ http = new XMLHttpRequest(); }catch(e){}
  1424. }
  1425. if(!http){
  1426. for(var i=0; i<3; ++i){
  1427. var progid = d._XMLHTTP_PROGIDS[i];
  1428. try{
  1429. http = new ActiveXObject(progid);
  1430. }catch(e){
  1431. last_e = e;
  1432. }
  1433. if(http){
  1434. d._XMLHTTP_PROGIDS = [progid]; // so faster next time
  1435. break;
  1436. }
  1437. }
  1438. }
  1439. if(!http){
  1440. throw new Error("XMLHTTP not available: "+last_e);
  1441. }
  1442. return http; // XMLHTTPRequest instance
  1443. }
  1444. d._isDocumentOk = function(http){
  1445. var stat = http.status || 0,
  1446. lp = location.protocol;
  1447. return (stat >= 200 && stat < 300) || // Boolean
  1448. stat == 304 || // allow any 2XX response code
  1449. stat == 1223 || // get it out of the cache
  1450. // Internet Explorer mangled the status code
  1451. // Internet Explorer mangled the status code OR we're Titanium/browser chrome/chrome extension requesting a local file
  1452. (!stat && (lp == "file:" || lp == "chrome:" || lp == "chrome-extension:" || lp == "app:"));
  1453. }
  1454. //See if base tag is in use.
  1455. //This is to fix http://trac.dojotoolkit.org/ticket/3973,
  1456. //but really, we need to find out how to get rid of the dojo._Url reference
  1457. //below and still have DOH work with the dojo.i18n test following some other
  1458. //test that uses the test frame to load a document (trac #2757).
  1459. //Opera still has problems, but perhaps a larger issue of base tag support
  1460. //with XHR requests (hasBase is true, but the request is still made to document
  1461. //path, not base path).
  1462. var owloc = window.location+"";
  1463. var base = document.getElementsByTagName("base");
  1464. var hasBase = (base && base.length > 0);
  1465. d._getText = function(/*URI*/ uri, /*Boolean*/ fail_ok){
  1466. // summary: Read the contents of the specified uri and return those contents.
  1467. // uri:
  1468. // A relative or absolute uri. If absolute, it still must be in
  1469. // the same "domain" as we are.
  1470. // fail_ok:
  1471. // Default false. If fail_ok and loading fails, return null
  1472. // instead of throwing.
  1473. // returns: The response text. null is returned when there is a
  1474. // failure and failure is okay (an exception otherwise)
  1475. // NOTE: must be declared before scope switches ie. this._xhrObj()
  1476. var http = d._xhrObj();
  1477. if(!hasBase && dojo._Url){
  1478. uri = (new dojo._Url(owloc, uri)).toString();
  1479. }
  1480. if(d.config.cacheBust){
  1481. //Make sure we have a string before string methods are used on uri
  1482. uri += "";
  1483. uri += (uri.indexOf("?") == -1 ? "?" : "&") + String(d.config.cacheBust).replace(/\W+/g,"");
  1484. }
  1485. http.open('GET', uri, false);
  1486. try{
  1487. http.send(null);
  1488. if(!d._isDocumentOk(http)){
  1489. var err = Error("Unable to load "+uri+" status:"+ http.status);
  1490. err.status = http.status;
  1491. err.responseText = http.responseText;
  1492. throw err;
  1493. }
  1494. }catch(e){
  1495. if(fail_ok){ return null; } // null
  1496. // rethrow the exception
  1497. throw e;
  1498. }
  1499. return http.responseText; // String
  1500. }
  1501. var _w = window;
  1502. var _handleNodeEvent = function(/*String*/evtName, /*Function*/fp){
  1503. // summary:
  1504. // non-destructively adds the specified function to the node's
  1505. // evtName handler.
  1506. // evtName: should be in the form "onclick" for "onclick" handlers.
  1507. // Make sure you pass in the "on" part.
  1508. var _a = _w.attachEvent || _w.addEventListener;
  1509. evtName = _w.attachEvent ? evtName : evtName.substring(2);
  1510. _a(evtName, function(){
  1511. fp.apply(_w, arguments);
  1512. }, false);
  1513. };
  1514. d._windowUnloaders = [];
  1515. d.windowUnloaded = function(){
  1516. // summary:
  1517. // signal fired by impending window destruction. You may use
  1518. // dojo.addOnWindowUnload() to register a listener for this
  1519. // event. NOTE: if you wish to dojo.connect() to this method
  1520. // to perform page/application cleanup, be aware that this
  1521. // event WILL NOT fire if no handler has been registered with
  1522. // dojo.addOnWindowUnload. This behavior started in Dojo 1.3.
  1523. // Previous versions always triggered dojo.windowUnloaded. See
  1524. // dojo.addOnWindowUnload for more info.
  1525. var mll = d._windowUnloaders;
  1526. while(mll.length){
  1527. (mll.pop())();
  1528. }
  1529. d = null;
  1530. };
  1531. var _onWindowUnloadAttached = 0;
  1532. d.addOnWindowUnload = function(/*Object?|Function?*/obj, /*String|Function?*/functionName){
  1533. // summary:
  1534. // registers a function to be triggered when window.onunload
  1535. // fires.
  1536. // description:
  1537. // The first time that addOnWindowUnload is called Dojo
  1538. // will register a page listener to trigger your unload
  1539. // handler with. Note that registering these handlers may
  1540. // destory "fastback" page caching in browsers that support
  1541. // it. Be careful trying to modify the DOM or access
  1542. // JavaScript properties during this phase of page unloading:
  1543. // they may not always be available. Consider
  1544. // dojo.addOnUnload() if you need to modify the DOM or do
  1545. // heavy JavaScript work since it fires at the eqivalent of
  1546. // the page's "onbeforeunload" event.
  1547. // example:
  1548. // | dojo.addOnWindowUnload(functionPointer)
  1549. // | dojo.addOnWindowUnload(object, "functionName");
  1550. // | dojo.addOnWindowUnload(object, function(){ /* ... */});
  1551. d._onto(d._windowUnloaders, obj, functionName);
  1552. if(!_onWindowUnloadAttached){
  1553. _onWindowUnloadAttached = 1;
  1554. _handleNodeEvent("onunload", d.windowUnloaded);
  1555. }
  1556. };
  1557. var _onUnloadAttached = 0;
  1558. d.addOnUnload = function(/*Object?|Function?*/obj, /*String|Function?*/functionName){
  1559. // summary:
  1560. // registers a function to be triggered when the page unloads.
  1561. // description:
  1562. // The first time that addOnUnload is called Dojo will
  1563. // register a page listener to trigger your unload handler
  1564. // with.
  1565. //
  1566. // In a browser enviroment, the functions will be triggered
  1567. // during the window.onbeforeunload event. Be careful of doing
  1568. // too much work in an unload handler. onbeforeunload can be
  1569. // triggered if a link to download a file is clicked, or if
  1570. // the link is a javascript: link. In these cases, the
  1571. // onbeforeunload event fires, but the document is not
  1572. // actually destroyed. So be careful about doing destructive
  1573. // operations in a dojo.addOnUnload callback.
  1574. //
  1575. // Further note that calling dojo.addOnUnload will prevent
  1576. // browsers from using a "fast back" cache to make page
  1577. // loading via back button instantaneous.
  1578. // example:
  1579. // | dojo.addOnUnload(functionPointer)
  1580. // | dojo.addOnUnload(object, "functionName")
  1581. // | dojo.addOnUnload(object, function(){ /* ... */});
  1582. d._onto(d._unloaders, obj, functionName);
  1583. if(!_onUnloadAttached){
  1584. _onUnloadAttached = 1;
  1585. _handleNodeEvent("onbeforeunload", dojo.unloaded);
  1586. }
  1587. };
  1588. })();
  1589. //START DOMContentLoaded
  1590. dojo._initFired = false;
  1591. dojo._loadInit = function(e){
  1592. if(dojo._scrollIntervalId){
  1593. clearInterval(dojo._scrollIntervalId);
  1594. dojo._scrollIntervalId = 0;
  1595. }
  1596. if(!dojo._initFired){
  1597. dojo._initFired = true;
  1598. //Help out IE to avoid memory leak.
  1599. if(!dojo.config.afterOnLoad && window.detachEvent){
  1600. window.detachEvent("onload", dojo._loadInit);
  1601. }
  1602. if(dojo._inFlightCount == 0){
  1603. dojo._modulesLoaded();
  1604. }
  1605. }
  1606. }
  1607. if(!dojo.config.afterOnLoad){
  1608. if(document.addEventListener){
  1609. //Standards. Hooray! Assumption here that if standards based,
  1610. //it knows about DOMContentLoaded. It is OK if it does not, the fall through
  1611. //to window onload should be good enough.
  1612. document.addEventListener("DOMContentLoaded", dojo._loadInit, false);
  1613. window.addEventListener("load", dojo._loadInit, false);
  1614. }else if(window.attachEvent){
  1615. window.attachEvent("onload", dojo._loadInit);
  1616. //DOMContentLoaded approximation. Diego Perini found this MSDN article
  1617. //that indicates doScroll is available after DOM ready, so do a setTimeout
  1618. //to check when it is available.
  1619. //http://msdn.microsoft.com/en-us/library/ms531426.aspx
  1620. if(!dojo.config.skipIeDomLoaded && self === self.top){
  1621. dojo._scrollIntervalId = setInterval(function (){
  1622. try{
  1623. //When dojo is loaded into an iframe in an IE HTML Application
  1624. //(HTA), such as in a selenium test, javascript in the iframe
  1625. //can't see anything outside of it, so self===self.top is true,
  1626. //but the iframe is not the top window and doScroll will be
  1627. //available before document.body is set. Test document.body
  1628. //before trying the doScroll trick
  1629. if(document.body){
  1630. document.documentElement.doScroll("left");
  1631. dojo._loadInit();
  1632. }
  1633. }catch (e){}
  1634. }, 30);
  1635. }
  1636. }
  1637. }
  1638. if(dojo.isIE){
  1639. try{
  1640. (function(){
  1641. document.namespaces.add("v", "urn:schemas-microsoft-com:vml");
  1642. var vmlElems = ["*", "group", "roundrect", "oval", "shape", "rect", "imagedata", "path", "textpath", "text"],
  1643. i = 0, l = 1, s = document.createStyleSheet();
  1644. if(dojo.isIE >= 8){
  1645. i = 1;
  1646. l = vmlElems.length;
  1647. }
  1648. for(; i < l; ++i){
  1649. s.addRule("v\\:" + vmlElems[i], "behavior:url(#default#VML); display:inline-block");
  1650. }
  1651. })();
  1652. }catch(e){}
  1653. }
  1654. //END DOMContentLoaded
  1655. /*
  1656. OpenAjax.subscribe("OpenAjax", "onload", function(){
  1657. if(dojo._inFlightCount == 0){
  1658. dojo._modulesLoaded();
  1659. }
  1660. });
  1661. OpenAjax.subscribe("OpenAjax", "onunload", function(){
  1662. dojo.unloaded();
  1663. });
  1664. */
  1665. } //if (typeof window != 'undefined')
  1666. //Register any module paths set up in djConfig. Need to do this
  1667. //in the hostenvs since hostenv_browser can read djConfig from a
  1668. //script tag's attribute.
  1669. (function(){
  1670. var mp = dojo.config["modulePaths"];
  1671. if(mp){
  1672. for(var param in mp){
  1673. dojo.registerModulePath(param, mp[param]);
  1674. }
  1675. }
  1676. })();
  1677. //Load debug code if necessary.
  1678. if(dojo.config.isDebug){
  1679. dojo.require("dojo._firebug.firebug");
  1680. }
  1681. if(dojo.config.debugAtAllCosts){
  1682. // this breaks the new AMD based module loader. The XDomain won't be necessary
  1683. // anyway if you switch to the asynchronous loader
  1684. //dojo.config.useXDomain = true;
  1685. //dojo.require("dojo._base._loader.loader_xd");
  1686. dojo.require("dojo._base._loader.loader_debug");
  1687. dojo.require("dojo.i18n");
  1688. }
  1689. if(!dojo._hasResource["dojo._base.lang"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  1690. dojo._hasResource["dojo._base.lang"] = true;
  1691. dojo.provide("dojo._base.lang");
  1692. (function(){
  1693. var d = dojo, opts = Object.prototype.toString;
  1694. // Crockford (ish) functions
  1695. dojo.isString = function(/*anything*/ it){
  1696. // summary:
  1697. // Return true if it is a String
  1698. return (typeof it == "string" || it instanceof String); // Boolean
  1699. };
  1700. dojo.isArray = function(/*anything*/ it){
  1701. // summary:
  1702. // Return true if it is an Array.
  1703. // Does not work on Arrays created in other windows.
  1704. return it && (it instanceof Array || typeof it == "array"); // Boolean
  1705. };
  1706. dojo.isFunction = function(/*anything*/ it){
  1707. // summary:
  1708. // Return true if it is a Function
  1709. return opts.call(it) === "[object Function]";
  1710. };
  1711. dojo.isObject = function(/*anything*/ it){
  1712. // summary:
  1713. // Returns true if it is a JavaScript object (or an Array, a Function
  1714. // or null)
  1715. return it !== undefined &&
  1716. (it === null || typeof it == "object" || d.isArray(it) || d.isFunction(it)); // Boolean
  1717. };
  1718. dojo.isArrayLike = function(/*anything*/ it){
  1719. // summary:
  1720. // similar to dojo.isArray() but more permissive
  1721. // description:
  1722. // Doesn't strongly test for "arrayness". Instead, settles for "isn't
  1723. // a string or number and has a length property". Arguments objects
  1724. // and DOM collections will return true when passed to
  1725. // dojo.isArrayLike(), but will return false when passed to
  1726. // dojo.isArray().
  1727. // returns:
  1728. // If it walks like a duck and quacks like a duck, return `true`
  1729. return it && it !== undefined && // Boolean
  1730. // keep out built-in constructors (Number, String, ...) which have length
  1731. // properties
  1732. !d.isString(it) && !d.isFunction(it) &&
  1733. !(it.tagName && it.tagName.toLowerCase() == 'form') &&
  1734. (d.isArray(it) || isFinite(it.length));
  1735. };
  1736. dojo.isAlien = function(/*anything*/ it){
  1737. // summary:
  1738. // Returns true if it is a built-in function or some other kind of
  1739. // oddball that *should* report as a function but doesn't
  1740. return it && !d.isFunction(it) && /\{\s*\[native code\]\s*\}/.test(String(it)); // Boolean
  1741. };
  1742. dojo.extend = function(/*Object*/ constructor, /*Object...*/ props){
  1743. // summary:
  1744. // Adds all properties and methods of props to constructor's
  1745. // prototype, making them available to all instances created with
  1746. // constructor.
  1747. for(var i=1, l=arguments.length; i<l; i++){
  1748. d._mixin(constructor.prototype, arguments[i]);
  1749. }
  1750. return constructor; // Object
  1751. };
  1752. dojo._hitchArgs = function(scope, method /*,...*/){
  1753. var pre = d._toArray(arguments, 2);
  1754. var named = d.isString(method);
  1755. return function(){
  1756. // arrayify arguments
  1757. var args = d._toArray(arguments);
  1758. // locate our method
  1759. var f = named ? (scope||d.global)[method] : method;
  1760. // invoke with collected args
  1761. return f && f.apply(scope || this, pre.concat(args)); // mixed
  1762. }; // Function
  1763. };
  1764. dojo.hitch = function(/*Object*/scope, /*Function|String*/method /*,...*/){
  1765. // summary:
  1766. // Returns a function that will only ever execute in the a given scope.
  1767. // This allows for easy use of object member functions
  1768. // in callbacks and other places in which the "this" keyword may
  1769. // otherwise not reference the expected scope.
  1770. // Any number of default positional arguments may be passed as parameters
  1771. // beyond "method".
  1772. // Each of these values will be used to "placehold" (similar to curry)
  1773. // for the hitched function.
  1774. // scope:
  1775. // The scope to use when method executes. If method is a string,
  1776. // scope is also the object containing method.
  1777. // method:
  1778. // A function to be hitched to scope, or the name of the method in
  1779. // scope to be hitched.
  1780. // example:
  1781. // | dojo.hitch(foo, "bar")();
  1782. // runs foo.bar() in the scope of foo
  1783. // example:
  1784. // | dojo.hitch(foo, myFunction);
  1785. // returns a function that runs myFunction in the scope of foo
  1786. // example:
  1787. // Expansion on the default positional arguments passed along from
  1788. // hitch. Passed args are mixed first, additional args after.
  1789. // | var foo = { bar: function(a, b, c){ console.log(a, b, c); } };
  1790. // | var fn = dojo.hitch(foo, "bar", 1, 2);
  1791. // | fn(3); // logs "1, 2, 3"
  1792. // example:
  1793. // | var foo = { bar: 2 };
  1794. // | dojo.hitch(foo, function(){ this.bar = 10; })();
  1795. // execute an anonymous function in scope of foo
  1796. if(arguments.length > 2){
  1797. return d._hitchArgs.apply(d, arguments); // Function
  1798. }
  1799. if(!method){
  1800. method = scope;
  1801. scope = null;
  1802. }
  1803. if(d.isString(method)){
  1804. scope = scope || d.global;
  1805. if(!scope[method]){ throw(['dojo.hitch: scope["', method, '"] is null (scope="', scope, '")'].join('')); }
  1806. return function(){ return scope[method].apply(scope, arguments || []); }; // Function
  1807. }
  1808. return !scope ? method : function(){ return method.apply(scope, arguments || []); }; // Function
  1809. };
  1810. /*=====
  1811. dojo.delegate = function(obj, props){
  1812. // summary:
  1813. // Returns a new object which "looks" to obj for properties which it
  1814. // does not have a value for. Optionally takes a bag of properties to
  1815. // seed the returned object with initially.
  1816. // description:
  1817. // This is a small implementaton of the Boodman/Crockford delegation
  1818. // pattern in JavaScript. An intermediate object constructor mediates
  1819. // the prototype chain for the returned object, using it to delegate
  1820. // down to obj for property lookup when object-local lookup fails.
  1821. // This can be thought of similarly to ES4's "wrap", save that it does
  1822. // not act on types but rather on pure objects.
  1823. // obj:
  1824. // The object to delegate to for properties not found directly on the
  1825. // return object or in props.
  1826. // props:
  1827. // an object containing properties to assign to the returned object
  1828. // returns:
  1829. // an Object of anonymous type
  1830. // example:
  1831. // | var foo = { bar: "baz" };
  1832. // | var thinger = dojo.delegate(foo, { thud: "xyzzy"});
  1833. // | thinger.bar == "baz"; // delegated to foo
  1834. // | foo.thud == undefined; // by definition
  1835. // | thinger.thud == "xyzzy"; // mixed in from props
  1836. // | foo.bar = "thonk";
  1837. // | thinger.bar == "thonk"; // still delegated to foo's bar
  1838. }
  1839. =====*/
  1840. dojo.delegate = dojo._delegate = (function(){
  1841. // boodman/crockford delegation w/ cornford optimization
  1842. function TMP(){}
  1843. return function(obj, props){
  1844. TMP.prototype = obj;
  1845. var tmp = new TMP();
  1846. TMP.prototype = null;
  1847. if(props){
  1848. d._mixin(tmp, props);
  1849. }
  1850. return tmp; // Object
  1851. };
  1852. })();
  1853. /*=====
  1854. dojo._toArray = function(obj, offset, startWith){
  1855. // summary:
  1856. // Converts an array-like object (i.e. arguments, DOMCollection) to an
  1857. // array. Returns a new Array with the elements of obj.
  1858. // obj: Object
  1859. // the object to "arrayify". We expect the object to have, at a
  1860. // minimum, a length property which corresponds to integer-indexed
  1861. // properties.
  1862. // offset: Number?
  1863. // the location in obj to start iterating from. Defaults to 0.
  1864. // Optional.
  1865. // startWith: Array?
  1866. // An array to pack with the properties of obj. If provided,
  1867. // properties in obj are appended at the end of startWith and
  1868. // startWith is the returned array.
  1869. }
  1870. =====*/
  1871. var efficient = function(obj, offset, startWith){
  1872. return (startWith||[]).concat(Array.prototype.slice.call(obj, offset||0));
  1873. };
  1874. var slow = function(obj, offset, startWith){
  1875. var arr = startWith||[];
  1876. for(var x = offset || 0; x < obj.length; x++){
  1877. arr.push(obj[x]);
  1878. }
  1879. return arr;
  1880. };
  1881. dojo._toArray =
  1882. d.isIE ? function(obj){
  1883. return ((obj.item) ? slow : efficient).apply(this, arguments);
  1884. } :
  1885. efficient;
  1886. dojo.partial = function(/*Function|String*/method /*, ...*/){
  1887. // summary:
  1888. // similar to hitch() except that the scope object is left to be
  1889. // whatever the execution context eventually becomes.
  1890. // description:
  1891. // Calling dojo.partial is the functional equivalent of calling:
  1892. // | dojo.hitch(null, funcName, ...);
  1893. var arr = [ null ];
  1894. return d.hitch.apply(d, arr.concat(d._toArray(arguments))); // Function
  1895. };
  1896. var extraNames = d._extraNames, extraLen = extraNames.length, empty = {};
  1897. dojo.clone = function(/*anything*/ o){
  1898. // summary:
  1899. // Clones objects (including DOM nodes) and all children.
  1900. // Warning: do not clone cyclic structures.
  1901. if(!o || typeof o != "object" || d.isFunction(o)){
  1902. // null, undefined, any non-object, or function
  1903. return o; // anything
  1904. }
  1905. if(o.nodeType && "cloneNode" in o){
  1906. // DOM Node
  1907. return o.cloneNode(true); // Node
  1908. }
  1909. if(o instanceof Date){
  1910. // Date
  1911. return new Date(o.getTime()); // Date
  1912. }
  1913. if(o instanceof RegExp){
  1914. // RegExp
  1915. return new RegExp(o); // RegExp
  1916. }
  1917. var r, i, l, s, name;
  1918. if(d.isArray(o)){
  1919. // array
  1920. r = [];
  1921. for(i = 0, l = o.length; i < l; ++i){
  1922. if(i in o){
  1923. r.push(d.clone(o[i]));
  1924. }
  1925. }
  1926. // we don't clone functions for performance reasons
  1927. // }else if(d.isFunction(o)){
  1928. // // function
  1929. // r = function(){ return o.apply(this, arguments); };
  1930. }else{
  1931. // generic objects
  1932. r = o.constructor ? new o.constructor() : {};
  1933. }
  1934. for(name in o){
  1935. // the "tobj" condition avoid copying properties in "source"
  1936. // inherited from Object.prototype. For example, if target has a custom
  1937. // toString() method, don't overwrite it with the toString() method
  1938. // that source inherited from Object.prototype
  1939. s = o[name];
  1940. if(!(name in r) || (r[name] !== s && (!(name in empty) || empty[name] !== s))){
  1941. r[name] = d.clone(s);
  1942. }
  1943. }
  1944. // IE doesn't recognize some custom functions in for..in
  1945. if(extraLen){
  1946. for(i = 0; i < extraLen; ++i){
  1947. name = extraNames[i];
  1948. s = o[name];
  1949. if(!(name in r) || (r[name] !== s && (!(name in empty) || empty[name] !== s))){
  1950. r[name] = s; // functions only, we don't clone them
  1951. }
  1952. }
  1953. }
  1954. return r; // Object
  1955. };
  1956. /*=====
  1957. dojo.trim = function(str){
  1958. // summary:
  1959. // Trims whitespace from both sides of the string
  1960. // str: String
  1961. // String to be trimmed
  1962. // returns: String
  1963. // Returns the trimmed string
  1964. // description:
  1965. // This version of trim() was selected for inclusion into the base due
  1966. // to its compact size and relatively good performance
  1967. // (see [Steven Levithan's blog](http://blog.stevenlevithan.com/archives/faster-trim-javascript)
  1968. // Uses String.prototype.trim instead, if available.
  1969. // The fastest but longest version of this function is located at
  1970. // dojo.string.trim()
  1971. return ""; // String
  1972. }
  1973. =====*/
  1974. dojo.trim = String.prototype.trim ?
  1975. function(str){ return str.trim(); } :
  1976. function(str){ return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); };
  1977. /*=====
  1978. dojo.replace = function(tmpl, map, pattern){
  1979. // summary:
  1980. // Performs parameterized substitutions on a string. Throws an
  1981. // exception if any parameter is unmatched.
  1982. // tmpl: String
  1983. // String to be used as a template.
  1984. // map: Object|Function
  1985. // If an object, it is used as a dictionary to look up substitutions.
  1986. // If a function, it is called for every substitution with following
  1987. // parameters: a whole match, a name, an offset, and the whole template
  1988. // string (see https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/String/replace
  1989. // for more details).
  1990. // pattern: RegEx?
  1991. // Optional regular expression objects that overrides the default pattern.
  1992. // Must be global and match one item. The default is: /\{([^\}]+)\}/g,
  1993. // which matches patterns like that: "{xxx}", where "xxx" is any sequence
  1994. // of characters, which doesn't include "}".
  1995. // returns: String
  1996. // Returns the substituted string.
  1997. // example:
  1998. // | // uses a dictionary for substitutions:
  1999. // | dojo.replace("Hello, {name.first} {name.last} AKA {nick}!",
  2000. // | {
  2001. // | nick: "Bob",
  2002. // | name: {
  2003. // | first: "Robert",
  2004. // | middle: "X",
  2005. // | last: "Cringely"
  2006. // | }
  2007. // | });
  2008. // | // returns: Hello, Robert Cringely AKA Bob!
  2009. // example:
  2010. // | // uses an array for substitutions:
  2011. // | dojo.replace("Hello, {0} {2}!",
  2012. // | ["Robert", "X", "Cringely"]);
  2013. // | // returns: Hello, Robert Cringely!
  2014. // example:
  2015. // | // uses a function for substitutions:
  2016. // | function sum(a){
  2017. // | var t = 0;
  2018. // | dojo.forEach(a, function(x){ t += x; });
  2019. // | return t;
  2020. // | }
  2021. // | dojo.replace(
  2022. // | "{count} payments averaging {avg} USD per payment.",
  2023. // | dojo.hitch(
  2024. // | { payments: [11, 16, 12] },
  2025. // | function(_, key){
  2026. // | switch(key){
  2027. // | case "count": return this.payments.length;
  2028. // | case "min": return Math.min.apply(Math, this.payments);
  2029. // | case "max": return Math.max.apply(Math, this.payments);
  2030. // | case "sum": return sum(this.payments);
  2031. // | case "avg": return sum(this.payments) / this.payments.length;
  2032. // | }
  2033. // | }
  2034. // | )
  2035. // | );
  2036. // | // prints: 3 payments averaging 13 USD per payment.
  2037. // example:
  2038. // | // uses an alternative PHP-like pattern for substitutions:
  2039. // | dojo.replace("Hello, ${0} ${2}!",
  2040. // | ["Robert", "X", "Cringely"], /\$\{([^\}]+)\}/g);
  2041. // | // returns: Hello, Robert Cringely!
  2042. return ""; // String
  2043. }
  2044. =====*/
  2045. var _pattern = /\{([^\}]+)\}/g;
  2046. dojo.replace = function(tmpl, map, pattern){
  2047. return tmpl.replace(pattern || _pattern, d.isFunction(map) ?
  2048. map : function(_, k){ return d.getObject(k, false, map); });
  2049. };
  2050. })();
  2051. }
  2052. if(!dojo._hasResource["dojo._base.array"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  2053. dojo._hasResource["dojo._base.array"] = true;
  2054. dojo.provide("dojo._base.array");
  2055. (function(){
  2056. var _getParts = function(arr, obj, cb){
  2057. return [
  2058. (typeof arr == "string") ? arr.split("") : arr,
  2059. obj || dojo.global,
  2060. // FIXME: cache the anonymous functions we create here?
  2061. (typeof cb == "string") ? new Function("item", "index", "array", cb) : cb
  2062. ];
  2063. };
  2064. var everyOrSome = function(/*Boolean*/every, /*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
  2065. var _p = _getParts(arr, thisObject, callback); arr = _p[0];
  2066. for(var i=0,l=arr.length; i<l; ++i){
  2067. var result = !!_p[2].call(_p[1], arr[i], i, arr);
  2068. if(every ^ result){
  2069. return result; // Boolean
  2070. }
  2071. }
  2072. return every; // Boolean
  2073. };
  2074. dojo.mixin(dojo, {
  2075. indexOf: function( /*Array*/ array,
  2076. /*Object*/ value,
  2077. /*Integer?*/ fromIndex,
  2078. /*Boolean?*/ findLast){
  2079. // summary:
  2080. // locates the first index of the provided value in the
  2081. // passed array. If the value is not found, -1 is returned.
  2082. // description:
  2083. // This method corresponds to the JavaScript 1.6 Array.indexOf method, with one difference: when
  2084. // run over sparse arrays, the Dojo function invokes the callback for every index whereas JavaScript
  2085. // 1.6's indexOf skips the holes in the sparse array.
  2086. // For details on this method, see:
  2087. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/indexOf
  2088. var step = 1, end = array.length || 0, i = 0;
  2089. if(findLast){
  2090. i = end - 1;
  2091. step = end = -1;
  2092. }
  2093. if(fromIndex != undefined){ i = fromIndex; }
  2094. if((findLast && i > end) || i < end){
  2095. for(; i != end; i += step){
  2096. if(array[i] == value){ return i; }
  2097. }
  2098. }
  2099. return -1; // Number
  2100. },
  2101. lastIndexOf: function(/*Array*/array, /*Object*/value, /*Integer?*/fromIndex){
  2102. // summary:
  2103. // locates the last index of the provided value in the passed
  2104. // array. If the value is not found, -1 is returned.
  2105. // description:
  2106. // This method corresponds to the JavaScript 1.6 Array.lastIndexOf method, with one difference: when
  2107. // run over sparse arrays, the Dojo function invokes the callback for every index whereas JavaScript
  2108. // 1.6's lastIndexOf skips the holes in the sparse array.
  2109. // For details on this method, see:
  2110. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/lastIndexOf
  2111. return dojo.indexOf(array, value, fromIndex, true); // Number
  2112. },
  2113. forEach: function(/*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
  2114. // summary:
  2115. // for every item in arr, callback is invoked. Return values are ignored.
  2116. // If you want to break out of the loop, consider using dojo.every() or dojo.some().
  2117. // forEach does not allow breaking out of the loop over the items in arr.
  2118. // arr:
  2119. // the array to iterate over. If a string, operates on individual characters.
  2120. // callback:
  2121. // a function is invoked with three arguments: item, index, and array
  2122. // thisObject:
  2123. // may be used to scope the call to callback
  2124. // description:
  2125. // This function corresponds to the JavaScript 1.6 Array.forEach() method, with one difference: when
  2126. // run over sparse arrays, this implemenation passes the "holes" in the sparse array to
  2127. // the callback function with a value of undefined. JavaScript 1.6's forEach skips the holes in the sparse array.
  2128. // For more details, see:
  2129. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/forEach
  2130. // example:
  2131. // | // log out all members of the array:
  2132. // | dojo.forEach(
  2133. // | [ "thinger", "blah", "howdy", 10 ],
  2134. // | function(item){
  2135. // | console.log(item);
  2136. // | }
  2137. // | );
  2138. // example:
  2139. // | // log out the members and their indexes
  2140. // | dojo.forEach(
  2141. // | [ "thinger", "blah", "howdy", 10 ],
  2142. // | function(item, idx, arr){
  2143. // | console.log(item, "at index:", idx);
  2144. // | }
  2145. // | );
  2146. // example:
  2147. // | // use a scoped object member as the callback
  2148. // |
  2149. // | var obj = {
  2150. // | prefix: "logged via obj.callback:",
  2151. // | callback: function(item){
  2152. // | console.log(this.prefix, item);
  2153. // | }
  2154. // | };
  2155. // |
  2156. // | // specifying the scope function executes the callback in that scope
  2157. // | dojo.forEach(
  2158. // | [ "thinger", "blah", "howdy", 10 ],
  2159. // | obj.callback,
  2160. // | obj
  2161. // | );
  2162. // |
  2163. // | // alternately, we can accomplish the same thing with dojo.hitch()
  2164. // | dojo.forEach(
  2165. // | [ "thinger", "blah", "howdy", 10 ],
  2166. // | dojo.hitch(obj, "callback")
  2167. // | );
  2168. // match the behavior of the built-in forEach WRT empty arrs
  2169. if(!arr || !arr.length){ return; }
  2170. // FIXME: there are several ways of handilng thisObject. Is
  2171. // dojo.global always the default context?
  2172. var _p = _getParts(arr, thisObject, callback); arr = _p[0];
  2173. for(var i=0,l=arr.length; i<l; ++i){
  2174. _p[2].call(_p[1], arr[i], i, arr);
  2175. }
  2176. },
  2177. every: function(/*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
  2178. // summary:
  2179. // Determines whether or not every item in arr satisfies the
  2180. // condition implemented by callback.
  2181. // arr:
  2182. // the array to iterate on. If a string, operates on individual characters.
  2183. // callback:
  2184. // a function is invoked with three arguments: item, index,
  2185. // and array and returns true if the condition is met.
  2186. // thisObject:
  2187. // may be used to scope the call to callback
  2188. // description:
  2189. // This function corresponds to the JavaScript 1.6 Array.every() method, with one difference: when
  2190. // run over sparse arrays, this implemenation passes the "holes" in the sparse array to
  2191. // the callback function with a value of undefined. JavaScript 1.6's every skips the holes in the sparse array.
  2192. // For more details, see:
  2193. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/every
  2194. // example:
  2195. // | // returns false
  2196. // | dojo.every([1, 2, 3, 4], function(item){ return item>1; });
  2197. // example:
  2198. // | // returns true
  2199. // | dojo.every([1, 2, 3, 4], function(item){ return item>0; });
  2200. return everyOrSome(true, arr, callback, thisObject); // Boolean
  2201. },
  2202. some: function(/*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
  2203. // summary:
  2204. // Determines whether or not any item in arr satisfies the
  2205. // condition implemented by callback.
  2206. // arr:
  2207. // the array to iterate over. If a string, operates on individual characters.
  2208. // callback:
  2209. // a function is invoked with three arguments: item, index,
  2210. // and array and returns true if the condition is met.
  2211. // thisObject:
  2212. // may be used to scope the call to callback
  2213. // description:
  2214. // This function corresponds to the JavaScript 1.6 Array.some() method, with one difference: when
  2215. // run over sparse arrays, this implemenation passes the "holes" in the sparse array to
  2216. // the callback function with a value of undefined. JavaScript 1.6's some skips the holes in the sparse array.
  2217. // For more details, see:
  2218. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/some
  2219. // example:
  2220. // | // is true
  2221. // | dojo.some([1, 2, 3, 4], function(item){ return item>1; });
  2222. // example:
  2223. // | // is false
  2224. // | dojo.some([1, 2, 3, 4], function(item){ return item<1; });
  2225. return everyOrSome(false, arr, callback, thisObject); // Boolean
  2226. },
  2227. map: function(/*Array|String*/arr, /*Function|String*/callback, /*Function?*/thisObject){
  2228. // summary:
  2229. // applies callback to each element of arr and returns
  2230. // an Array with the results
  2231. // arr:
  2232. // the array to iterate on. If a string, operates on
  2233. // individual characters.
  2234. // callback:
  2235. // a function is invoked with three arguments, (item, index,
  2236. // array), and returns a value
  2237. // thisObject:
  2238. // may be used to scope the call to callback
  2239. // description:
  2240. // This function corresponds to the JavaScript 1.6 Array.map() method, with one difference: when
  2241. // run over sparse arrays, this implemenation passes the "holes" in the sparse array to
  2242. // the callback function with a value of undefined. JavaScript 1.6's map skips the holes in the sparse array.
  2243. // For more details, see:
  2244. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
  2245. // example:
  2246. // | // returns [2, 3, 4, 5]
  2247. // | dojo.map([1, 2, 3, 4], function(item){ return item+1 });
  2248. var _p = _getParts(arr, thisObject, callback); arr = _p[0];
  2249. var outArr = (arguments[3] ? (new arguments[3]()) : []);
  2250. for(var i=0,l=arr.length; i<l; ++i){
  2251. outArr.push(_p[2].call(_p[1], arr[i], i, arr));
  2252. }
  2253. return outArr; // Array
  2254. },
  2255. filter: function(/*Array*/arr, /*Function|String*/callback, /*Object?*/thisObject){
  2256. // summary:
  2257. // Returns a new Array with those items from arr that match the
  2258. // condition implemented by callback.
  2259. // arr:
  2260. // the array to iterate over.
  2261. // callback:
  2262. // a function that is invoked with three arguments (item,
  2263. // index, array). The return of this function is expected to
  2264. // be a boolean which determines whether the passed-in item
  2265. // will be included in the returned array.
  2266. // thisObject:
  2267. // may be used to scope the call to callback
  2268. // description:
  2269. // This function corresponds to the JavaScript 1.6 Array.filter() method, with one difference: when
  2270. // run over sparse arrays, this implemenation passes the "holes" in the sparse array to
  2271. // the callback function with a value of undefined. JavaScript 1.6's filter skips the holes in the sparse array.
  2272. // For more details, see:
  2273. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
  2274. // example:
  2275. // | // returns [2, 3, 4]
  2276. // | dojo.filter([1, 2, 3, 4], function(item){ return item>1; });
  2277. var _p = _getParts(arr, thisObject, callback); arr = _p[0];
  2278. var outArr = [];
  2279. for(var i=0,l=arr.length; i<l; ++i){
  2280. if(_p[2].call(_p[1], arr[i], i, arr)){
  2281. outArr.push(arr[i]);
  2282. }
  2283. }
  2284. return outArr; // Array
  2285. }
  2286. });
  2287. })();
  2288. /*
  2289. */
  2290. }
  2291. if(!dojo._hasResource["dojo._base.declare"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  2292. dojo._hasResource["dojo._base.declare"] = true;
  2293. dojo.provide("dojo._base.declare");
  2294. (function(){
  2295. var d = dojo, mix = d._mixin, op = Object.prototype, opts = op.toString,
  2296. xtor = new Function, counter = 0, cname = "constructor";
  2297. function err(msg, cls){ throw new Error("declare" + (cls ? " " + cls : "") + ": " + msg); }
  2298. // C3 Method Resolution Order (see http://www.python.org/download/releases/2.3/mro/)
  2299. function c3mro(bases, className){
  2300. var result = [], roots = [{cls: 0, refs: []}], nameMap = {}, clsCount = 1,
  2301. l = bases.length, i = 0, j, lin, base, top, proto, rec, name, refs;
  2302. // build a list of bases naming them if needed
  2303. for(; i < l; ++i){
  2304. base = bases[i];
  2305. if(!base){
  2306. err("mixin #" + i + " is unknown. Did you use dojo.require to pull it in?", className);
  2307. }else if(opts.call(base) != "[object Function]"){
  2308. err("mixin #" + i + " is not a callable constructor.", className);
  2309. }
  2310. lin = base._meta ? base._meta.bases : [base];
  2311. top = 0;
  2312. // add bases to the name map
  2313. for(j = lin.length - 1; j >= 0; --j){
  2314. proto = lin[j].prototype;
  2315. if(!proto.hasOwnProperty("declaredClass")){
  2316. proto.declaredClass = "uniqName_" + (counter++);
  2317. }
  2318. name = proto.declaredClass;
  2319. if(!nameMap.hasOwnProperty(name)){
  2320. nameMap[name] = {count: 0, refs: [], cls: lin[j]};
  2321. ++clsCount;
  2322. }
  2323. rec = nameMap[name];
  2324. if(top && top !== rec){
  2325. rec.refs.push(top);
  2326. ++top.count;
  2327. }
  2328. top = rec;
  2329. }
  2330. ++top.count;
  2331. roots[0].refs.push(top);
  2332. }
  2333. // remove classes without external references recursively
  2334. while(roots.length){
  2335. top = roots.pop();
  2336. result.push(top.cls);
  2337. --clsCount;
  2338. // optimization: follow a single-linked chain
  2339. while(refs = top.refs, refs.length == 1){
  2340. top = refs[0];
  2341. if(!top || --top.count){
  2342. // branch or end of chain => do not end to roots
  2343. top = 0;
  2344. break;
  2345. }
  2346. result.push(top.cls);
  2347. --clsCount;
  2348. }
  2349. if(top){
  2350. // branch
  2351. for(i = 0, l = refs.length; i < l; ++i){
  2352. top = refs[i];
  2353. if(!--top.count){
  2354. roots.push(top);
  2355. }
  2356. }
  2357. }
  2358. }
  2359. if(clsCount){
  2360. err("can't build consistent linearization", className);
  2361. }
  2362. // calculate the superclass offset
  2363. base = bases[0];
  2364. result[0] = base ?
  2365. base._meta && base === result[result.length - base._meta.bases.length] ?
  2366. base._meta.bases.length : 1 : 0;
  2367. return result;
  2368. }
  2369. function inherited(args, a, f){
  2370. var name, chains, bases, caller, meta, base, proto, opf, pos,
  2371. cache = this._inherited = this._inherited || {};
  2372. // crack arguments
  2373. if(typeof args == "string"){
  2374. name = args;
  2375. args = a;
  2376. a = f;
  2377. }
  2378. f = 0;
  2379. caller = args.callee;
  2380. name = name || caller.nom;
  2381. if(!name){
  2382. err("can't deduce a name to call inherited()", this.declaredClass);
  2383. }
  2384. meta = this.constructor._meta;
  2385. bases = meta.bases;
  2386. pos = cache.p;
  2387. if(name != cname){
  2388. // method
  2389. if(cache.c !== caller){
  2390. // cache bust
  2391. pos = 0;
  2392. base = bases[0];
  2393. meta = base._meta;
  2394. if(meta.hidden[name] !== caller){
  2395. // error detection
  2396. chains = meta.chains;
  2397. if(chains && typeof chains[name] == "string"){
  2398. err("calling chained method with inherited: " + name, this.declaredClass);
  2399. }
  2400. // find caller
  2401. do{
  2402. meta = base._meta;
  2403. proto = base.prototype;
  2404. if(meta && (proto[name] === caller && proto.hasOwnProperty(name) || meta.hidden[name] === caller)){
  2405. break;
  2406. }
  2407. }while(base = bases[++pos]); // intentional assignment
  2408. pos = base ? pos : -1;
  2409. }
  2410. }
  2411. // find next
  2412. base = bases[++pos];
  2413. if(base){
  2414. proto = base.prototype;
  2415. if(base._meta && proto.hasOwnProperty(name)){
  2416. f = proto[name];
  2417. }else{
  2418. opf = op[name];
  2419. do{
  2420. proto = base.prototype;
  2421. f = proto[name];
  2422. if(f && (base._meta ? proto.hasOwnProperty(name) : f !== opf)){
  2423. break;
  2424. }
  2425. }while(base = bases[++pos]); // intentional assignment
  2426. }
  2427. }
  2428. f = base && f || op[name];
  2429. }else{
  2430. // constructor
  2431. if(cache.c !== caller){
  2432. // cache bust
  2433. pos = 0;
  2434. meta = bases[0]._meta;
  2435. if(meta && meta.ctor !== caller){
  2436. // error detection
  2437. chains = meta.chains;
  2438. if(!chains || chains.constructor !== "manual"){
  2439. err("calling chained constructor with inherited", this.declaredClass);
  2440. }
  2441. // find caller
  2442. while(base = bases[++pos]){ // intentional assignment
  2443. meta = base._meta;
  2444. if(meta && meta.ctor === caller){
  2445. break;
  2446. }
  2447. }
  2448. pos = base ? pos : -1;
  2449. }
  2450. }
  2451. // find next
  2452. while(base = bases[++pos]){ // intentional assignment
  2453. meta = base._meta;
  2454. f = meta ? meta.ctor : base;
  2455. if(f){
  2456. break;
  2457. }
  2458. }
  2459. f = base && f;
  2460. }
  2461. // cache the found super method
  2462. cache.c = f;
  2463. cache.p = pos;
  2464. // now we have the result
  2465. if(f){
  2466. return a === true ? f : f.apply(this, a || args);
  2467. }
  2468. // intentionally if a super method was not found
  2469. }
  2470. function getInherited(name, args){
  2471. if(typeof name == "string"){
  2472. return this.inherited(name, args, true);
  2473. }
  2474. return this.inherited(name, true);
  2475. }
  2476. // emulation of "instanceof"
  2477. function isInstanceOf(cls){
  2478. var bases = this.constructor._meta.bases;
  2479. for(var i = 0, l = bases.length; i < l; ++i){
  2480. if(bases[i] === cls){
  2481. return true;
  2482. }
  2483. }
  2484. return this instanceof cls;
  2485. }
  2486. function mixOwn(target, source){
  2487. var name, i = 0, l = d._extraNames.length;
  2488. // add props adding metadata for incoming functions skipping a constructor
  2489. for(name in source){
  2490. if(name != cname && source.hasOwnProperty(name)){
  2491. target[name] = source[name];
  2492. }
  2493. }
  2494. // process unenumerable methods on IE
  2495. for(; i < l; ++i){
  2496. name = d._extraNames[i];
  2497. if(name != cname && source.hasOwnProperty(name)){
  2498. target[name] = source[name];
  2499. }
  2500. }
  2501. }
  2502. // implementation of safe mixin function
  2503. function safeMixin(target, source){
  2504. var name, t, i = 0, l = d._extraNames.length;
  2505. // add props adding metadata for incoming functions skipping a constructor
  2506. for(name in source){
  2507. t = source[name];
  2508. if((t !== op[name] || !(name in op)) && name != cname){
  2509. if(opts.call(t) == "[object Function]"){
  2510. // non-trivial function method => attach its name
  2511. t.nom = name;
  2512. }
  2513. target[name] = t;
  2514. }
  2515. }
  2516. // process unenumerable methods on IE
  2517. for(; i < l; ++i){
  2518. name = d._extraNames[i];
  2519. t = source[name];
  2520. if((t !== op[name] || !(name in op)) && name != cname){
  2521. if(opts.call(t) == "[object Function]"){
  2522. // non-trivial function method => attach its name
  2523. t.nom = name;
  2524. }
  2525. target[name] = t;
  2526. }
  2527. }
  2528. return target;
  2529. }
  2530. function extend(source){
  2531. safeMixin(this.prototype, source);
  2532. return this;
  2533. }
  2534. // chained constructor compatible with the legacy dojo.declare()
  2535. function chainedConstructor(bases, ctorSpecial){
  2536. return function(){
  2537. var a = arguments, args = a, a0 = a[0], f, i, m,
  2538. l = bases.length, preArgs;
  2539. if(!(this instanceof a.callee)){
  2540. // not called via new, so force it
  2541. return applyNew(a);
  2542. }
  2543. //this._inherited = {};
  2544. // perform the shaman's rituals of the original dojo.declare()
  2545. // 1) call two types of the preamble
  2546. if(ctorSpecial && (a0 && a0.preamble || this.preamble)){
  2547. // full blown ritual
  2548. preArgs = new Array(bases.length);
  2549. // prepare parameters
  2550. preArgs[0] = a;
  2551. for(i = 0;;){
  2552. // process the preamble of the 1st argument
  2553. a0 = a[0];
  2554. if(a0){
  2555. f = a0.preamble;
  2556. if(f){
  2557. a = f.apply(this, a) || a;
  2558. }
  2559. }
  2560. // process the preamble of this class
  2561. f = bases[i].prototype;
  2562. f = f.hasOwnProperty("preamble") && f.preamble;
  2563. if(f){
  2564. a = f.apply(this, a) || a;
  2565. }
  2566. // one peculiarity of the preamble:
  2567. // it is called if it is not needed,
  2568. // e.g., there is no constructor to call
  2569. // let's watch for the last constructor
  2570. // (see ticket #9795)
  2571. if(++i == l){
  2572. break;
  2573. }
  2574. preArgs[i] = a;
  2575. }
  2576. }
  2577. // 2) call all non-trivial constructors using prepared arguments
  2578. for(i = l - 1; i >= 0; --i){
  2579. f = bases[i];
  2580. m = f._meta;
  2581. f = m ? m.ctor : f;
  2582. if(f){
  2583. f.apply(this, preArgs ? preArgs[i] : a);
  2584. }
  2585. }
  2586. // 3) continue the original ritual: call the postscript
  2587. f = this.postscript;
  2588. if(f){
  2589. f.apply(this, args);
  2590. }
  2591. };
  2592. }
  2593. // chained constructor compatible with the legacy dojo.declare()
  2594. function singleConstructor(ctor, ctorSpecial){
  2595. return function(){
  2596. var a = arguments, t = a, a0 = a[0], f;
  2597. if(!(this instanceof a.callee)){
  2598. // not called via new, so force it
  2599. return applyNew(a);
  2600. }
  2601. //this._inherited = {};
  2602. // perform the shaman's rituals of the original dojo.declare()
  2603. // 1) call two types of the preamble
  2604. if(ctorSpecial){
  2605. // full blown ritual
  2606. if(a0){
  2607. // process the preamble of the 1st argument
  2608. f = a0.preamble;
  2609. if(f){
  2610. t = f.apply(this, t) || t;
  2611. }
  2612. }
  2613. f = this.preamble;
  2614. if(f){
  2615. // process the preamble of this class
  2616. f.apply(this, t);
  2617. // one peculiarity of the preamble:
  2618. // it is called even if it is not needed,
  2619. // e.g., there is no constructor to call
  2620. // let's watch for the last constructor
  2621. // (see ticket #9795)
  2622. }
  2623. }
  2624. // 2) call a constructor
  2625. if(ctor){
  2626. ctor.apply(this, a);
  2627. }
  2628. // 3) continue the original ritual: call the postscript
  2629. f = this.postscript;
  2630. if(f){
  2631. f.apply(this, a);
  2632. }
  2633. };
  2634. }
  2635. // plain vanilla constructor (can use inherited() to call its base constructor)
  2636. function simpleConstructor(bases){
  2637. return function(){
  2638. var a = arguments, i = 0, f, m;
  2639. if(!(this instanceof a.callee)){
  2640. // not called via new, so force it
  2641. return applyNew(a);
  2642. }
  2643. //this._inherited = {};
  2644. // perform the shaman's rituals of the original dojo.declare()
  2645. // 1) do not call the preamble
  2646. // 2) call the top constructor (it can use this.inherited())
  2647. for(; f = bases[i]; ++i){ // intentional assignment
  2648. m = f._meta;
  2649. f = m ? m.ctor : f;
  2650. if(f){
  2651. f.apply(this, a);
  2652. break;
  2653. }
  2654. }
  2655. // 3) call the postscript
  2656. f = this.postscript;
  2657. if(f){
  2658. f.apply(this, a);
  2659. }
  2660. };
  2661. }
  2662. function chain(name, bases, reversed){
  2663. return function(){
  2664. var b, m, f, i = 0, step = 1;
  2665. if(reversed){
  2666. i = bases.length - 1;
  2667. step = -1;
  2668. }
  2669. for(; b = bases[i]; i += step){ // intentional assignment
  2670. m = b._meta;
  2671. f = (m ? m.hidden : b.prototype)[name];
  2672. if(f){
  2673. f.apply(this, arguments);
  2674. }
  2675. }
  2676. };
  2677. }
  2678. // forceNew(ctor)
  2679. // return a new object that inherits from ctor.prototype but
  2680. // without actually running ctor on the object.
  2681. function forceNew(ctor){
  2682. // create object with correct prototype using a do-nothing
  2683. // constructor
  2684. xtor.prototype = ctor.prototype;
  2685. var t = new xtor;
  2686. xtor.prototype = null; // clean up
  2687. return t;
  2688. }
  2689. // applyNew(args)
  2690. // just like 'new ctor()' except that the constructor and its arguments come
  2691. // from args, which must be an array or an arguments object
  2692. function applyNew(args){
  2693. // create an object with ctor's prototype but without
  2694. // calling ctor on it.
  2695. var ctor = args.callee, t = forceNew(ctor);
  2696. // execute the real constructor on the new object
  2697. ctor.apply(t, args);
  2698. return t;
  2699. }
  2700. d.declare = function(className, superclass, props){
  2701. // crack parameters
  2702. if(typeof className != "string"){
  2703. props = superclass;
  2704. superclass = className;
  2705. className = "";
  2706. }
  2707. props = props || {};
  2708. var proto, i, t, ctor, name, bases, chains, mixins = 1, parents = superclass;
  2709. // build a prototype
  2710. if(opts.call(superclass) == "[object Array]"){
  2711. // C3 MRO
  2712. bases = c3mro(superclass, className);
  2713. t = bases[0];
  2714. mixins = bases.length - t;
  2715. superclass = bases[mixins];
  2716. }else{
  2717. bases = [0];
  2718. if(superclass){
  2719. if(opts.call(superclass) == "[object Function]"){
  2720. t = superclass._meta;
  2721. bases = bases.concat(t ? t.bases : superclass);
  2722. }else{
  2723. err("base class is not a callable constructor.", className);
  2724. }
  2725. }else if(superclass !== null){
  2726. err("unknown base class. Did you use dojo.require to pull it in?", className);
  2727. }
  2728. }
  2729. if(superclass){
  2730. for(i = mixins - 1;; --i){
  2731. proto = forceNew(superclass);
  2732. if(!i){
  2733. // stop if nothing to add (the last base)
  2734. break;
  2735. }
  2736. // mix in properties
  2737. t = bases[i];
  2738. (t._meta ? mixOwn : mix)(proto, t.prototype);
  2739. // chain in new constructor
  2740. ctor = new Function;
  2741. ctor.superclass = superclass;
  2742. ctor.prototype = proto;
  2743. superclass = proto.constructor = ctor;
  2744. }
  2745. }else{
  2746. proto = {};
  2747. }
  2748. // add all properties
  2749. safeMixin(proto, props);
  2750. // add constructor
  2751. t = props.constructor;
  2752. if(t !== op.constructor){
  2753. t.nom = cname;
  2754. proto.constructor = t;
  2755. }
  2756. // collect chains and flags
  2757. for(i = mixins - 1; i; --i){ // intentional assignment
  2758. t = bases[i]._meta;
  2759. if(t && t.chains){
  2760. chains = mix(chains || {}, t.chains);
  2761. }
  2762. }
  2763. if(proto["-chains-"]){
  2764. chains = mix(chains || {}, proto["-chains-"]);
  2765. }
  2766. // build ctor
  2767. t = !chains || !chains.hasOwnProperty(cname);
  2768. bases[0] = ctor = (chains && chains.constructor === "manual") ? simpleConstructor(bases) :
  2769. (bases.length == 1 ? singleConstructor(props.constructor, t) : chainedConstructor(bases, t));
  2770. // add meta information to the constructor
  2771. ctor._meta = {bases: bases, hidden: props, chains: chains,
  2772. parents: parents, ctor: props.constructor};
  2773. ctor.superclass = superclass && superclass.prototype;
  2774. ctor.extend = extend;
  2775. ctor.prototype = proto;
  2776. proto.constructor = ctor;
  2777. // add "standard" methods to the prototype
  2778. proto.getInherited = getInherited;
  2779. proto.inherited = inherited;
  2780. proto.isInstanceOf = isInstanceOf;
  2781. // add name if specified
  2782. if(className){
  2783. proto.declaredClass = className;
  2784. d.setObject(className, ctor);
  2785. }
  2786. // build chains and add them to the prototype
  2787. if(chains){
  2788. for(name in chains){
  2789. if(proto[name] && typeof chains[name] == "string" && name != cname){
  2790. t = proto[name] = chain(name, bases, chains[name] === "after");
  2791. t.nom = name;
  2792. }
  2793. }
  2794. }
  2795. // chained methods do not return values
  2796. // no need to chain "invisible" functions
  2797. return ctor; // Function
  2798. };
  2799. d.safeMixin = safeMixin;
  2800. /*=====
  2801. dojo.declare = function(className, superclass, props){
  2802. // summary:
  2803. // Create a feature-rich constructor from compact notation.
  2804. // className: String?:
  2805. // The optional name of the constructor (loosely, a "class")
  2806. // stored in the "declaredClass" property in the created prototype.
  2807. // It will be used as a global name for a created constructor.
  2808. // superclass: Function|Function[]:
  2809. // May be null, a Function, or an Array of Functions. This argument
  2810. // specifies a list of bases (the left-most one is the most deepest
  2811. // base).
  2812. // props: Object:
  2813. // An object whose properties are copied to the created prototype.
  2814. // Add an instance-initialization function by making it a property
  2815. // named "constructor".
  2816. // returns:
  2817. // New constructor function.
  2818. // description:
  2819. // Create a constructor using a compact notation for inheritance and
  2820. // prototype extension.
  2821. //
  2822. // Mixin ancestors provide a type of multiple inheritance.
  2823. // Prototypes of mixin ancestors are copied to the new class:
  2824. // changes to mixin prototypes will not affect classes to which
  2825. // they have been mixed in.
  2826. //
  2827. // Ancestors can be compound classes created by this version of
  2828. // dojo.declare. In complex cases all base classes are going to be
  2829. // linearized according to C3 MRO algorithm
  2830. // (see http://www.python.org/download/releases/2.3/mro/ for more
  2831. // details).
  2832. //
  2833. // "className" is cached in "declaredClass" property of the new class,
  2834. // if it was supplied. The immediate super class will be cached in
  2835. // "superclass" property of the new class.
  2836. //
  2837. // Methods in "props" will be copied and modified: "nom" property
  2838. // (the declared name of the method) will be added to all copied
  2839. // functions to help identify them for the internal machinery. Be
  2840. // very careful, while reusing methods: if you use the same
  2841. // function under different names, it can produce errors in some
  2842. // cases.
  2843. //
  2844. // It is possible to use constructors created "manually" (without
  2845. // dojo.declare) as bases. They will be called as usual during the
  2846. // creation of an instance, their methods will be chained, and even
  2847. // called by "this.inherited()".
  2848. //
  2849. // Special property "-chains-" governs how to chain methods. It is
  2850. // a dictionary, which uses method names as keys, and hint strings
  2851. // as values. If a hint string is "after", this method will be
  2852. // called after methods of its base classes. If a hint string is
  2853. // "before", this method will be called before methods of its base
  2854. // classes.
  2855. //
  2856. // If "constructor" is not mentioned in "-chains-" property, it will
  2857. // be chained using the legacy mode: using "after" chaining,
  2858. // calling preamble() method before each constructor, if available,
  2859. // and calling postscript() after all constructors were executed.
  2860. // If the hint is "after", it is chained as a regular method, but
  2861. // postscript() will be called after the chain of constructors.
  2862. // "constructor" cannot be chained "before", but it allows
  2863. // a special hint string: "manual", which means that constructors
  2864. // are not going to be chained in any way, and programmer will call
  2865. // them manually using this.inherited(). In the latter case
  2866. // postscript() will be called after the construction.
  2867. //
  2868. // All chaining hints are "inherited" from base classes and
  2869. // potentially can be overridden. Be very careful when overriding
  2870. // hints! Make sure that all chained methods can work in a proposed
  2871. // manner of chaining.
  2872. //
  2873. // Once a method was chained, it is impossible to unchain it. The
  2874. // only exception is "constructor". You don't need to define a
  2875. // method in order to supply a chaining hint.
  2876. //
  2877. // If a method is chained, it cannot use this.inherited() because
  2878. // all other methods in the hierarchy will be called automatically.
  2879. //
  2880. // Usually constructors and initializers of any kind are chained
  2881. // using "after" and destructors of any kind are chained as
  2882. // "before". Note that chaining assumes that chained methods do not
  2883. // return any value: any returned value will be discarded.
  2884. //
  2885. // example:
  2886. // | dojo.declare("my.classes.bar", my.classes.foo, {
  2887. // | // properties to be added to the class prototype
  2888. // | someValue: 2,
  2889. // | // initialization function
  2890. // | constructor: function(){
  2891. // | this.myComplicatedObject = new ReallyComplicatedObject();
  2892. // | },
  2893. // | // other functions
  2894. // | someMethod: function(){
  2895. // | doStuff();
  2896. // | }
  2897. // | });
  2898. //
  2899. // example:
  2900. // | var MyBase = dojo.declare(null, {
  2901. // | // constructor, properties, and methods go here
  2902. // | // ...
  2903. // | });
  2904. // | var MyClass1 = dojo.declare(MyBase, {
  2905. // | // constructor, properties, and methods go here
  2906. // | // ...
  2907. // | });
  2908. // | var MyClass2 = dojo.declare(MyBase, {
  2909. // | // constructor, properties, and methods go here
  2910. // | // ...
  2911. // | });
  2912. // | var MyDiamond = dojo.declare([MyClass1, MyClass2], {
  2913. // | // constructor, properties, and methods go here
  2914. // | // ...
  2915. // | });
  2916. //
  2917. // example:
  2918. // | var F = function(){ console.log("raw constructor"); };
  2919. // | F.prototype.method = function(){
  2920. // | console.log("raw method");
  2921. // | };
  2922. // | var A = dojo.declare(F, {
  2923. // | constructor: function(){
  2924. // | console.log("A.constructor");
  2925. // | },
  2926. // | method: function(){
  2927. // | console.log("before calling F.method...");
  2928. // | this.inherited(arguments);
  2929. // | console.log("...back in A");
  2930. // | }
  2931. // | });
  2932. // | new A().method();
  2933. // | // will print:
  2934. // | // raw constructor
  2935. // | // A.constructor
  2936. // | // before calling F.method...
  2937. // | // raw method
  2938. // | // ...back in A
  2939. //
  2940. // example:
  2941. // | var A = dojo.declare(null, {
  2942. // | "-chains-": {
  2943. // | destroy: "before"
  2944. // | }
  2945. // | });
  2946. // | var B = dojo.declare(A, {
  2947. // | constructor: function(){
  2948. // | console.log("B.constructor");
  2949. // | },
  2950. // | destroy: function(){
  2951. // | console.log("B.destroy");
  2952. // | }
  2953. // | });
  2954. // | var C = dojo.declare(B, {
  2955. // | constructor: function(){
  2956. // | console.log("C.constructor");
  2957. // | },
  2958. // | destroy: function(){
  2959. // | console.log("C.destroy");
  2960. // | }
  2961. // | });
  2962. // | new C().destroy();
  2963. // | // prints:
  2964. // | // B.constructor
  2965. // | // C.constructor
  2966. // | // C.destroy
  2967. // | // B.destroy
  2968. //
  2969. // example:
  2970. // | var A = dojo.declare(null, {
  2971. // | "-chains-": {
  2972. // | constructor: "manual"
  2973. // | }
  2974. // | });
  2975. // | var B = dojo.declare(A, {
  2976. // | constructor: function(){
  2977. // | // ...
  2978. // | // call the base constructor with new parameters
  2979. // | this.inherited(arguments, [1, 2, 3]);
  2980. // | // ...
  2981. // | }
  2982. // | });
  2983. //
  2984. // example:
  2985. // | var A = dojo.declare(null, {
  2986. // | "-chains-": {
  2987. // | m1: "before"
  2988. // | },
  2989. // | m1: function(){
  2990. // | console.log("A.m1");
  2991. // | },
  2992. // | m2: function(){
  2993. // | console.log("A.m2");
  2994. // | }
  2995. // | });
  2996. // | var B = dojo.declare(A, {
  2997. // | "-chains-": {
  2998. // | m2: "after"
  2999. // | },
  3000. // | m1: function(){
  3001. // | console.log("B.m1");
  3002. // | },
  3003. // | m2: function(){
  3004. // | console.log("B.m2");
  3005. // | }
  3006. // | });
  3007. // | var x = new B();
  3008. // | x.m1();
  3009. // | // prints:
  3010. // | // B.m1
  3011. // | // A.m1
  3012. // | x.m2();
  3013. // | // prints:
  3014. // | // A.m2
  3015. // | // B.m2
  3016. return new Function(); // Function
  3017. };
  3018. =====*/
  3019. /*=====
  3020. dojo.safeMixin = function(target, source){
  3021. // summary:
  3022. // Mix in properties skipping a constructor and decorating functions
  3023. // like it is done by dojo.declare.
  3024. // target: Object
  3025. // Target object to accept new properties.
  3026. // source: Object
  3027. // Source object for new properties.
  3028. // description:
  3029. // This function is used to mix in properties like dojo._mixin does,
  3030. // but it skips a constructor property and decorates functions like
  3031. // dojo.declare does.
  3032. //
  3033. // It is meant to be used with classes and objects produced with
  3034. // dojo.declare. Functions mixed in with dojo.safeMixin can use
  3035. // this.inherited() like normal methods.
  3036. //
  3037. // This function is used to implement extend() method of a constructor
  3038. // produced with dojo.declare().
  3039. //
  3040. // example:
  3041. // | var A = dojo.declare(null, {
  3042. // | m1: function(){
  3043. // | console.log("A.m1");
  3044. // | },
  3045. // | m2: function(){
  3046. // | console.log("A.m2");
  3047. // | }
  3048. // | });
  3049. // | var B = dojo.declare(A, {
  3050. // | m1: function(){
  3051. // | this.inherited(arguments);
  3052. // | console.log("B.m1");
  3053. // | }
  3054. // | });
  3055. // | B.extend({
  3056. // | m2: function(){
  3057. // | this.inherited(arguments);
  3058. // | console.log("B.m2");
  3059. // | }
  3060. // | });
  3061. // | var x = new B();
  3062. // | dojo.safeMixin(x, {
  3063. // | m1: function(){
  3064. // | this.inherited(arguments);
  3065. // | console.log("X.m1");
  3066. // | },
  3067. // | m2: function(){
  3068. // | this.inherited(arguments);
  3069. // | console.log("X.m2");
  3070. // | }
  3071. // | });
  3072. // | x.m2();
  3073. // | // prints:
  3074. // | // A.m1
  3075. // | // B.m1
  3076. // | // X.m1
  3077. };
  3078. =====*/
  3079. /*=====
  3080. Object.inherited = function(name, args, newArgs){
  3081. // summary:
  3082. // Calls a super method.
  3083. // name: String?
  3084. // The optional method name. Should be the same as the caller's
  3085. // name. Usually "name" is specified in complex dynamic cases, when
  3086. // the calling method was dynamically added, undecorated by
  3087. // dojo.declare, and it cannot be determined.
  3088. // args: Arguments
  3089. // The caller supply this argument, which should be the original
  3090. // "arguments".
  3091. // newArgs: Object?
  3092. // If "true", the found function will be returned without
  3093. // executing it.
  3094. // If Array, it will be used to call a super method. Otherwise
  3095. // "args" will be used.
  3096. // returns:
  3097. // Whatever is returned by a super method, or a super method itself,
  3098. // if "true" was specified as newArgs.
  3099. // description:
  3100. // This method is used inside method of classes produced with
  3101. // dojo.declare to call a super method (next in the chain). It is
  3102. // used for manually controlled chaining. Consider using the regular
  3103. // chaining, because it is faster. Use "this.inherited()" only in
  3104. // complex cases.
  3105. //
  3106. // This method cannot me called from automatically chained
  3107. // constructors including the case of a special (legacy)
  3108. // constructor chaining. It cannot be called from chained methods.
  3109. //
  3110. // If "this.inherited()" cannot find the next-in-chain method, it
  3111. // does nothing and returns "undefined". The last method in chain
  3112. // can be a default method implemented in Object, which will be
  3113. // called last.
  3114. //
  3115. // If "name" is specified, it is assumed that the method that
  3116. // received "args" is the parent method for this call. It is looked
  3117. // up in the chain list and if it is found the next-in-chain method
  3118. // is called. If it is not found, the first-in-chain method is
  3119. // called.
  3120. //
  3121. // If "name" is not specified, it will be derived from the calling
  3122. // method (using a methoid property "nom").
  3123. //
  3124. // example:
  3125. // | var B = dojo.declare(A, {
  3126. // | method1: function(a, b, c){
  3127. // | this.inherited(arguments);
  3128. // | },
  3129. // | method2: function(a, b){
  3130. // | return this.inherited(arguments, [a + b]);
  3131. // | }
  3132. // | });
  3133. // | // next method is not in the chain list because it is added
  3134. // | // manually after the class was created.
  3135. // | B.prototype.method3 = function(){
  3136. // | console.log("This is a dynamically-added method.");
  3137. // | this.inherited("method3", arguments);
  3138. // | };
  3139. // example:
  3140. // | var B = dojo.declare(A, {
  3141. // | method: function(a, b){
  3142. // | var super = this.inherited(arguments, true);
  3143. // | // ...
  3144. // | if(!super){
  3145. // | console.log("there is no super method");
  3146. // | return 0;
  3147. // | }
  3148. // | return super.apply(this, arguments);
  3149. // | }
  3150. // | });
  3151. return {}; // Object
  3152. }
  3153. =====*/
  3154. /*=====
  3155. Object.getInherited = function(name, args){
  3156. // summary:
  3157. // Returns a super method.
  3158. // name: String?
  3159. // The optional method name. Should be the same as the caller's
  3160. // name. Usually "name" is specified in complex dynamic cases, when
  3161. // the calling method was dynamically added, undecorated by
  3162. // dojo.declare, and it cannot be determined.
  3163. // args: Arguments
  3164. // The caller supply this argument, which should be the original
  3165. // "arguments".
  3166. // returns:
  3167. // Returns a super method (Function) or "undefined".
  3168. // description:
  3169. // This method is a convenience method for "this.inherited()".
  3170. // It uses the same algorithm but instead of executing a super
  3171. // method, it returns it, or "undefined" if not found.
  3172. //
  3173. // example:
  3174. // | var B = dojo.declare(A, {
  3175. // | method: function(a, b){
  3176. // | var super = this.getInherited(arguments);
  3177. // | // ...
  3178. // | if(!super){
  3179. // | console.log("there is no super method");
  3180. // | return 0;
  3181. // | }
  3182. // | return super.apply(this, arguments);
  3183. // | }
  3184. // | });
  3185. return {}; // Object
  3186. }
  3187. =====*/
  3188. /*=====
  3189. Object.isInstanceOf = function(cls){
  3190. // summary:
  3191. // Checks the inheritance chain to see if it is inherited from this
  3192. // class.
  3193. // cls: Function
  3194. // Class constructor.
  3195. // returns:
  3196. // "true", if this object is inherited from this class, "false"
  3197. // otherwise.
  3198. // description:
  3199. // This method is used with instances of classes produced with
  3200. // dojo.declare to determine of they support a certain interface or
  3201. // not. It models "instanceof" operator.
  3202. //
  3203. // example:
  3204. // | var A = dojo.declare(null, {
  3205. // | // constructor, properties, and methods go here
  3206. // | // ...
  3207. // | });
  3208. // | var B = dojo.declare(null, {
  3209. // | // constructor, properties, and methods go here
  3210. // | // ...
  3211. // | });
  3212. // | var C = dojo.declare([A, B], {
  3213. // | // constructor, properties, and methods go here
  3214. // | // ...
  3215. // | });
  3216. // | var D = dojo.declare(A, {
  3217. // | // constructor, properties, and methods go here
  3218. // | // ...
  3219. // | });
  3220. // |
  3221. // | var a = new A(), b = new B(), c = new C(), d = new D();
  3222. // |
  3223. // | console.log(a.isInstanceOf(A)); // true
  3224. // | console.log(b.isInstanceOf(A)); // false
  3225. // | console.log(c.isInstanceOf(A)); // true
  3226. // | console.log(d.isInstanceOf(A)); // true
  3227. // |
  3228. // | console.log(a.isInstanceOf(B)); // false
  3229. // | console.log(b.isInstanceOf(B)); // true
  3230. // | console.log(c.isInstanceOf(B)); // true
  3231. // | console.log(d.isInstanceOf(B)); // false
  3232. // |
  3233. // | console.log(a.isInstanceOf(C)); // false
  3234. // | console.log(b.isInstanceOf(C)); // false
  3235. // | console.log(c.isInstanceOf(C)); // true
  3236. // | console.log(d.isInstanceOf(C)); // false
  3237. // |
  3238. // | console.log(a.isInstanceOf(D)); // false
  3239. // | console.log(b.isInstanceOf(D)); // false
  3240. // | console.log(c.isInstanceOf(D)); // false
  3241. // | console.log(d.isInstanceOf(D)); // true
  3242. return {}; // Object
  3243. }
  3244. =====*/
  3245. /*=====
  3246. Object.extend = function(source){
  3247. // summary:
  3248. // Adds all properties and methods of source to constructor's
  3249. // prototype, making them available to all instances created with
  3250. // constructor. This method is specific to constructors created with
  3251. // dojo.declare.
  3252. // source: Object
  3253. // Source object which properties are going to be copied to the
  3254. // constructor's prototype.
  3255. // description:
  3256. // Adds source properties to the constructor's prototype. It can
  3257. // override existing properties.
  3258. //
  3259. // This method is similar to dojo.extend function, but it is specific
  3260. // to constructors produced by dojo.declare. It is implemented
  3261. // using dojo.safeMixin, and it skips a constructor property,
  3262. // and properly decorates copied functions.
  3263. //
  3264. // example:
  3265. // | var A = dojo.declare(null, {
  3266. // | m1: function(){},
  3267. // | s1: "Popokatepetl"
  3268. // | });
  3269. // | A.extend({
  3270. // | m1: function(){},
  3271. // | m2: function(){},
  3272. // | f1: true,
  3273. // | d1: 42
  3274. // | });
  3275. };
  3276. =====*/
  3277. })();
  3278. }
  3279. if(!dojo._hasResource["dojo._base.connect"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  3280. dojo._hasResource["dojo._base.connect"] = true;
  3281. dojo.provide("dojo._base.connect");
  3282. // this file courtesy of the TurboAjax Group, licensed under a Dojo CLA
  3283. // low-level delegation machinery
  3284. dojo._listener = {
  3285. // create a dispatcher function
  3286. getDispatcher: function(){
  3287. // following comments pulled out-of-line to prevent cloning them
  3288. // in the returned function.
  3289. // - indices (i) that are really in the array of listeners (ls) will
  3290. // not be in Array.prototype. This is the 'sparse array' trick
  3291. // that keeps us safe from libs that take liberties with built-in
  3292. // objects
  3293. // - listener is invoked with current scope (this)
  3294. return function(){
  3295. var ap = Array.prototype, c = arguments.callee, ls = c._listeners, t = c.target,
  3296. // return value comes from original target function
  3297. r = t && t.apply(this, arguments),
  3298. // make local copy of listener array so it is immutable during processing
  3299. i, lls = [].concat(ls)
  3300. ;
  3301. // invoke listeners after target function
  3302. for(i in lls){
  3303. if(!(i in ap)){
  3304. lls[i].apply(this, arguments);
  3305. }
  3306. }
  3307. // return value comes from original target function
  3308. return r;
  3309. };
  3310. },
  3311. // add a listener to an object
  3312. add: function(/*Object*/ source, /*String*/ method, /*Function*/ listener){
  3313. // Whenever 'method' is invoked, 'listener' will have the same scope.
  3314. // Trying to supporting a context object for the listener led to
  3315. // complexity.
  3316. // Non trivial to provide 'once' functionality here
  3317. // because listener could be the result of a dojo.hitch call,
  3318. // in which case two references to the same hitch target would not
  3319. // be equivalent.
  3320. source = source || dojo.global;
  3321. // The source method is either null, a dispatcher, or some other function
  3322. var f = source[method];
  3323. // Ensure a dispatcher
  3324. if(!f || !f._listeners){
  3325. var d = dojo._listener.getDispatcher();
  3326. // original target function is special
  3327. d.target = f;
  3328. // dispatcher holds a list of listeners
  3329. d._listeners = [];
  3330. // redirect source to dispatcher
  3331. f = source[method] = d;
  3332. }
  3333. // The contract is that a handle is returned that can
  3334. // identify this listener for disconnect.
  3335. //
  3336. // The type of the handle is private. Here is it implemented as Integer.
  3337. // DOM event code has this same contract but handle is Function
  3338. // in non-IE browsers.
  3339. //
  3340. // We could have separate lists of before and after listeners.
  3341. return f._listeners.push(listener); /*Handle*/
  3342. },
  3343. // remove a listener from an object
  3344. remove: function(/*Object*/ source, /*String*/ method, /*Handle*/ handle){
  3345. var f = (source || dojo.global)[method];
  3346. // remember that handle is the index+1 (0 is not a valid handle)
  3347. if(f && f._listeners && handle--){
  3348. delete f._listeners[handle];
  3349. }
  3350. }
  3351. };
  3352. // Multiple delegation for arbitrary methods.
  3353. // This unit knows nothing about DOM, but we include DOM aware documentation
  3354. // and dontFix argument here to help the autodocs. Actual DOM aware code is in
  3355. // event.js.
  3356. dojo.connect = function(/*Object|null*/ obj,
  3357. /*String*/ event,
  3358. /*Object|null*/ context,
  3359. /*String|Function*/ method,
  3360. /*Boolean?*/ dontFix){
  3361. // summary:
  3362. // `dojo.connect` is the core event handling and delegation method in
  3363. // Dojo. It allows one function to "listen in" on the execution of
  3364. // any other, triggering the second whenever the first is called. Many
  3365. // listeners may be attached to a function, and source functions may
  3366. // be either regular function calls or DOM events.
  3367. //
  3368. // description:
  3369. // Connects listeners to actions, so that after event fires, a
  3370. // listener is called with the same arguments passed to the original
  3371. // function.
  3372. //
  3373. // Since `dojo.connect` allows the source of events to be either a
  3374. // "regular" JavaScript function or a DOM event, it provides a uniform
  3375. // interface for listening to all the types of events that an
  3376. // application is likely to deal with though a single, unified
  3377. // interface. DOM programmers may want to think of it as
  3378. // "addEventListener for everything and anything".
  3379. //
  3380. // When setting up a connection, the `event` parameter must be a
  3381. // string that is the name of the method/event to be listened for. If
  3382. // `obj` is null, `dojo.global` is assumed, meaning that connections
  3383. // to global methods are supported but also that you may inadvertently
  3384. // connect to a global by passing an incorrect object name or invalid
  3385. // reference.
  3386. //
  3387. // `dojo.connect` generally is forgiving. If you pass the name of a
  3388. // function or method that does not yet exist on `obj`, connect will
  3389. // not fail, but will instead set up a stub method. Similarly, null
  3390. // arguments may simply be omitted such that fewer than 4 arguments
  3391. // may be required to set up a connection See the examples for details.
  3392. //
  3393. // The return value is a handle that is needed to
  3394. // remove this connection with `dojo.disconnect`.
  3395. //
  3396. // obj:
  3397. // The source object for the event function.
  3398. // Defaults to `dojo.global` if null.
  3399. // If obj is a DOM node, the connection is delegated
  3400. // to the DOM event manager (unless dontFix is true).
  3401. //
  3402. // event:
  3403. // String name of the event function in obj.
  3404. // I.e. identifies a property `obj[event]`.
  3405. //
  3406. // context:
  3407. // The object that method will receive as "this".
  3408. //
  3409. // If context is null and method is a function, then method
  3410. // inherits the context of event.
  3411. //
  3412. // If method is a string then context must be the source
  3413. // object object for method (context[method]). If context is null,
  3414. // dojo.global is used.
  3415. //
  3416. // method:
  3417. // A function reference, or name of a function in context.
  3418. // The function identified by method fires after event does.
  3419. // method receives the same arguments as the event.
  3420. // See context argument comments for information on method's scope.
  3421. //
  3422. // dontFix:
  3423. // If obj is a DOM node, set dontFix to true to prevent delegation
  3424. // of this connection to the DOM event manager.
  3425. //
  3426. // example:
  3427. // When obj.onchange(), do ui.update():
  3428. // | dojo.connect(obj, "onchange", ui, "update");
  3429. // | dojo.connect(obj, "onchange", ui, ui.update); // same
  3430. //
  3431. // example:
  3432. // Using return value for disconnect:
  3433. // | var link = dojo.connect(obj, "onchange", ui, "update");
  3434. // | ...
  3435. // | dojo.disconnect(link);
  3436. //
  3437. // example:
  3438. // When onglobalevent executes, watcher.handler is invoked:
  3439. // | dojo.connect(null, "onglobalevent", watcher, "handler");
  3440. //
  3441. // example:
  3442. // When ob.onCustomEvent executes, customEventHandler is invoked:
  3443. // | dojo.connect(ob, "onCustomEvent", null, "customEventHandler");
  3444. // | dojo.connect(ob, "onCustomEvent", "customEventHandler"); // same
  3445. //
  3446. // example:
  3447. // When ob.onCustomEvent executes, customEventHandler is invoked
  3448. // with the same scope (this):
  3449. // | dojo.connect(ob, "onCustomEvent", null, customEventHandler);
  3450. // | dojo.connect(ob, "onCustomEvent", customEventHandler); // same
  3451. //
  3452. // example:
  3453. // When globalEvent executes, globalHandler is invoked
  3454. // with the same scope (this):
  3455. // | dojo.connect(null, "globalEvent", null, globalHandler);
  3456. // | dojo.connect("globalEvent", globalHandler); // same
  3457. // normalize arguments
  3458. var a=arguments, args=[], i=0;
  3459. // if a[0] is a String, obj was omitted
  3460. args.push(dojo.isString(a[0]) ? null : a[i++], a[i++]);
  3461. // if the arg-after-next is a String or Function, context was NOT omitted
  3462. var a1 = a[i+1];
  3463. args.push(dojo.isString(a1)||dojo.isFunction(a1) ? a[i++] : null, a[i++]);
  3464. // absorb any additional arguments
  3465. for(var l=a.length; i<l; i++){ args.push(a[i]); }
  3466. // do the actual work
  3467. return dojo._connect.apply(this, args); /*Handle*/
  3468. }
  3469. // used by non-browser hostenvs. always overriden by event.js
  3470. dojo._connect = function(obj, event, context, method){
  3471. var l=dojo._listener, h=l.add(obj, event, dojo.hitch(context, method));
  3472. return [obj, event, h, l]; // Handle
  3473. };
  3474. dojo.disconnect = function(/*Handle*/ handle){
  3475. // summary:
  3476. // Remove a link created by dojo.connect.
  3477. // description:
  3478. // Removes the connection between event and the method referenced by handle.
  3479. // handle:
  3480. // the return value of the dojo.connect call that created the connection.
  3481. if(handle && handle[0] !== undefined){
  3482. dojo._disconnect.apply(this, handle);
  3483. // let's not keep this reference
  3484. delete handle[0];
  3485. }
  3486. };
  3487. dojo._disconnect = function(obj, event, handle, listener){
  3488. listener.remove(obj, event, handle);
  3489. };
  3490. // topic publish/subscribe
  3491. dojo._topics = {};
  3492. dojo.subscribe = function(/*String*/ topic, /*Object|null*/ context, /*String|Function*/ method){
  3493. // summary:
  3494. // Attach a listener to a named topic. The listener function is invoked whenever the
  3495. // named topic is published (see: dojo.publish).
  3496. // Returns a handle which is needed to unsubscribe this listener.
  3497. // context:
  3498. // Scope in which method will be invoked, or null for default scope.
  3499. // method:
  3500. // The name of a function in context, or a function reference. This is the function that
  3501. // is invoked when topic is published.
  3502. // example:
  3503. // | dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); });
  3504. // | dojo.publish("alerts", [ "read this", "hello world" ]);
  3505. // support for 2 argument invocation (omitting context) depends on hitch
  3506. return [topic, dojo._listener.add(dojo._topics, topic, dojo.hitch(context, method))]; /*Handle*/
  3507. };
  3508. dojo.unsubscribe = function(/*Handle*/ handle){
  3509. // summary:
  3510. // Remove a topic listener.
  3511. // handle:
  3512. // The handle returned from a call to subscribe.
  3513. // example:
  3514. // | var alerter = dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
  3515. // | ...
  3516. // | dojo.unsubscribe(alerter);
  3517. if(handle){
  3518. dojo._listener.remove(dojo._topics, handle[0], handle[1]);
  3519. }
  3520. };
  3521. dojo.publish = function(/*String*/ topic, /*Array*/ args){
  3522. // summary:
  3523. // Invoke all listener method subscribed to topic.
  3524. // topic:
  3525. // The name of the topic to publish.
  3526. // args:
  3527. // An array of arguments. The arguments will be applied
  3528. // to each topic subscriber (as first class parameters, via apply).
  3529. // example:
  3530. // | dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
  3531. // | dojo.publish("alerts", [ "read this", "hello world" ]);
  3532. // Note that args is an array, which is more efficient vs variable length
  3533. // argument list. Ideally, var args would be implemented via Array
  3534. // throughout the APIs.
  3535. var f = dojo._topics[topic];
  3536. if(f){
  3537. f.apply(this, args||[]);
  3538. }
  3539. };
  3540. dojo.connectPublisher = function( /*String*/ topic,
  3541. /*Object|null*/ obj,
  3542. /*String*/ event){
  3543. // summary:
  3544. // Ensure that every time obj.event() is called, a message is published
  3545. // on the topic. Returns a handle which can be passed to
  3546. // dojo.disconnect() to disable subsequent automatic publication on
  3547. // the topic.
  3548. // topic:
  3549. // The name of the topic to publish.
  3550. // obj:
  3551. // The source object for the event function. Defaults to dojo.global
  3552. // if null.
  3553. // event:
  3554. // The name of the event function in obj.
  3555. // I.e. identifies a property obj[event].
  3556. // example:
  3557. // | dojo.connectPublisher("/ajax/start", dojo, "xhrGet");
  3558. var pf = function(){ dojo.publish(topic, arguments); }
  3559. return event ? dojo.connect(obj, event, pf) : dojo.connect(obj, pf); //Handle
  3560. };
  3561. }
  3562. if(!dojo._hasResource["dojo._base.Deferred"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  3563. dojo._hasResource["dojo._base.Deferred"] = true;
  3564. dojo.provide("dojo._base.Deferred");
  3565. (function(){
  3566. var mutator = function(){};
  3567. var freeze = Object.freeze || function(){};
  3568. // A deferred provides an API for creating and resolving a promise.
  3569. dojo.Deferred = function(/*Function?*/canceller){
  3570. // summary:
  3571. // Deferreds provide a generic means for encapsulating an asynchronous
  3572. // operation and notifying users of the completion and result of the operation.
  3573. // description:
  3574. // The dojo.Deferred API is based on the concept of promises that provide a
  3575. // generic interface into the eventual completion of an asynchronous action.
  3576. // The motivation for promises fundamentally is about creating a
  3577. // separation of concerns that allows one to achieve the same type of
  3578. // call patterns and logical data flow in asynchronous code as can be
  3579. // achieved in synchronous code. Promises allows one
  3580. // to be able to call a function purely with arguments needed for
  3581. // execution, without conflating the call with concerns of whether it is
  3582. // sync or async. One shouldn't need to alter a call's arguments if the
  3583. // implementation switches from sync to async (or vice versa). By having
  3584. // async functions return promises, the concerns of making the call are
  3585. // separated from the concerns of asynchronous interaction (which are
  3586. // handled by the promise).
  3587. //
  3588. // The dojo.Deferred is a type of promise that provides methods for fulfilling the
  3589. // promise with a successful result or an error. The most important method for
  3590. // working with Dojo's promises is the then() method, which follows the
  3591. // CommonJS proposed promise API. An example of using a Dojo promise:
  3592. //
  3593. // | var resultingPromise = someAsyncOperation.then(function(result){
  3594. // | ... handle result ...
  3595. // | },
  3596. // | function(error){
  3597. // | ... handle error ...
  3598. // | });
  3599. //
  3600. // The .then() call returns a new promise that represents the result of the
  3601. // execution of the callback. The callbacks will never affect the original promises value.
  3602. //
  3603. // The dojo.Deferred instances also provide the following functions for backwards compatibility:
  3604. //
  3605. // * addCallback(handler)
  3606. // * addErrback(handler)
  3607. // * callback(result)
  3608. // * errback(result)
  3609. //
  3610. // Callbacks are allowed to return promises themselves, so
  3611. // you can build complicated sequences of events with ease.
  3612. //
  3613. // The creator of the Deferred may specify a canceller. The canceller
  3614. // is a function that will be called if Deferred.cancel is called
  3615. // before the Deferred fires. You can use this to implement clean
  3616. // aborting of an XMLHttpRequest, etc. Note that cancel will fire the
  3617. // deferred with a CancelledError (unless your canceller returns
  3618. // another kind of error), so the errbacks should be prepared to
  3619. // handle that error for cancellable Deferreds.
  3620. // example:
  3621. // | var deferred = new dojo.Deferred();
  3622. // | setTimeout(function(){ deferred.callback({success: true}); }, 1000);
  3623. // | return deferred;
  3624. // example:
  3625. // Deferred objects are often used when making code asynchronous. It
  3626. // may be easiest to write functions in a synchronous manner and then
  3627. // split code using a deferred to trigger a response to a long-lived
  3628. // operation. For example, instead of register a callback function to
  3629. // denote when a rendering operation completes, the function can
  3630. // simply return a deferred:
  3631. //
  3632. // | // callback style:
  3633. // | function renderLotsOfData(data, callback){
  3634. // | var success = false
  3635. // | try{
  3636. // | for(var x in data){
  3637. // | renderDataitem(data[x]);
  3638. // | }
  3639. // | success = true;
  3640. // | }catch(e){ }
  3641. // | if(callback){
  3642. // | callback(success);
  3643. // | }
  3644. // | }
  3645. //
  3646. // | // using callback style
  3647. // | renderLotsOfData(someDataObj, function(success){
  3648. // | // handles success or failure
  3649. // | if(!success){
  3650. // | promptUserToRecover();
  3651. // | }
  3652. // | });
  3653. // | // NOTE: no way to add another callback here!!
  3654. // example:
  3655. // Using a Deferred doesn't simplify the sending code any, but it
  3656. // provides a standard interface for callers and senders alike,
  3657. // providing both with a simple way to service multiple callbacks for
  3658. // an operation and freeing both sides from worrying about details
  3659. // such as "did this get called already?". With Deferreds, new
  3660. // callbacks can be added at any time.
  3661. //
  3662. // | // Deferred style:
  3663. // | function renderLotsOfData(data){
  3664. // | var d = new dojo.Deferred();
  3665. // | try{
  3666. // | for(var x in data){
  3667. // | renderDataitem(data[x]);
  3668. // | }
  3669. // | d.callback(true);
  3670. // | }catch(e){
  3671. // | d.errback(new Error("rendering failed"));
  3672. // | }
  3673. // | return d;
  3674. // | }
  3675. //
  3676. // | // using Deferred style
  3677. // | renderLotsOfData(someDataObj).then(null, function(){
  3678. // | promptUserToRecover();
  3679. // | });
  3680. // | // NOTE: addErrback and addCallback both return the Deferred
  3681. // | // again, so we could chain adding callbacks or save the
  3682. // | // deferred for later should we need to be notified again.
  3683. // example:
  3684. // In this example, renderLotsOfData is synchronous and so both
  3685. // versions are pretty artificial. Putting the data display on a
  3686. // timeout helps show why Deferreds rock:
  3687. //
  3688. // | // Deferred style and async func
  3689. // | function renderLotsOfData(data){
  3690. // | var d = new dojo.Deferred();
  3691. // | setTimeout(function(){
  3692. // | try{
  3693. // | for(var x in data){
  3694. // | renderDataitem(data[x]);
  3695. // | }
  3696. // | d.callback(true);
  3697. // | }catch(e){
  3698. // | d.errback(new Error("rendering failed"));
  3699. // | }
  3700. // | }, 100);
  3701. // | return d;
  3702. // | }
  3703. //
  3704. // | // using Deferred style
  3705. // | renderLotsOfData(someDataObj).then(null, function(){
  3706. // | promptUserToRecover();
  3707. // | });
  3708. //
  3709. // Note that the caller doesn't have to change his code at all to
  3710. // handle the asynchronous case.
  3711. var result, finished, isError, head, nextListener;
  3712. var promise = (this.promise = {});
  3713. function complete(value){
  3714. if(finished){
  3715. throw new Error("This deferred has already been resolved");
  3716. }
  3717. result = value;
  3718. finished = true;
  3719. notify();
  3720. }
  3721. function notify(){
  3722. var mutated;
  3723. while(!mutated && nextListener){
  3724. var listener = nextListener;
  3725. nextListener = nextListener.next;
  3726. if((mutated = (listener.progress == mutator))){ // assignment and check
  3727. finished = false;
  3728. }
  3729. var func = (isError ? listener.error : listener.resolved);
  3730. if (func) {
  3731. try {
  3732. var newResult = func(result);
  3733. if (newResult && typeof newResult.then === "function") {
  3734. newResult.then(dojo.hitch(listener.deferred, "resolve"), dojo.hitch(listener.deferred, "reject"));
  3735. continue;
  3736. }
  3737. var unchanged = mutated && newResult === undefined;
  3738. if(mutated && !unchanged){
  3739. isError = newResult instanceof Error;
  3740. }
  3741. listener.deferred[unchanged && isError ? "reject" : "resolve"](unchanged ? result : newResult);
  3742. }
  3743. catch (e) {
  3744. listener.deferred.reject(e);
  3745. }
  3746. }else {
  3747. if(isError){
  3748. listener.deferred.reject(result);
  3749. }else{
  3750. listener.deferred.resolve(result);
  3751. }
  3752. }
  3753. }
  3754. }
  3755. // calling resolve will resolve the promise
  3756. this.resolve = this.callback = function(value){
  3757. // summary:
  3758. // Fulfills the Deferred instance successfully with the provide value
  3759. this.fired = 0;
  3760. this.results = [value, null];
  3761. complete(value);
  3762. };
  3763. // calling error will indicate that the promise failed
  3764. this.reject = this.errback = function(error){
  3765. // summary:
  3766. // Fulfills the Deferred instance as an error with the provided error
  3767. isError = true;
  3768. this.fired = 1;
  3769. complete(error);
  3770. this.results = [null, error];
  3771. if(!error || error.log !== false){
  3772. (dojo.config.deferredOnError || function(x){ console.error(x); })(error);
  3773. }
  3774. };
  3775. // call progress to provide updates on the progress on the completion of the promise
  3776. this.progress = function(update){
  3777. // summary
  3778. // Send progress events to all listeners
  3779. var listener = nextListener;
  3780. while(listener){
  3781. var progress = listener.progress;
  3782. progress && progress(update);
  3783. listener = listener.next;
  3784. }
  3785. };
  3786. this.addCallbacks = function(/*Function?*/callback, /*Function?*/errback){
  3787. this.then(callback, errback, mutator);
  3788. return this;
  3789. };
  3790. // provide the implementation of the promise
  3791. this.then = promise.then = function(/*Function?*/resolvedCallback, /*Function?*/errorCallback, /*Function?*/progressCallback){
  3792. // summary:
  3793. // Adds a fulfilledHandler, errorHandler, and progressHandler to be called for
  3794. // completion of a promise. The fulfilledHandler is called when the promise
  3795. // is fulfilled. The errorHandler is called when a promise fails. The
  3796. // progressHandler is called for progress events. All arguments are optional
  3797. // and non-function values are ignored. The progressHandler is not only an
  3798. // optional argument, but progress events are purely optional. Promise
  3799. // providers are not required to ever create progress events.
  3800. //
  3801. // This function will return a new promise that is fulfilled when the given
  3802. // fulfilledHandler or errorHandler callback is finished. This allows promise
  3803. // operations to be chained together. The value returned from the callback
  3804. // handler is the fulfillment value for the returned promise. If the callback
  3805. // throws an error, the returned promise will be moved to failed state.
  3806. //
  3807. // example:
  3808. // An example of using a CommonJS compliant promise:
  3809. // | asyncComputeTheAnswerToEverything().
  3810. // | then(addTwo).
  3811. // | then(printResult, onError);
  3812. // | >44
  3813. //
  3814. var returnDeferred = progressCallback == mutator ? this : new dojo.Deferred(promise.cancel);
  3815. var listener = {
  3816. resolved: resolvedCallback,
  3817. error: errorCallback,
  3818. progress: progressCallback,
  3819. deferred: returnDeferred
  3820. };
  3821. if(nextListener){
  3822. head = head.next = listener;
  3823. }
  3824. else{
  3825. nextListener = head = listener;
  3826. }
  3827. if(finished){
  3828. notify();
  3829. }
  3830. return returnDeferred.promise;
  3831. };
  3832. var deferred = this;
  3833. this.cancel = promise.cancel = function () {
  3834. // summary:
  3835. // Cancels the asynchronous operation
  3836. if(!finished){
  3837. var error = canceller && canceller(deferred);
  3838. if(!finished){
  3839. if (!(error instanceof Error)) {
  3840. error = new Error(error);
  3841. }
  3842. error.log = false;
  3843. deferred.reject(error);
  3844. }
  3845. }
  3846. };
  3847. freeze(promise);
  3848. };
  3849. dojo.extend(dojo.Deferred, {
  3850. addCallback: function (/*Function*/callback) {
  3851. return this.addCallbacks(dojo.hitch.apply(dojo, arguments));
  3852. },
  3853. addErrback: function (/*Function*/errback) {
  3854. return this.addCallbacks(null, dojo.hitch.apply(dojo, arguments));
  3855. },
  3856. addBoth: function (/*Function*/callback) {
  3857. var enclosed = dojo.hitch.apply(dojo, arguments);
  3858. return this.addCallbacks(enclosed, enclosed);
  3859. },
  3860. fired: -1
  3861. });
  3862. })();
  3863. dojo.when = function(promiseOrValue, /*Function?*/callback, /*Function?*/errback, /*Function?*/progressHandler){
  3864. // summary:
  3865. // This provides normalization between normal synchronous values and
  3866. // asynchronous promises, so you can interact with them in a common way
  3867. // example:
  3868. // | function printFirstAndList(items){
  3869. // | dojo.when(findFirst(items), console.log);
  3870. // | dojo.when(findLast(items), console.log);
  3871. // | }
  3872. // | function findFirst(items){
  3873. // | return dojo.when(items, function(items){
  3874. // | return items[0];
  3875. // | });
  3876. // | }
  3877. // | function findLast(items){
  3878. // | return dojo.when(items, function(items){
  3879. // | return items[items.length];
  3880. // | });
  3881. // | }
  3882. // And now all three of his functions can be used sync or async.
  3883. // | printFirstAndLast([1,2,3,4]) will work just as well as
  3884. // | printFirstAndLast(dojo.xhrGet(...));
  3885. if(promiseOrValue && typeof promiseOrValue.then === "function"){
  3886. return promiseOrValue.then(callback, errback, progressHandler);
  3887. }
  3888. return callback(promiseOrValue);
  3889. };
  3890. }
  3891. if(!dojo._hasResource["dojo._base.json"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  3892. dojo._hasResource["dojo._base.json"] = true;
  3893. dojo.provide("dojo._base.json");
  3894. dojo.fromJson = function(/*String*/ json){
  3895. // summary:
  3896. // Parses a [JSON](http://json.org) string to return a JavaScript object.
  3897. // description:
  3898. // Throws for invalid JSON strings, but it does not use a strict JSON parser. It
  3899. // delegates to eval(). The content passed to this method must therefore come
  3900. // from a trusted source.
  3901. // json:
  3902. // a string literal of a JSON item, for instance:
  3903. // `'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'`
  3904. return eval("(" + json + ")"); // Object
  3905. };
  3906. dojo._escapeString = function(/*String*/str){
  3907. //summary:
  3908. // Adds escape sequences for non-visual characters, double quote and
  3909. // backslash and surrounds with double quotes to form a valid string
  3910. // literal.
  3911. return ('"' + str.replace(/(["\\])/g, '\\$1') + '"').
  3912. replace(/[\f]/g, "\\f").replace(/[\b]/g, "\\b").replace(/[\n]/g, "\\n").
  3913. replace(/[\t]/g, "\\t").replace(/[\r]/g, "\\r"); // string
  3914. };
  3915. dojo.toJsonIndentStr = "\t";
  3916. dojo.toJson = function(/*Object*/ it, /*Boolean?*/ prettyPrint, /*String?*/ _indentStr){
  3917. // summary:
  3918. // Returns a [JSON](http://json.org) serialization of an object.
  3919. // description:
  3920. // Returns a [JSON](http://json.org) serialization of an object.
  3921. // Note that this doesn't check for infinite recursion, so don't do that!
  3922. // it:
  3923. // an object to be serialized. Objects may define their own
  3924. // serialization via a special "__json__" or "json" function
  3925. // property. If a specialized serializer has been defined, it will
  3926. // be used as a fallback.
  3927. // prettyPrint:
  3928. // if true, we indent objects and arrays to make the output prettier.
  3929. // The variable `dojo.toJsonIndentStr` is used as the indent string --
  3930. // to use something other than the default (tab), change that variable
  3931. // before calling dojo.toJson().
  3932. // _indentStr:
  3933. // private variable for recursive calls when pretty printing, do not use.
  3934. // example:
  3935. // simple serialization of a trivial object
  3936. // | var jsonStr = dojo.toJson({ howdy: "stranger!", isStrange: true });
  3937. // | doh.is('{"howdy":"stranger!","isStrange":true}', jsonStr);
  3938. // example:
  3939. // a custom serializer for an objects of a particular class:
  3940. // | dojo.declare("Furby", null, {
  3941. // | furbies: "are strange",
  3942. // | furbyCount: 10,
  3943. // | __json__: function(){
  3944. // | },
  3945. // | });
  3946. if(it === undefined){
  3947. return "undefined";
  3948. }
  3949. var objtype = typeof it;
  3950. if(objtype == "number" || objtype == "boolean"){
  3951. return it + "";
  3952. }
  3953. if(it === null){
  3954. return "null";
  3955. }
  3956. if(dojo.isString(it)){
  3957. return dojo._escapeString(it);
  3958. }
  3959. // recurse
  3960. var recurse = arguments.callee;
  3961. // short-circuit for objects that support "json" serialization
  3962. // if they return "self" then just pass-through...
  3963. var newObj;
  3964. _indentStr = _indentStr || "";
  3965. var nextIndent = prettyPrint ? _indentStr + dojo.toJsonIndentStr : "";
  3966. var tf = it.__json__||it.json;
  3967. if(dojo.isFunction(tf)){
  3968. newObj = tf.call(it);
  3969. if(it !== newObj){
  3970. return recurse(newObj, prettyPrint, nextIndent);
  3971. }
  3972. }
  3973. if(it.nodeType && it.cloneNode){ // isNode
  3974. // we can't seriailize DOM nodes as regular objects because they have cycles
  3975. // DOM nodes could be serialized with something like outerHTML, but
  3976. // that can be provided by users in the form of .json or .__json__ function.
  3977. throw new Error("Can't serialize DOM nodes");
  3978. }
  3979. var sep = prettyPrint ? " " : "";
  3980. var newLine = prettyPrint ? "\n" : "";
  3981. // array
  3982. if(dojo.isArray(it)){
  3983. var res = dojo.map(it, function(obj){
  3984. var val = recurse(obj, prettyPrint, nextIndent);
  3985. if(typeof val != "string"){
  3986. val = "undefined";
  3987. }
  3988. return newLine + nextIndent + val;
  3989. });
  3990. return "[" + res.join("," + sep) + newLine + _indentStr + "]";
  3991. }
  3992. /*
  3993. // look in the registry
  3994. try {
  3995. window.o = it;
  3996. newObj = dojo.json.jsonRegistry.match(it);
  3997. return recurse(newObj, prettyPrint, nextIndent);
  3998. }catch(e){
  3999. // console.log(e);
  4000. }
  4001. // it's a function with no adapter, skip it
  4002. */
  4003. if(objtype == "function"){
  4004. return null; // null
  4005. }
  4006. // generic object code path
  4007. var output = [], key;
  4008. for(key in it){
  4009. var keyStr, val;
  4010. if(typeof key == "number"){
  4011. keyStr = '"' + key + '"';
  4012. }else if(typeof key == "string"){
  4013. keyStr = dojo._escapeString(key);
  4014. }else{
  4015. // skip non-string or number keys
  4016. continue;
  4017. }
  4018. val = recurse(it[key], prettyPrint, nextIndent);
  4019. if(typeof val != "string"){
  4020. // skip non-serializable values
  4021. continue;
  4022. }
  4023. // FIXME: use += on Moz!!
  4024. // MOW NOTE: using += is a pain because you have to account for the dangling comma...
  4025. output.push(newLine + nextIndent + keyStr + ":" + sep + val);
  4026. }
  4027. return "{" + output.join("," + sep) + newLine + _indentStr + "}"; // String
  4028. };
  4029. }
  4030. if(!dojo._hasResource["dojo._base.Color"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  4031. dojo._hasResource["dojo._base.Color"] = true;
  4032. dojo.provide("dojo._base.Color");
  4033. (function(){
  4034. var d = dojo;
  4035. dojo.Color = function(/*Array|String|Object*/ color){
  4036. // summary:
  4037. // Takes a named string, hex string, array of rgb or rgba values,
  4038. // an object with r, g, b, and a properties, or another `dojo.Color` object
  4039. // and creates a new Color instance to work from.
  4040. //
  4041. // example:
  4042. // Work with a Color instance:
  4043. // | var c = new dojo.Color();
  4044. // | c.setColor([0,0,0]); // black
  4045. // | var hex = c.toHex(); // #000000
  4046. //
  4047. // example:
  4048. // Work with a node's color:
  4049. // | var color = dojo.style("someNode", "backgroundColor");
  4050. // | var n = new dojo.Color(color);
  4051. // | // adjust the color some
  4052. // | n.r *= .5;
  4053. // | console.log(n.toString()); // rgb(128, 255, 255);
  4054. if(color){ this.setColor(color); }
  4055. };
  4056. // FIXME:
  4057. // there's got to be a more space-efficient way to encode or discover
  4058. // these!! Use hex?
  4059. dojo.Color.named = {
  4060. black: [0,0,0],
  4061. silver: [192,192,192],
  4062. gray: [128,128,128],
  4063. white: [255,255,255],
  4064. maroon: [128,0,0],
  4065. red: [255,0,0],
  4066. purple: [128,0,128],
  4067. fuchsia: [255,0,255],
  4068. green: [0,128,0],
  4069. lime: [0,255,0],
  4070. olive: [128,128,0],
  4071. yellow: [255,255,0],
  4072. navy: [0,0,128],
  4073. blue: [0,0,255],
  4074. teal: [0,128,128],
  4075. aqua: [0,255,255],
  4076. transparent: d.config.transparentColor || [255,255,255]
  4077. };
  4078. dojo.extend(dojo.Color, {
  4079. r: 255, g: 255, b: 255, a: 1,
  4080. _set: function(r, g, b, a){
  4081. var t = this; t.r = r; t.g = g; t.b = b; t.a = a;
  4082. },
  4083. setColor: function(/*Array|String|Object*/ color){
  4084. // summary:
  4085. // Takes a named string, hex string, array of rgb or rgba values,
  4086. // an object with r, g, b, and a properties, or another `dojo.Color` object
  4087. // and sets this color instance to that value.
  4088. //
  4089. // example:
  4090. // | var c = new dojo.Color(); // no color
  4091. // | c.setColor("#ededed"); // greyish
  4092. if(d.isString(color)){
  4093. d.colorFromString(color, this);
  4094. }else if(d.isArray(color)){
  4095. d.colorFromArray(color, this);
  4096. }else{
  4097. this._set(color.r, color.g, color.b, color.a);
  4098. if(!(color instanceof d.Color)){ this.sanitize(); }
  4099. }
  4100. return this; // dojo.Color
  4101. },
  4102. sanitize: function(){
  4103. // summary:
  4104. // Ensures the object has correct attributes
  4105. // description:
  4106. // the default implementation does nothing, include dojo.colors to
  4107. // augment it with real checks
  4108. return this; // dojo.Color
  4109. },
  4110. toRgb: function(){
  4111. // summary:
  4112. // Returns 3 component array of rgb values
  4113. // example:
  4114. // | var c = new dojo.Color("#000000");
  4115. // | console.log(c.toRgb()); // [0,0,0]
  4116. var t = this;
  4117. return [t.r, t.g, t.b]; // Array
  4118. },
  4119. toRgba: function(){
  4120. // summary:
  4121. // Returns a 4 component array of rgba values from the color
  4122. // represented by this object.
  4123. var t = this;
  4124. return [t.r, t.g, t.b, t.a]; // Array
  4125. },
  4126. toHex: function(){
  4127. // summary:
  4128. // Returns a CSS color string in hexadecimal representation
  4129. // example:
  4130. // | console.log(new dojo.Color([0,0,0]).toHex()); // #000000
  4131. var arr = d.map(["r", "g", "b"], function(x){
  4132. var s = this[x].toString(16);
  4133. return s.length < 2 ? "0" + s : s;
  4134. }, this);
  4135. return "#" + arr.join(""); // String
  4136. },
  4137. toCss: function(/*Boolean?*/ includeAlpha){
  4138. // summary:
  4139. // Returns a css color string in rgb(a) representation
  4140. // example:
  4141. // | var c = new dojo.Color("#FFF").toCss();
  4142. // | console.log(c); // rgb('255','255','255')
  4143. var t = this, rgb = t.r + ", " + t.g + ", " + t.b;
  4144. return (includeAlpha ? "rgba(" + rgb + ", " + t.a : "rgb(" + rgb) + ")"; // String
  4145. },
  4146. toString: function(){
  4147. // summary:
  4148. // Returns a visual representation of the color
  4149. return this.toCss(true); // String
  4150. }
  4151. });
  4152. dojo.blendColors = function(
  4153. /*dojo.Color*/ start,
  4154. /*dojo.Color*/ end,
  4155. /*Number*/ weight,
  4156. /*dojo.Color?*/ obj
  4157. ){
  4158. // summary:
  4159. // Blend colors end and start with weight from 0 to 1, 0.5 being a 50/50 blend,
  4160. // can reuse a previously allocated dojo.Color object for the result
  4161. var t = obj || new d.Color();
  4162. d.forEach(["r", "g", "b", "a"], function(x){
  4163. t[x] = start[x] + (end[x] - start[x]) * weight;
  4164. if(x != "a"){ t[x] = Math.round(t[x]); }
  4165. });
  4166. return t.sanitize(); // dojo.Color
  4167. };
  4168. dojo.colorFromRgb = function(/*String*/ color, /*dojo.Color?*/ obj){
  4169. // summary:
  4170. // Returns a `dojo.Color` instance from a string of the form
  4171. // "rgb(...)" or "rgba(...)". Optionally accepts a `dojo.Color`
  4172. // object to update with the parsed value and return instead of
  4173. // creating a new object.
  4174. // returns:
  4175. // A dojo.Color object. If obj is passed, it will be the return value.
  4176. var m = color.toLowerCase().match(/^rgba?\(([\s\.,0-9]+)\)/);
  4177. return m && dojo.colorFromArray(m[1].split(/\s*,\s*/), obj); // dojo.Color
  4178. };
  4179. dojo.colorFromHex = function(/*String*/ color, /*dojo.Color?*/ obj){
  4180. // summary:
  4181. // Converts a hex string with a '#' prefix to a color object.
  4182. // Supports 12-bit #rgb shorthand. Optionally accepts a
  4183. // `dojo.Color` object to update with the parsed value.
  4184. //
  4185. // returns:
  4186. // A dojo.Color object. If obj is passed, it will be the return value.
  4187. //
  4188. // example:
  4189. // | var thing = dojo.colorFromHex("#ededed"); // grey, longhand
  4190. //
  4191. // example:
  4192. // | var thing = dojo.colorFromHex("#000"); // black, shorthand
  4193. var t = obj || new d.Color(),
  4194. bits = (color.length == 4) ? 4 : 8,
  4195. mask = (1 << bits) - 1;
  4196. color = Number("0x" + color.substr(1));
  4197. if(isNaN(color)){
  4198. return null; // dojo.Color
  4199. }
  4200. d.forEach(["b", "g", "r"], function(x){
  4201. var c = color & mask;
  4202. color >>= bits;
  4203. t[x] = bits == 4 ? 17 * c : c;
  4204. });
  4205. t.a = 1;
  4206. return t; // dojo.Color
  4207. };
  4208. dojo.colorFromArray = function(/*Array*/ a, /*dojo.Color?*/ obj){
  4209. // summary:
  4210. // Builds a `dojo.Color` from a 3 or 4 element array, mapping each
  4211. // element in sequence to the rgb(a) values of the color.
  4212. // example:
  4213. // | var myColor = dojo.colorFromArray([237,237,237,0.5]); // grey, 50% alpha
  4214. // returns:
  4215. // A dojo.Color object. If obj is passed, it will be the return value.
  4216. var t = obj || new d.Color();
  4217. t._set(Number(a[0]), Number(a[1]), Number(a[2]), Number(a[3]));
  4218. if(isNaN(t.a)){ t.a = 1; }
  4219. return t.sanitize(); // dojo.Color
  4220. };
  4221. dojo.colorFromString = function(/*String*/ str, /*dojo.Color?*/ obj){
  4222. // summary:
  4223. // Parses `str` for a color value. Accepts hex, rgb, and rgba
  4224. // style color values.
  4225. // description:
  4226. // Acceptable input values for str may include arrays of any form
  4227. // accepted by dojo.colorFromArray, hex strings such as "#aaaaaa", or
  4228. // rgb or rgba strings such as "rgb(133, 200, 16)" or "rgba(10, 10,
  4229. // 10, 50)"
  4230. // returns:
  4231. // A dojo.Color object. If obj is passed, it will be the return value.
  4232. var a = d.Color.named[str];
  4233. return a && d.colorFromArray(a, obj) || d.colorFromRgb(str, obj) || d.colorFromHex(str, obj);
  4234. };
  4235. })();
  4236. }
  4237. if(!dojo._hasResource["dojo._base.window"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  4238. dojo._hasResource["dojo._base.window"] = true;
  4239. dojo.provide("dojo._base.window");
  4240. /*=====
  4241. dojo.doc = {
  4242. // summary:
  4243. // Alias for the current document. 'dojo.doc' can be modified
  4244. // for temporary context shifting. Also see dojo.withDoc().
  4245. // description:
  4246. // Refer to dojo.doc rather
  4247. // than referring to 'window.document' to ensure your code runs
  4248. // correctly in managed contexts.
  4249. // example:
  4250. // | n.appendChild(dojo.doc.createElement('div'));
  4251. }
  4252. =====*/
  4253. dojo.doc = window["document"] || null;
  4254. dojo.body = function(){
  4255. // summary:
  4256. // Return the body element of the document
  4257. // return the body object associated with dojo.doc
  4258. // example:
  4259. // | dojo.body().appendChild(dojo.doc.createElement('div'));
  4260. // Note: document.body is not defined for a strict xhtml document
  4261. // Would like to memoize this, but dojo.doc can change vi dojo.withDoc().
  4262. return dojo.doc.body || dojo.doc.getElementsByTagName("body")[0]; // Node
  4263. };
  4264. dojo.setContext = function(/*Object*/globalObject, /*DocumentElement*/globalDocument){
  4265. // summary:
  4266. // changes the behavior of many core Dojo functions that deal with
  4267. // namespace and DOM lookup, changing them to work in a new global
  4268. // context (e.g., an iframe). The varibles dojo.global and dojo.doc
  4269. // are modified as a result of calling this function and the result of
  4270. // `dojo.body()` likewise differs.
  4271. dojo.global = globalObject;
  4272. dojo.doc = globalDocument;
  4273. };
  4274. dojo.withGlobal = function( /*Object*/globalObject,
  4275. /*Function*/callback,
  4276. /*Object?*/thisObject,
  4277. /*Array?*/cbArguments){
  4278. // summary:
  4279. // Invoke callback with globalObject as dojo.global and
  4280. // globalObject.document as dojo.doc.
  4281. // description:
  4282. // Invoke callback with globalObject as dojo.global and
  4283. // globalObject.document as dojo.doc. If provided, globalObject
  4284. // will be executed in the context of object thisObject
  4285. // When callback() returns or throws an error, the dojo.global
  4286. // and dojo.doc will be restored to its previous state.
  4287. var oldGlob = dojo.global;
  4288. try{
  4289. dojo.global = globalObject;
  4290. return dojo.withDoc.call(null, globalObject.document, callback, thisObject, cbArguments);
  4291. }finally{
  4292. dojo.global = oldGlob;
  4293. }
  4294. };
  4295. dojo.withDoc = function( /*DocumentElement*/documentObject,
  4296. /*Function*/callback,
  4297. /*Object?*/thisObject,
  4298. /*Array?*/cbArguments){
  4299. // summary:
  4300. // Invoke callback with documentObject as dojo.doc.
  4301. // description:
  4302. // Invoke callback with documentObject as dojo.doc. If provided,
  4303. // callback will be executed in the context of object thisObject
  4304. // When callback() returns or throws an error, the dojo.doc will
  4305. // be restored to its previous state.
  4306. var oldDoc = dojo.doc,
  4307. oldLtr = dojo._bodyLtr,
  4308. oldQ = dojo.isQuirks;
  4309. try{
  4310. dojo.doc = documentObject;
  4311. delete dojo._bodyLtr; // uncache
  4312. dojo.isQuirks = dojo.doc.compatMode == "BackCompat"; // no need to check for QuirksMode which was Opera 7 only
  4313. if(thisObject && typeof callback == "string"){
  4314. callback = thisObject[callback];
  4315. }
  4316. return callback.apply(thisObject, cbArguments || []);
  4317. }finally{
  4318. dojo.doc = oldDoc;
  4319. delete dojo._bodyLtr; // in case it was undefined originally, and set to true/false by the alternate document
  4320. if(oldLtr !== undefined){ dojo._bodyLtr = oldLtr; }
  4321. dojo.isQuirks = oldQ;
  4322. }
  4323. };
  4324. }
  4325. if(!dojo._hasResource["dojo._base.event"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  4326. dojo._hasResource["dojo._base.event"] = true;
  4327. dojo.provide("dojo._base.event");
  4328. // this file courtesy of the TurboAjax Group, licensed under a Dojo CLA
  4329. (function(){
  4330. // DOM event listener machinery
  4331. var del = (dojo._event_listener = {
  4332. add: function(/*DOMNode*/ node, /*String*/ name, /*Function*/ fp){
  4333. if(!node){return;}
  4334. name = del._normalizeEventName(name);
  4335. fp = del._fixCallback(name, fp);
  4336. if(
  4337. !dojo.isIE &&
  4338. (name == "mouseenter" || name == "mouseleave")
  4339. ){
  4340. var ofp = fp;
  4341. name = (name == "mouseenter") ? "mouseover" : "mouseout";
  4342. fp = function(e){
  4343. if(!dojo.isDescendant(e.relatedTarget, node)){
  4344. // e.type = oname; // FIXME: doesn't take? SJM: event.type is generally immutable.
  4345. return ofp.call(this, e);
  4346. }
  4347. }
  4348. }
  4349. node.addEventListener(name, fp, false);
  4350. return fp; /*Handle*/
  4351. },
  4352. remove: function(/*DOMNode*/ node, /*String*/ event, /*Handle*/ handle){
  4353. // summary:
  4354. // clobbers the listener from the node
  4355. // node:
  4356. // DOM node to attach the event to
  4357. // event:
  4358. // the name of the handler to remove the function from
  4359. // handle:
  4360. // the handle returned from add
  4361. if(node){
  4362. event = del._normalizeEventName(event);
  4363. if(!dojo.isIE && (event == "mouseenter" || event == "mouseleave")){
  4364. event = (event == "mouseenter") ? "mouseover" : "mouseout";
  4365. }
  4366. node.removeEventListener(event, handle, false);
  4367. }
  4368. },
  4369. _normalizeEventName: function(/*String*/ name){
  4370. // Generally, name should be lower case, unless it is special
  4371. // somehow (e.g. a Mozilla DOM event).
  4372. // Remove 'on'.
  4373. return name.slice(0,2) =="on" ? name.slice(2) : name;
  4374. },
  4375. _fixCallback: function(/*String*/ name, fp){
  4376. // By default, we only invoke _fixEvent for 'keypress'
  4377. // If code is added to _fixEvent for other events, we have
  4378. // to revisit this optimization.
  4379. // This also applies to _fixEvent overrides for Safari and Opera
  4380. // below.
  4381. return name != "keypress" ? fp : function(e){ return fp.call(this, del._fixEvent(e, this)); };
  4382. },
  4383. _fixEvent: function(evt, sender){
  4384. // _fixCallback only attaches us to keypress.
  4385. // Switch on evt.type anyway because we might
  4386. // be called directly from dojo.fixEvent.
  4387. switch(evt.type){
  4388. case "keypress":
  4389. del._setKeyChar(evt);
  4390. break;
  4391. }
  4392. return evt;
  4393. },
  4394. _setKeyChar: function(evt){
  4395. evt.keyChar = evt.charCode >= 32 ? String.fromCharCode(evt.charCode) : '';
  4396. evt.charOrCode = evt.keyChar || evt.keyCode;
  4397. },
  4398. // For IE and Safari: some ctrl-key combinations (mostly w/punctuation) do not emit a char code in IE
  4399. // we map those virtual key codes to ascii here
  4400. // not valid for all (non-US) keyboards, so maybe we shouldn't bother
  4401. _punctMap: {
  4402. 106:42,
  4403. 111:47,
  4404. 186:59,
  4405. 187:43,
  4406. 188:44,
  4407. 189:45,
  4408. 190:46,
  4409. 191:47,
  4410. 192:96,
  4411. 219:91,
  4412. 220:92,
  4413. 221:93,
  4414. 222:39
  4415. }
  4416. });
  4417. // DOM events
  4418. dojo.fixEvent = function(/*Event*/ evt, /*DOMNode*/ sender){
  4419. // summary:
  4420. // normalizes properties on the event object including event
  4421. // bubbling methods, keystroke normalization, and x/y positions
  4422. // evt: Event
  4423. // native event object
  4424. // sender: DOMNode
  4425. // node to treat as "currentTarget"
  4426. return del._fixEvent(evt, sender);
  4427. };
  4428. dojo.stopEvent = function(/*Event*/ evt){
  4429. // summary:
  4430. // prevents propagation and clobbers the default action of the
  4431. // passed event
  4432. // evt: Event
  4433. // The event object. If omitted, window.event is used on IE.
  4434. evt.preventDefault();
  4435. evt.stopPropagation();
  4436. // NOTE: below, this method is overridden for IE
  4437. };
  4438. // the default listener to use on dontFix nodes, overriden for IE
  4439. var node_listener = dojo._listener;
  4440. // Unify connect and event listeners
  4441. dojo._connect = function(obj, event, context, method, dontFix){
  4442. // FIXME: need a more strict test
  4443. var isNode = obj && (obj.nodeType||obj.attachEvent||obj.addEventListener);
  4444. // choose one of three listener options: raw (connect.js), DOM event on a Node, custom event on a Node
  4445. // we need the third option to provide leak prevention on broken browsers (IE)
  4446. var lid = isNode ? (dontFix ? 2 : 1) : 0, l = [dojo._listener, del, node_listener][lid];
  4447. // create a listener
  4448. var h = l.add(obj, event, dojo.hitch(context, method));
  4449. // formerly, the disconnect package contained "l" directly, but if client code
  4450. // leaks the disconnect package (by connecting it to a node), referencing "l"
  4451. // compounds the problem.
  4452. // instead we return a listener id, which requires custom _disconnect below.
  4453. // return disconnect package
  4454. return [ obj, event, h, lid ];
  4455. };
  4456. dojo._disconnect = function(obj, event, handle, listener){
  4457. ([dojo._listener, del, node_listener][listener]).remove(obj, event, handle);
  4458. };
  4459. // Constants
  4460. // Public: client code should test
  4461. // keyCode against these named constants, as the
  4462. // actual codes can vary by browser.
  4463. dojo.keys = {
  4464. // summary:
  4465. // Definitions for common key values
  4466. BACKSPACE: 8,
  4467. TAB: 9,
  4468. CLEAR: 12,
  4469. ENTER: 13,
  4470. SHIFT: 16,
  4471. CTRL: 17,
  4472. ALT: 18,
  4473. META: dojo.isSafari ? 91 : 224, // the apple key on macs
  4474. PAUSE: 19,
  4475. CAPS_LOCK: 20,
  4476. ESCAPE: 27,
  4477. SPACE: 32,
  4478. PAGE_UP: 33,
  4479. PAGE_DOWN: 34,
  4480. END: 35,
  4481. HOME: 36,
  4482. LEFT_ARROW: 37,
  4483. UP_ARROW: 38,
  4484. RIGHT_ARROW: 39,
  4485. DOWN_ARROW: 40,
  4486. INSERT: 45,
  4487. DELETE: 46,
  4488. HELP: 47,
  4489. LEFT_WINDOW: 91,
  4490. RIGHT_WINDOW: 92,
  4491. SELECT: 93,
  4492. NUMPAD_0: 96,
  4493. NUMPAD_1: 97,
  4494. NUMPAD_2: 98,
  4495. NUMPAD_3: 99,
  4496. NUMPAD_4: 100,
  4497. NUMPAD_5: 101,
  4498. NUMPAD_6: 102,
  4499. NUMPAD_7: 103,
  4500. NUMPAD_8: 104,
  4501. NUMPAD_9: 105,
  4502. NUMPAD_MULTIPLY: 106,
  4503. NUMPAD_PLUS: 107,
  4504. NUMPAD_ENTER: 108,
  4505. NUMPAD_MINUS: 109,
  4506. NUMPAD_PERIOD: 110,
  4507. NUMPAD_DIVIDE: 111,
  4508. F1: 112,
  4509. F2: 113,
  4510. F3: 114,
  4511. F4: 115,
  4512. F5: 116,
  4513. F6: 117,
  4514. F7: 118,
  4515. F8: 119,
  4516. F9: 120,
  4517. F10: 121,
  4518. F11: 122,
  4519. F12: 123,
  4520. F13: 124,
  4521. F14: 125,
  4522. F15: 126,
  4523. NUM_LOCK: 144,
  4524. SCROLL_LOCK: 145,
  4525. // virtual key mapping
  4526. copyKey: dojo.isMac && !dojo.isAIR ? (dojo.isSafari ? 91 : 224 ) : 17
  4527. };
  4528. var evtCopyKey = dojo.isMac ? "metaKey" : "ctrlKey";
  4529. dojo.isCopyKey = function(e){
  4530. // summary:
  4531. // Checks an event for the copy key (meta on Mac, and ctrl anywhere else)
  4532. // e: Event
  4533. // Event object to examine
  4534. return e[evtCopyKey]; // Boolean
  4535. };
  4536. // Public: decoding mouse buttons from events
  4537. /*=====
  4538. dojo.mouseButtons = {
  4539. // LEFT: Number
  4540. // Numeric value of the left mouse button for the platform.
  4541. LEFT: 0,
  4542. // MIDDLE: Number
  4543. // Numeric value of the middle mouse button for the platform.
  4544. MIDDLE: 1,
  4545. // RIGHT: Number
  4546. // Numeric value of the right mouse button for the platform.
  4547. RIGHT: 2,
  4548. isButton: function(e, button){
  4549. // summary:
  4550. // Checks an event object for a pressed button
  4551. // e: Event
  4552. // Event object to examine
  4553. // button: Number
  4554. // The button value (example: dojo.mouseButton.LEFT)
  4555. return e.button == button; // Boolean
  4556. },
  4557. isLeft: function(e){
  4558. // summary:
  4559. // Checks an event object for the pressed left button
  4560. // e: Event
  4561. // Event object to examine
  4562. return e.button == 0; // Boolean
  4563. },
  4564. isMiddle: function(e){
  4565. // summary:
  4566. // Checks an event object for the pressed middle button
  4567. // e: Event
  4568. // Event object to examine
  4569. return e.button == 1; // Boolean
  4570. },
  4571. isRight: function(e){
  4572. // summary:
  4573. // Checks an event object for the pressed right button
  4574. // e: Event
  4575. // Event object to examine
  4576. return e.button == 2; // Boolean
  4577. }
  4578. };
  4579. =====*/
  4580. if(dojo.isIE < 9 || (dojo.isIE && dojo.isQuirks)){
  4581. dojo.mouseButtons = {
  4582. LEFT: 1,
  4583. MIDDLE: 4,
  4584. RIGHT: 2,
  4585. // helper functions
  4586. isButton: function(e, button){ return e.button & button; },
  4587. isLeft: function(e){ return e.button & 1; },
  4588. isMiddle: function(e){ return e.button & 4; },
  4589. isRight: function(e){ return e.button & 2; }
  4590. };
  4591. }else{
  4592. dojo.mouseButtons = {
  4593. LEFT: 0,
  4594. MIDDLE: 1,
  4595. RIGHT: 2,
  4596. // helper functions
  4597. isButton: function(e, button){ return e.button == button; },
  4598. isLeft: function(e){ return e.button == 0; },
  4599. isMiddle: function(e){ return e.button == 1; },
  4600. isRight: function(e){ return e.button == 2; }
  4601. };
  4602. }
  4603. // IE event normalization
  4604. if(dojo.isIE){
  4605. var _trySetKeyCode = function(e, code){
  4606. try{
  4607. // squelch errors when keyCode is read-only
  4608. // (e.g. if keyCode is ctrl or shift)
  4609. return (e.keyCode = code);
  4610. }catch(e){
  4611. return 0;
  4612. }
  4613. };
  4614. // by default, use the standard listener
  4615. var iel = dojo._listener;
  4616. var listenersName = (dojo._ieListenersName = "_" + dojo._scopeName + "_listeners");
  4617. // dispatcher tracking property
  4618. if(!dojo.config._allow_leaks){
  4619. // custom listener that handles leak protection for DOM events
  4620. node_listener = iel = dojo._ie_listener = {
  4621. // support handler indirection: event handler functions are
  4622. // referenced here. Event dispatchers hold only indices.
  4623. handlers: [],
  4624. // add a listener to an object
  4625. add: function(/*Object*/ source, /*String*/ method, /*Function*/ listener){
  4626. source = source || dojo.global;
  4627. var f = source[method];
  4628. if(!f||!f[listenersName]){
  4629. var d = dojo._getIeDispatcher();
  4630. // original target function is special
  4631. d.target = f && (ieh.push(f) - 1);
  4632. // dispatcher holds a list of indices into handlers table
  4633. d[listenersName] = [];
  4634. // redirect source to dispatcher
  4635. f = source[method] = d;
  4636. }
  4637. return f[listenersName].push(ieh.push(listener) - 1) ; /*Handle*/
  4638. },
  4639. // remove a listener from an object
  4640. remove: function(/*Object*/ source, /*String*/ method, /*Handle*/ handle){
  4641. var f = (source||dojo.global)[method], l = f && f[listenersName];
  4642. if(f && l && handle--){
  4643. delete ieh[l[handle]];
  4644. delete l[handle];
  4645. }
  4646. }
  4647. };
  4648. // alias used above
  4649. var ieh = iel.handlers;
  4650. }
  4651. dojo.mixin(del, {
  4652. add: function(/*DOMNode*/ node, /*String*/ event, /*Function*/ fp){
  4653. if(!node){return;} // undefined
  4654. event = del._normalizeEventName(event);
  4655. if(event=="onkeypress"){
  4656. // we need to listen to onkeydown to synthesize
  4657. // keypress events that otherwise won't fire
  4658. // on IE
  4659. var kd = node.onkeydown;
  4660. if(!kd || !kd[listenersName] || !kd._stealthKeydownHandle){
  4661. var h = del.add(node, "onkeydown", del._stealthKeyDown);
  4662. kd = node.onkeydown;
  4663. kd._stealthKeydownHandle = h;
  4664. kd._stealthKeydownRefs = 1;
  4665. }else{
  4666. kd._stealthKeydownRefs++;
  4667. }
  4668. }
  4669. return iel.add(node, event, del._fixCallback(fp));
  4670. },
  4671. remove: function(/*DOMNode*/ node, /*String*/ event, /*Handle*/ handle){
  4672. event = del._normalizeEventName(event);
  4673. iel.remove(node, event, handle);
  4674. if(event=="onkeypress"){
  4675. var kd = node.onkeydown;
  4676. if(--kd._stealthKeydownRefs <= 0){
  4677. iel.remove(node, "onkeydown", kd._stealthKeydownHandle);
  4678. delete kd._stealthKeydownHandle;
  4679. }
  4680. }
  4681. },
  4682. _normalizeEventName: function(/*String*/ eventName){
  4683. // Generally, eventName should be lower case, unless it is
  4684. // special somehow (e.g. a Mozilla event)
  4685. // ensure 'on'
  4686. return eventName.slice(0,2) != "on" ? "on" + eventName : eventName;
  4687. },
  4688. _nop: function(){},
  4689. _fixEvent: function(/*Event*/ evt, /*DOMNode*/ sender){
  4690. // summary:
  4691. // normalizes properties on the event object including event
  4692. // bubbling methods, keystroke normalization, and x/y positions
  4693. // evt:
  4694. // native event object
  4695. // sender:
  4696. // node to treat as "currentTarget"
  4697. if(!evt){
  4698. var w = sender && (sender.ownerDocument || sender.document || sender).parentWindow || window;
  4699. evt = w.event;
  4700. }
  4701. if(!evt){return(evt);}
  4702. evt.target = evt.srcElement;
  4703. evt.currentTarget = (sender || evt.srcElement);
  4704. evt.layerX = evt.offsetX;
  4705. evt.layerY = evt.offsetY;
  4706. // FIXME: scroll position query is duped from dojo.html to
  4707. // avoid dependency on that entire module. Now that HTML is in
  4708. // Base, we should convert back to something similar there.
  4709. var se = evt.srcElement, doc = (se && se.ownerDocument) || document;
  4710. // DO NOT replace the following to use dojo.body(), in IE, document.documentElement should be used
  4711. // here rather than document.body
  4712. var docBody = ((dojo.isIE < 6) || (doc["compatMode"] == "BackCompat")) ? doc.body : doc.documentElement;
  4713. var offset = dojo._getIeDocumentElementOffset();
  4714. evt.pageX = evt.clientX + dojo._fixIeBiDiScrollLeft(docBody.scrollLeft || 0) - offset.x;
  4715. evt.pageY = evt.clientY + (docBody.scrollTop || 0) - offset.y;
  4716. if(evt.type == "mouseover"){
  4717. evt.relatedTarget = evt.fromElement;
  4718. }
  4719. if(evt.type == "mouseout"){
  4720. evt.relatedTarget = evt.toElement;
  4721. }
  4722. if (dojo.isIE < 9 || dojo.isQuirks) {
  4723. evt.stopPropagation = del._stopPropagation;
  4724. evt.preventDefault = del._preventDefault;
  4725. }
  4726. return del._fixKeys(evt);
  4727. },
  4728. _fixKeys: function(evt){
  4729. switch(evt.type){
  4730. case "keypress":
  4731. var c = ("charCode" in evt ? evt.charCode : evt.keyCode);
  4732. if (c==10){
  4733. // CTRL-ENTER is CTRL-ASCII(10) on IE, but CTRL-ENTER on Mozilla
  4734. c=0;
  4735. evt.keyCode = 13;
  4736. }else if(c==13||c==27){
  4737. c=0; // Mozilla considers ENTER and ESC non-printable
  4738. }else if(c==3){
  4739. c=99; // Mozilla maps CTRL-BREAK to CTRL-c
  4740. }
  4741. // Mozilla sets keyCode to 0 when there is a charCode
  4742. // but that stops the event on IE.
  4743. evt.charCode = c;
  4744. del._setKeyChar(evt);
  4745. break;
  4746. }
  4747. return evt;
  4748. },
  4749. _stealthKeyDown: function(evt){
  4750. // IE doesn't fire keypress for most non-printable characters.
  4751. // other browsers do, we simulate it here.
  4752. var kp = evt.currentTarget.onkeypress;
  4753. // only works if kp exists and is a dispatcher
  4754. if(!kp || !kp[listenersName]){ return; }
  4755. // munge key/charCode
  4756. var k=evt.keyCode;
  4757. // These are Windows Virtual Key Codes
  4758. // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/WinUI/WindowsUserInterface/UserInput/VirtualKeyCodes.asp
  4759. var unprintable = (k!=13 || (dojo.isIE >= 9 && !dojo.isQuirks)) && k!=32 && k!=27 && (k<48||k>90) && (k<96||k>111) && (k<186||k>192) && (k<219||k>222);
  4760. // synthesize keypress for most unprintables and CTRL-keys
  4761. if(unprintable||evt.ctrlKey){
  4762. var c = unprintable ? 0 : k;
  4763. if(evt.ctrlKey){
  4764. if(k==3 || k==13){
  4765. return; // IE will post CTRL-BREAK, CTRL-ENTER as keypress natively
  4766. }else if(c>95 && c<106){
  4767. c -= 48; // map CTRL-[numpad 0-9] to ASCII
  4768. }else if((!evt.shiftKey)&&(c>=65&&c<=90)){
  4769. c += 32; // map CTRL-[A-Z] to lowercase
  4770. }else{
  4771. c = del._punctMap[c] || c; // map other problematic CTRL combinations to ASCII
  4772. }
  4773. }
  4774. // simulate a keypress event
  4775. var faux = del._synthesizeEvent(evt, {type: 'keypress', faux: true, charCode: c});
  4776. kp.call(evt.currentTarget, faux);
  4777. if(dojo.isIE < 9 || (dojo.isIE && dojo.isQuirks)){
  4778. evt.cancelBubble = faux.cancelBubble;
  4779. }
  4780. evt.returnValue = faux.returnValue;
  4781. _trySetKeyCode(evt, faux.keyCode);
  4782. }
  4783. },
  4784. // Called in Event scope
  4785. _stopPropagation: function(){
  4786. this.cancelBubble = true;
  4787. },
  4788. _preventDefault: function(){
  4789. // Setting keyCode to 0 is the only way to prevent certain keypresses (namely
  4790. // ctrl-combinations that correspond to menu accelerator keys).
  4791. // Otoh, it prevents upstream listeners from getting this information
  4792. // Try to split the difference here by clobbering keyCode only for ctrl
  4793. // combinations. If you still need to access the key upstream, bubbledKeyCode is
  4794. // provided as a workaround.
  4795. this.bubbledKeyCode = this.keyCode;
  4796. if(this.ctrlKey){_trySetKeyCode(this, 0);}
  4797. this.returnValue = false;
  4798. }
  4799. });
  4800. // override stopEvent for IE
  4801. dojo.stopEvent = (dojo.isIE < 9 || dojo.isQuirks) ? function(evt){
  4802. evt = evt || window.event;
  4803. del._stopPropagation.call(evt);
  4804. del._preventDefault.call(evt);
  4805. } : dojo.stopEvent;
  4806. }
  4807. del._synthesizeEvent = function(evt, props){
  4808. var faux = dojo.mixin({}, evt, props);
  4809. del._setKeyChar(faux);
  4810. // FIXME: would prefer to use dojo.hitch: dojo.hitch(evt, evt.preventDefault);
  4811. // but it throws an error when preventDefault is invoked on Safari
  4812. // does Event.preventDefault not support "apply" on Safari?
  4813. faux.preventDefault = function(){ evt.preventDefault(); };
  4814. faux.stopPropagation = function(){ evt.stopPropagation(); };
  4815. return faux;
  4816. };
  4817. // Opera event normalization
  4818. if(dojo.isOpera){
  4819. dojo.mixin(del, {
  4820. _fixEvent: function(evt, sender){
  4821. switch(evt.type){
  4822. case "keypress":
  4823. var c = evt.which;
  4824. if(c==3){
  4825. c=99; // Mozilla maps CTRL-BREAK to CTRL-c
  4826. }
  4827. // can't trap some keys at all, like INSERT and DELETE
  4828. // there is no differentiating info between DELETE and ".", or INSERT and "-"
  4829. c = c<41 && !evt.shiftKey ? 0 : c;
  4830. if(evt.ctrlKey && !evt.shiftKey && c>=65 && c<=90){
  4831. // lowercase CTRL-[A-Z] keys
  4832. c += 32;
  4833. }
  4834. return del._synthesizeEvent(evt, { charCode: c });
  4835. }
  4836. return evt;
  4837. }
  4838. });
  4839. }
  4840. // Webkit event normalization
  4841. if(dojo.isWebKit){
  4842. del._add = del.add;
  4843. del._remove = del.remove;
  4844. dojo.mixin(del, {
  4845. add: function(/*DOMNode*/ node, /*String*/ event, /*Function*/ fp){
  4846. if(!node){return;} // undefined
  4847. var handle = del._add(node, event, fp);
  4848. if(del._normalizeEventName(event) == "keypress"){
  4849. // we need to listen to onkeydown to synthesize
  4850. // keypress events that otherwise won't fire
  4851. // in Safari 3.1+: https://lists.webkit.org/pipermail/webkit-dev/2007-December/002992.html
  4852. handle._stealthKeyDownHandle = del._add(node, "keydown", function(evt){
  4853. //A variation on the IE _stealthKeydown function
  4854. //Synthesize an onkeypress event, but only for unprintable characters.
  4855. var k=evt.keyCode;
  4856. // These are Windows Virtual Key Codes
  4857. // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/WinUI/WindowsUserInterface/UserInput/VirtualKeyCodes.asp
  4858. var unprintable = k!=13 && k!=32 && (k<48 || k>90) && (k<96 || k>111) && (k<186 || k>192) && (k<219 || k>222);
  4859. // synthesize keypress for most unprintables and CTRL-keys
  4860. if(unprintable || evt.ctrlKey){
  4861. var c = unprintable ? 0 : k;
  4862. if(evt.ctrlKey){
  4863. if(k==3 || k==13){
  4864. return; // IE will post CTRL-BREAK, CTRL-ENTER as keypress natively
  4865. }else if(c>95 && c<106){
  4866. c -= 48; // map CTRL-[numpad 0-9] to ASCII
  4867. }else if(!evt.shiftKey && c>=65 && c<=90){
  4868. c += 32; // map CTRL-[A-Z] to lowercase
  4869. }else{
  4870. c = del._punctMap[c] || c; // map other problematic CTRL combinations to ASCII
  4871. }
  4872. }
  4873. // simulate a keypress event
  4874. var faux = del._synthesizeEvent(evt, {type: 'keypress', faux: true, charCode: c});
  4875. fp.call(evt.currentTarget, faux);
  4876. }
  4877. });
  4878. }
  4879. return handle; /*Handle*/
  4880. },
  4881. remove: function(/*DOMNode*/ node, /*String*/ event, /*Handle*/ handle){
  4882. if(node){
  4883. if(handle._stealthKeyDownHandle){
  4884. del._remove(node, "keydown", handle._stealthKeyDownHandle);
  4885. }
  4886. del._remove(node, event, handle);
  4887. }
  4888. },
  4889. _fixEvent: function(evt, sender){
  4890. switch(evt.type){
  4891. case "keypress":
  4892. if(evt.faux){ return evt; }
  4893. var c = evt.charCode;
  4894. c = c>=32 ? c : 0;
  4895. return del._synthesizeEvent(evt, {charCode: c, faux: true});
  4896. }
  4897. return evt;
  4898. }
  4899. });
  4900. }
  4901. })();
  4902. if(dojo.isIE){
  4903. // keep this out of the closure
  4904. // closing over 'iel' or 'ieh' b0rks leak prevention
  4905. // ls[i] is an index into the master handler array
  4906. dojo._ieDispatcher = function(args, sender){
  4907. var ap = Array.prototype,
  4908. h = dojo._ie_listener.handlers,
  4909. c = args.callee,
  4910. ls = c[dojo._ieListenersName],
  4911. t = h[c.target];
  4912. // return value comes from original target function
  4913. var r = t && t.apply(sender, args);
  4914. // make local copy of listener array so it's immutable during processing
  4915. var lls = [].concat(ls);
  4916. // invoke listeners after target function
  4917. for(var i in lls){
  4918. var f = h[lls[i]];
  4919. if(!(i in ap) && f){
  4920. f.apply(sender, args);
  4921. }
  4922. }
  4923. return r;
  4924. };
  4925. dojo._getIeDispatcher = function(){
  4926. // ensure the returned function closes over nothing ("new Function" apparently doesn't close)
  4927. return new Function(dojo._scopeName + "._ieDispatcher(arguments, this)"); // function
  4928. };
  4929. // keep this out of the closure to reduce RAM allocation
  4930. dojo._event_listener._fixCallback = function(fp){
  4931. var f = dojo._event_listener._fixEvent;
  4932. return function(e){ return fp.call(this, f(e, this)); };
  4933. };
  4934. }
  4935. }
  4936. if(!dojo._hasResource["dojo._base.html"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  4937. dojo._hasResource["dojo._base.html"] = true;
  4938. dojo.provide("dojo._base.html");
  4939. // FIXME: need to add unit tests for all the semi-public methods
  4940. try{
  4941. document.execCommand("BackgroundImageCache", false, true);
  4942. }catch(e){
  4943. // sane browsers don't have cache "issues"
  4944. }
  4945. // =============================
  4946. // DOM Functions
  4947. // =============================
  4948. /*=====
  4949. dojo.byId = function(id, doc){
  4950. // summary:
  4951. // Returns DOM node with matching `id` attribute or `null`
  4952. // if not found. If `id` is a DomNode, this function is a no-op.
  4953. //
  4954. // id: String|DOMNode
  4955. // A string to match an HTML id attribute or a reference to a DOM Node
  4956. //
  4957. // doc: Document?
  4958. // Document to work in. Defaults to the current value of
  4959. // dojo.doc. Can be used to retrieve
  4960. // node references from other documents.
  4961. //
  4962. // example:
  4963. // Look up a node by ID:
  4964. // | var n = dojo.byId("foo");
  4965. //
  4966. // example:
  4967. // Check if a node exists, and use it.
  4968. // | var n = dojo.byId("bar");
  4969. // | if(n){ doStuff() ... }
  4970. //
  4971. // example:
  4972. // Allow string or DomNode references to be passed to a custom function:
  4973. // | var foo = function(nodeOrId){
  4974. // | nodeOrId = dojo.byId(nodeOrId);
  4975. // | // ... more stuff
  4976. // | }
  4977. =====*/
  4978. if(dojo.isIE){
  4979. dojo.byId = function(id, doc){
  4980. if(typeof id != "string"){
  4981. return id;
  4982. }
  4983. var _d = doc || dojo.doc, te = _d.getElementById(id);
  4984. // attributes.id.value is better than just id in case the
  4985. // user has a name=id inside a form
  4986. if(te && (te.attributes.id.value == id || te.id == id)){
  4987. return te;
  4988. }else{
  4989. var eles = _d.all[id];
  4990. if(!eles || eles.nodeName){
  4991. eles = [eles];
  4992. }
  4993. // if more than 1, choose first with the correct id
  4994. var i=0;
  4995. while((te=eles[i++])){
  4996. if((te.attributes && te.attributes.id && te.attributes.id.value == id)
  4997. || te.id == id){
  4998. return te;
  4999. }
  5000. }
  5001. }
  5002. };
  5003. }else{
  5004. dojo.byId = function(id, doc){
  5005. // inline'd type check.
  5006. // be sure to return null per documentation, to match IE branch.
  5007. return ((typeof id == "string") ? (doc || dojo.doc).getElementById(id) : id) || null; // DomNode
  5008. };
  5009. }
  5010. /*=====
  5011. };
  5012. =====*/
  5013. (function(){
  5014. var d = dojo;
  5015. var byId = d.byId;
  5016. /*=====
  5017. dojo._destroyElement = function(node){
  5018. // summary:
  5019. // Existing alias for `dojo.destroy`. Deprecated, will be removed
  5020. // in 2.0
  5021. }
  5022. =====*/
  5023. function _destroy(/*DomNode*/ node, /*DomNode*/ parent){
  5024. if(node.firstChild){
  5025. _empty(node);
  5026. }
  5027. if(parent){
  5028. // removeNode(false) doesn't leak in IE 6+, but removeChild() and removeNode(true) are known to leak under IE 8- while 9+ is TBD
  5029. d.isIE && parent.canHaveChildren && 'removeNode' in node ? node.removeNode(false) :
  5030. parent.removeChild(node);
  5031. }
  5032. }
  5033. dojo._destroyElement = dojo.destroy = function(/*String|DomNode*/node){
  5034. // summary:
  5035. // Removes a node from its parent, clobbering it and all of its
  5036. // children.
  5037. //
  5038. // description:
  5039. // Removes a node from its parent, clobbering it and all of its
  5040. // children. Function only works with DomNodes, and returns nothing.
  5041. //
  5042. // node:
  5043. // A String ID or DomNode reference of the element to be destroyed
  5044. //
  5045. // example:
  5046. // Destroy a node byId:
  5047. // | dojo.destroy("someId");
  5048. //
  5049. // example:
  5050. // Destroy all nodes in a list by reference:
  5051. // | dojo.query(".someNode").forEach(dojo.destroy);
  5052. node = byId(node);
  5053. if(!node){ return; }
  5054. _destroy(node, node.parentNode);
  5055. };
  5056. dojo.isDescendant = function(/*DomNode|String*/node, /*DomNode|String*/ancestor){
  5057. // summary:
  5058. // Returns true if node is a descendant of ancestor
  5059. // node: string id or node reference to test
  5060. // ancestor: string id or node reference of potential parent to test against
  5061. //
  5062. // example:
  5063. // Test is node id="bar" is a descendant of node id="foo"
  5064. // | if(dojo.isDescendant("bar", "foo")){ ... }
  5065. try{
  5066. node = byId(node);
  5067. ancestor = byId(ancestor);
  5068. while(node){
  5069. if(node == ancestor){
  5070. return true; // Boolean
  5071. }
  5072. node = node.parentNode;
  5073. }
  5074. }catch(e){ /* squelch, return false */ }
  5075. return false; // Boolean
  5076. };
  5077. dojo.setSelectable = function(/*DomNode|String*/node, /*Boolean*/selectable){
  5078. // summary:
  5079. // Enable or disable selection on a node
  5080. // node:
  5081. // id or reference to node
  5082. // selectable:
  5083. // state to put the node in. false indicates unselectable, true
  5084. // allows selection.
  5085. // example:
  5086. // Make the node id="bar" unselectable
  5087. // | dojo.setSelectable("bar");
  5088. // example:
  5089. // Make the node id="bar" selectable
  5090. // | dojo.setSelectable("bar", true);
  5091. node = byId(node);
  5092. if(d.isMozilla){
  5093. node.style.MozUserSelect = selectable ? "" : "none";
  5094. }else if(d.isKhtml || d.isWebKit){
  5095. node.style.KhtmlUserSelect = selectable ? "auto" : "none";
  5096. }else if(d.isIE){
  5097. var v = (node.unselectable = selectable ? "" : "on");
  5098. d.query("*", node).forEach("item.unselectable = '"+v+"'");
  5099. }
  5100. //FIXME: else? Opera?
  5101. };
  5102. var _insertBefore = function(/*DomNode*/node, /*DomNode*/ref){
  5103. var parent = ref.parentNode;
  5104. if(parent){
  5105. parent.insertBefore(node, ref);
  5106. }
  5107. };
  5108. var _insertAfter = function(/*DomNode*/node, /*DomNode*/ref){
  5109. // summary:
  5110. // Try to insert node after ref
  5111. var parent = ref.parentNode;
  5112. if(parent){
  5113. if(parent.lastChild == ref){
  5114. parent.appendChild(node);
  5115. }else{
  5116. parent.insertBefore(node, ref.nextSibling);
  5117. }
  5118. }
  5119. };
  5120. dojo.place = function(node, refNode, position){
  5121. // summary:
  5122. // Attempt to insert node into the DOM, choosing from various positioning options.
  5123. // Returns the first argument resolved to a DOM node.
  5124. //
  5125. // node: String|DomNode
  5126. // id or node reference, or HTML fragment starting with "<" to place relative to refNode
  5127. //
  5128. // refNode: String|DomNode
  5129. // id or node reference to use as basis for placement
  5130. //
  5131. // position: String|Number?
  5132. // string noting the position of node relative to refNode or a
  5133. // number indicating the location in the childNodes collection of refNode.
  5134. // Accepted string values are:
  5135. // | * before
  5136. // | * after
  5137. // | * replace
  5138. // | * only
  5139. // | * first
  5140. // | * last
  5141. // "first" and "last" indicate positions as children of refNode, "replace" replaces refNode,
  5142. // "only" replaces all children. position defaults to "last" if not specified
  5143. //
  5144. // returns: DomNode
  5145. // Returned values is the first argument resolved to a DOM node.
  5146. //
  5147. // .place() is also a method of `dojo.NodeList`, allowing `dojo.query` node lookups.
  5148. //
  5149. // example:
  5150. // Place a node by string id as the last child of another node by string id:
  5151. // | dojo.place("someNode", "anotherNode");
  5152. //
  5153. // example:
  5154. // Place a node by string id before another node by string id
  5155. // | dojo.place("someNode", "anotherNode", "before");
  5156. //
  5157. // example:
  5158. // Create a Node, and place it in the body element (last child):
  5159. // | dojo.place("<div></div>", dojo.body());
  5160. //
  5161. // example:
  5162. // Put a new LI as the first child of a list by id:
  5163. // | dojo.place("<li></li>", "someUl", "first");
  5164. refNode = byId(refNode);
  5165. if(typeof node == "string"){ // inline'd type check
  5166. node = /^\s*</.test(node) ? d._toDom(node, refNode.ownerDocument) : byId(node);
  5167. }
  5168. if(typeof position == "number"){ // inline'd type check
  5169. var cn = refNode.childNodes;
  5170. if(!cn.length || cn.length <= position){
  5171. refNode.appendChild(node);
  5172. }else{
  5173. _insertBefore(node, cn[position < 0 ? 0 : position]);
  5174. }
  5175. }else{
  5176. switch(position){
  5177. case "before":
  5178. _insertBefore(node, refNode);
  5179. break;
  5180. case "after":
  5181. _insertAfter(node, refNode);
  5182. break;
  5183. case "replace":
  5184. refNode.parentNode.replaceChild(node, refNode);
  5185. break;
  5186. case "only":
  5187. d.empty(refNode);
  5188. refNode.appendChild(node);
  5189. break;
  5190. case "first":
  5191. if(refNode.firstChild){
  5192. _insertBefore(node, refNode.firstChild);
  5193. break;
  5194. }
  5195. // else fallthrough...
  5196. default: // aka: last
  5197. refNode.appendChild(node);
  5198. }
  5199. }
  5200. return node; // DomNode
  5201. };
  5202. // Box functions will assume this model.
  5203. // On IE/Opera, BORDER_BOX will be set if the primary document is in quirks mode.
  5204. // Can be set to change behavior of box setters.
  5205. // can be either:
  5206. // "border-box"
  5207. // "content-box" (default)
  5208. dojo.boxModel = "content-box";
  5209. // We punt per-node box mode testing completely.
  5210. // If anybody cares, we can provide an additional (optional) unit
  5211. // that overrides existing code to include per-node box sensitivity.
  5212. // Opera documentation claims that Opera 9 uses border-box in BackCompat mode.
  5213. // but experiments (Opera 9.10.8679 on Windows Vista) indicate that it actually continues to use content-box.
  5214. // IIRC, earlier versions of Opera did in fact use border-box.
  5215. // Opera guys, this is really confusing. Opera being broken in quirks mode is not our fault.
  5216. if(d.isIE /*|| dojo.isOpera*/){
  5217. // client code may have to adjust if compatMode varies across iframes
  5218. d.boxModel = document.compatMode == "BackCompat" ? "border-box" : "content-box";
  5219. }
  5220. // =============================
  5221. // Style Functions
  5222. // =============================
  5223. // getComputedStyle drives most of the style code.
  5224. // Wherever possible, reuse the returned object.
  5225. //
  5226. // API functions below that need to access computed styles accept an
  5227. // optional computedStyle parameter.
  5228. // If this parameter is omitted, the functions will call getComputedStyle themselves.
  5229. // This way, calling code can access computedStyle once, and then pass the reference to
  5230. // multiple API functions.
  5231. /*=====
  5232. dojo.getComputedStyle = function(node){
  5233. // summary:
  5234. // Returns a "computed style" object.
  5235. //
  5236. // description:
  5237. // Gets a "computed style" object which can be used to gather
  5238. // information about the current state of the rendered node.
  5239. //
  5240. // Note that this may behave differently on different browsers.
  5241. // Values may have different formats and value encodings across
  5242. // browsers.
  5243. //
  5244. // Note also that this method is expensive. Wherever possible,
  5245. // reuse the returned object.
  5246. //
  5247. // Use the dojo.style() method for more consistent (pixelized)
  5248. // return values.
  5249. //
  5250. // node: DOMNode
  5251. // A reference to a DOM node. Does NOT support taking an
  5252. // ID string for speed reasons.
  5253. // example:
  5254. // | dojo.getComputedStyle(dojo.byId('foo')).borderWidth;
  5255. //
  5256. // example:
  5257. // Reusing the returned object, avoiding multiple lookups:
  5258. // | var cs = dojo.getComputedStyle(dojo.byId("someNode"));
  5259. // | var w = cs.width, h = cs.height;
  5260. return; // CSS2Properties
  5261. }
  5262. =====*/
  5263. // Although we normally eschew argument validation at this
  5264. // level, here we test argument 'node' for (duck)type,
  5265. // by testing nodeType, ecause 'document' is the 'parentNode' of 'body'
  5266. // it is frequently sent to this function even
  5267. // though it is not Element.
  5268. var gcs;
  5269. if(d.isWebKit){
  5270. gcs = function(/*DomNode*/node){
  5271. var s;
  5272. if(node.nodeType == 1){
  5273. var dv = node.ownerDocument.defaultView;
  5274. s = dv.getComputedStyle(node, null);
  5275. if(!s && node.style){
  5276. node.style.display = "";
  5277. s = dv.getComputedStyle(node, null);
  5278. }
  5279. }
  5280. return s || {};
  5281. };
  5282. }else if(d.isIE && (d.isIE < 9 || d.isQuirks)){
  5283. gcs = function(node){
  5284. // IE (as of 7) doesn't expose Element like sane browsers
  5285. return node.nodeType == 1 /* ELEMENT_NODE*/ ? node.currentStyle : {};
  5286. };
  5287. }else{
  5288. gcs = function(node){
  5289. return node.nodeType == 1 ?
  5290. node.ownerDocument.defaultView.getComputedStyle(node, null) : {};
  5291. };
  5292. }
  5293. dojo.getComputedStyle = gcs;
  5294. if(!d.isIE){
  5295. d._toPixelValue = function(element, value){
  5296. // style values can be floats, client code may want
  5297. // to round for integer pixels.
  5298. return parseFloat(value) || 0;
  5299. };
  5300. }else{
  5301. d._toPixelValue = function(element, avalue){
  5302. if(!avalue){ return 0; }
  5303. // on IE7, medium is usually 4 pixels
  5304. if(avalue == "medium"){ return 4; }
  5305. // style values can be floats, client code may
  5306. // want to round this value for integer pixels.
  5307. if(avalue.slice && avalue.slice(-2) == 'px'){ return parseFloat(avalue); }
  5308. with(element){
  5309. var sLeft = style.left;
  5310. var rsLeft = runtimeStyle.left;
  5311. runtimeStyle.left = currentStyle.left;
  5312. try{
  5313. // 'avalue' may be incompatible with style.left, which can cause IE to throw
  5314. // this has been observed for border widths using "thin", "medium", "thick" constants
  5315. // those particular constants could be trapped by a lookup
  5316. // but perhaps there are more
  5317. style.left = avalue;
  5318. avalue = style.pixelLeft;
  5319. }catch(e){
  5320. avalue = 0;
  5321. }
  5322. style.left = sLeft;
  5323. runtimeStyle.left = rsLeft;
  5324. }
  5325. return avalue;
  5326. };
  5327. }
  5328. var px = d._toPixelValue;
  5329. // FIXME: there opacity quirks on FF that we haven't ported over. Hrm.
  5330. /*=====
  5331. dojo._getOpacity = function(node){
  5332. // summary:
  5333. // Returns the current opacity of the passed node as a
  5334. // floating-point value between 0 and 1.
  5335. // node: DomNode
  5336. // a reference to a DOM node. Does NOT support taking an
  5337. // ID string for speed reasons.
  5338. // returns: Number between 0 and 1
  5339. return; // Number
  5340. }
  5341. =====*/
  5342. var astr = "DXImageTransform.Microsoft.Alpha";
  5343. var af = function(n, f){
  5344. try{
  5345. return n.filters.item(astr);
  5346. }catch(e){
  5347. return f ? {} : null;
  5348. }
  5349. };
  5350. dojo._getOpacity =
  5351. d.isIE < 9 || (d.isIE < 10 && d.isQuirks) ? function(node){
  5352. try{
  5353. return af(node).Opacity / 100; // Number
  5354. }catch(e){
  5355. return 1; // Number
  5356. }
  5357. } :
  5358. function(node){
  5359. return gcs(node).opacity;
  5360. };
  5361. /*=====
  5362. dojo._setOpacity = function(node, opacity){
  5363. // summary:
  5364. // set the opacity of the passed node portably. Returns the
  5365. // new opacity of the node.
  5366. // node: DOMNode
  5367. // a reference to a DOM node. Does NOT support taking an
  5368. // ID string for performance reasons.
  5369. // opacity: Number
  5370. // A Number between 0 and 1. 0 specifies transparent.
  5371. // returns: Number between 0 and 1
  5372. return; // Number
  5373. }
  5374. =====*/
  5375. dojo._setOpacity =
  5376. d.isIE < 9 || (d.isIE < 10 && d.isQuirks) ? function(/*DomNode*/node, /*Number*/opacity){
  5377. var ov = opacity * 100, opaque = opacity == 1;
  5378. node.style.zoom = opaque ? "" : 1;
  5379. if(!af(node)){
  5380. if(opaque){
  5381. return opacity;
  5382. }
  5383. node.style.filter += " progid:" + astr + "(Opacity=" + ov + ")";
  5384. }else{
  5385. af(node, 1).Opacity = ov;
  5386. }
  5387. // on IE7 Alpha(Filter opacity=100) makes text look fuzzy so disable it altogether (bug #2661),
  5388. //but still update the opacity value so we can get a correct reading if it is read later.
  5389. af(node, 1).Enabled = !opaque;
  5390. if(node.nodeName.toLowerCase() == "tr"){
  5391. d.query("> td", node).forEach(function(i){
  5392. d._setOpacity(i, opacity);
  5393. });
  5394. }
  5395. return opacity;
  5396. } :
  5397. function(node, opacity){
  5398. return node.style.opacity = opacity;
  5399. };
  5400. var _pixelNamesCache = {
  5401. left: true, top: true
  5402. };
  5403. var _pixelRegExp = /margin|padding|width|height|max|min|offset/; // |border
  5404. var _toStyleValue = function(node, type, value){
  5405. type = type.toLowerCase(); // FIXME: should we really be doing string case conversion here? Should we cache it? Need to profile!
  5406. if(d.isIE){
  5407. if(value == "auto"){
  5408. if(type == "height"){ return node.offsetHeight; }
  5409. if(type == "width"){ return node.offsetWidth; }
  5410. }
  5411. if(type == "fontweight"){
  5412. switch(value){
  5413. case 700: return "bold";
  5414. case 400:
  5415. default: return "normal";
  5416. }
  5417. }
  5418. }
  5419. if(!(type in _pixelNamesCache)){
  5420. _pixelNamesCache[type] = _pixelRegExp.test(type);
  5421. }
  5422. return _pixelNamesCache[type] ? px(node, value) : value;
  5423. };
  5424. var _floatStyle = d.isIE ? "styleFloat" : "cssFloat",
  5425. _floatAliases = { "cssFloat": _floatStyle, "styleFloat": _floatStyle, "float": _floatStyle }
  5426. ;
  5427. // public API
  5428. dojo.style = function( /*DomNode|String*/ node,
  5429. /*String?|Object?*/ style,
  5430. /*String?*/ value){
  5431. // summary:
  5432. // Accesses styles on a node. If 2 arguments are
  5433. // passed, acts as a getter. If 3 arguments are passed, acts
  5434. // as a setter.
  5435. // description:
  5436. // Getting the style value uses the computed style for the node, so the value
  5437. // will be a calculated value, not just the immediate node.style value.
  5438. // Also when getting values, use specific style names,
  5439. // like "borderBottomWidth" instead of "border" since compound values like
  5440. // "border" are not necessarily reflected as expected.
  5441. // If you want to get node dimensions, use `dojo.marginBox()`,
  5442. // `dojo.contentBox()` or `dojo.position()`.
  5443. // node:
  5444. // id or reference to node to get/set style for
  5445. // style:
  5446. // the style property to set in DOM-accessor format
  5447. // ("borderWidth", not "border-width") or an object with key/value
  5448. // pairs suitable for setting each property.
  5449. // value:
  5450. // If passed, sets value on the node for style, handling
  5451. // cross-browser concerns. When setting a pixel value,
  5452. // be sure to include "px" in the value. For instance, top: "200px".
  5453. // Otherwise, in some cases, some browsers will not apply the style.
  5454. // example:
  5455. // Passing only an ID or node returns the computed style object of
  5456. // the node:
  5457. // | dojo.style("thinger");
  5458. // example:
  5459. // Passing a node and a style property returns the current
  5460. // normalized, computed value for that property:
  5461. // | dojo.style("thinger", "opacity"); // 1 by default
  5462. //
  5463. // example:
  5464. // Passing a node, a style property, and a value changes the
  5465. // current display of the node and returns the new computed value
  5466. // | dojo.style("thinger", "opacity", 0.5); // == 0.5
  5467. //
  5468. // example:
  5469. // Passing a node, an object-style style property sets each of the values in turn and returns the computed style object of the node:
  5470. // | dojo.style("thinger", {
  5471. // | "opacity": 0.5,
  5472. // | "border": "3px solid black",
  5473. // | "height": "300px"
  5474. // | });
  5475. //
  5476. // example:
  5477. // When the CSS style property is hyphenated, the JavaScript property is camelCased.
  5478. // font-size becomes fontSize, and so on.
  5479. // | dojo.style("thinger",{
  5480. // | fontSize:"14pt",
  5481. // | letterSpacing:"1.2em"
  5482. // | });
  5483. //
  5484. // example:
  5485. // dojo.NodeList implements .style() using the same syntax, omitting the "node" parameter, calling
  5486. // dojo.style() on every element of the list. See: `dojo.query()` and `dojo.NodeList()`
  5487. // | dojo.query(".someClassName").style("visibility","hidden");
  5488. // | // or
  5489. // | dojo.query("#baz > div").style({
  5490. // | opacity:0.75,
  5491. // | fontSize:"13pt"
  5492. // | });
  5493. var n = byId(node), args = arguments.length, op = (style == "opacity");
  5494. style = _floatAliases[style] || style;
  5495. if(args == 3){
  5496. return op ? d._setOpacity(n, value) : n.style[style] = value; /*Number*/
  5497. }
  5498. if(args == 2 && op){
  5499. return d._getOpacity(n);
  5500. }
  5501. var s = gcs(n);
  5502. if(args == 2 && typeof style != "string"){ // inline'd type check
  5503. for(var x in style){
  5504. d.style(node, x, style[x]);
  5505. }
  5506. return s;
  5507. }
  5508. return (args == 1) ? s : _toStyleValue(n, style, s[style] || n.style[style]); /* CSS2Properties||String||Number */
  5509. };
  5510. // =============================
  5511. // Box Functions
  5512. // =============================
  5513. dojo._getPadExtents = function(/*DomNode*/n, /*Object*/computedStyle){
  5514. // summary:
  5515. // Returns object with special values specifically useful for node
  5516. // fitting.
  5517. // description:
  5518. // Returns an object with `w`, `h`, `l`, `t` properties:
  5519. // | l/t = left/top padding (respectively)
  5520. // | w = the total of the left and right padding
  5521. // | h = the total of the top and bottom padding
  5522. // If 'node' has position, l/t forms the origin for child nodes.
  5523. // The w/h are used for calculating boxes.
  5524. // Normally application code will not need to invoke this
  5525. // directly, and will use the ...box... functions instead.
  5526. var
  5527. s = computedStyle||gcs(n),
  5528. l = px(n, s.paddingLeft),
  5529. t = px(n, s.paddingTop);
  5530. return {
  5531. l: l,
  5532. t: t,
  5533. w: l+px(n, s.paddingRight),
  5534. h: t+px(n, s.paddingBottom)
  5535. };
  5536. };
  5537. dojo._getBorderExtents = function(/*DomNode*/n, /*Object*/computedStyle){
  5538. // summary:
  5539. // returns an object with properties useful for noting the border
  5540. // dimensions.
  5541. // description:
  5542. // * l/t = the sum of left/top border (respectively)
  5543. // * w = the sum of the left and right border
  5544. // * h = the sum of the top and bottom border
  5545. //
  5546. // The w/h are used for calculating boxes.
  5547. // Normally application code will not need to invoke this
  5548. // directly, and will use the ...box... functions instead.
  5549. var
  5550. ne = "none",
  5551. s = computedStyle||gcs(n),
  5552. bl = (s.borderLeftStyle != ne ? px(n, s.borderLeftWidth) : 0),
  5553. bt = (s.borderTopStyle != ne ? px(n, s.borderTopWidth) : 0);
  5554. return {
  5555. l: bl,
  5556. t: bt,
  5557. w: bl + (s.borderRightStyle!=ne ? px(n, s.borderRightWidth) : 0),
  5558. h: bt + (s.borderBottomStyle!=ne ? px(n, s.borderBottomWidth) : 0)
  5559. };
  5560. };
  5561. dojo._getPadBorderExtents = function(/*DomNode*/n, /*Object*/computedStyle){
  5562. // summary:
  5563. // Returns object with properties useful for box fitting with
  5564. // regards to padding.
  5565. // description:
  5566. // * l/t = the sum of left/top padding and left/top border (respectively)
  5567. // * w = the sum of the left and right padding and border
  5568. // * h = the sum of the top and bottom padding and border
  5569. //
  5570. // The w/h are used for calculating boxes.
  5571. // Normally application code will not need to invoke this
  5572. // directly, and will use the ...box... functions instead.
  5573. var
  5574. s = computedStyle||gcs(n),
  5575. p = d._getPadExtents(n, s),
  5576. b = d._getBorderExtents(n, s);
  5577. return {
  5578. l: p.l + b.l,
  5579. t: p.t + b.t,
  5580. w: p.w + b.w,
  5581. h: p.h + b.h
  5582. };
  5583. };
  5584. dojo._getMarginExtents = function(n, computedStyle){
  5585. // summary:
  5586. // returns object with properties useful for box fitting with
  5587. // regards to box margins (i.e., the outer-box).
  5588. //
  5589. // * l/t = marginLeft, marginTop, respectively
  5590. // * w = total width, margin inclusive
  5591. // * h = total height, margin inclusive
  5592. //
  5593. // The w/h are used for calculating boxes.
  5594. // Normally application code will not need to invoke this
  5595. // directly, and will use the ...box... functions instead.
  5596. var
  5597. s = computedStyle||gcs(n),
  5598. l = px(n, s.marginLeft),
  5599. t = px(n, s.marginTop),
  5600. r = px(n, s.marginRight),
  5601. b = px(n, s.marginBottom);
  5602. if(d.isWebKit && (s.position != "absolute")){
  5603. // FIXME: Safari's version of the computed right margin
  5604. // is the space between our right edge and the right edge
  5605. // of our offsetParent.
  5606. // What we are looking for is the actual margin value as
  5607. // determined by CSS.
  5608. // Hack solution is to assume left/right margins are the same.
  5609. r = l;
  5610. }
  5611. return {
  5612. l: l,
  5613. t: t,
  5614. w: l+r,
  5615. h: t+b
  5616. };
  5617. };
  5618. // Box getters work in any box context because offsetWidth/clientWidth
  5619. // are invariant wrt box context
  5620. //
  5621. // They do *not* work for display: inline objects that have padding styles
  5622. // because the user agent ignores padding (it's bogus styling in any case)
  5623. //
  5624. // Be careful with IMGs because they are inline or block depending on
  5625. // browser and browser mode.
  5626. // Although it would be easier to read, there are not separate versions of
  5627. // _getMarginBox for each browser because:
  5628. // 1. the branching is not expensive
  5629. // 2. factoring the shared code wastes cycles (function call overhead)
  5630. // 3. duplicating the shared code wastes bytes
  5631. dojo._getMarginBox = function(/*DomNode*/node, /*Object*/computedStyle){
  5632. // summary:
  5633. // returns an object that encodes the width, height, left and top
  5634. // positions of the node's margin box.
  5635. var s = computedStyle || gcs(node), me = d._getMarginExtents(node, s);
  5636. var l = node.offsetLeft - me.l, t = node.offsetTop - me.t, p = node.parentNode;
  5637. if(d.isMoz){
  5638. // Mozilla:
  5639. // If offsetParent has a computed overflow != visible, the offsetLeft is decreased
  5640. // by the parent's border.
  5641. // We don't want to compute the parent's style, so instead we examine node's
  5642. // computed left/top which is more stable.
  5643. var sl = parseFloat(s.left), st = parseFloat(s.top);
  5644. if(!isNaN(sl) && !isNaN(st)){
  5645. l = sl, t = st;
  5646. }else{
  5647. // If child's computed left/top are not parseable as a number (e.g. "auto"), we
  5648. // have no choice but to examine the parent's computed style.
  5649. if(p && p.style){
  5650. var pcs = gcs(p);
  5651. if(pcs.overflow != "visible"){
  5652. var be = d._getBorderExtents(p, pcs);
  5653. l += be.l, t += be.t;
  5654. }
  5655. }
  5656. }
  5657. }else if(d.isOpera || (d.isIE == 8 && !d.isQuirks)){
  5658. // On Opera and IE 8, offsetLeft/Top includes the parent's border
  5659. if(p){
  5660. be = d._getBorderExtents(p);
  5661. l -= be.l;
  5662. t -= be.t;
  5663. }
  5664. }
  5665. return {
  5666. l: l,
  5667. t: t,
  5668. w: node.offsetWidth + me.w,
  5669. h: node.offsetHeight + me.h
  5670. };
  5671. }
  5672. dojo._getMarginSize = function(/*DomNode*/node, /*Object*/computedStyle){
  5673. // summary:
  5674. // returns an object that encodes the width and height of
  5675. // the node's margin box
  5676. node = byId(node);
  5677. var me = d._getMarginExtents(node, computedStyle || gcs(node));
  5678. var size = node.getBoundingClientRect();
  5679. return {
  5680. w: (size.right - size.left) + me.w,
  5681. h: (size.bottom - size.top) + me.h
  5682. }
  5683. }
  5684. dojo._getContentBox = function(node, computedStyle){
  5685. // summary:
  5686. // Returns an object that encodes the width, height, left and top
  5687. // positions of the node's content box, irrespective of the
  5688. // current box model.
  5689. // clientWidth/Height are important since the automatically account for scrollbars
  5690. // fallback to offsetWidth/Height for special cases (see #3378)
  5691. var s = computedStyle || gcs(node),
  5692. pe = d._getPadExtents(node, s),
  5693. be = d._getBorderExtents(node, s),
  5694. w = node.clientWidth,
  5695. h
  5696. ;
  5697. if(!w){
  5698. w = node.offsetWidth, h = node.offsetHeight;
  5699. }else{
  5700. h = node.clientHeight, be.w = be.h = 0;
  5701. }
  5702. // On Opera, offsetLeft includes the parent's border
  5703. if(d.isOpera){ pe.l += be.l; pe.t += be.t; }
  5704. return {
  5705. l: pe.l,
  5706. t: pe.t,
  5707. w: w - pe.w - be.w,
  5708. h: h - pe.h - be.h
  5709. };
  5710. };
  5711. dojo._getBorderBox = function(node, computedStyle){
  5712. var s = computedStyle || gcs(node),
  5713. pe = d._getPadExtents(node, s),
  5714. cb = d._getContentBox(node, s)
  5715. ;
  5716. return {
  5717. l: cb.l - pe.l,
  5718. t: cb.t - pe.t,
  5719. w: cb.w + pe.w,
  5720. h: cb.h + pe.h
  5721. };
  5722. };
  5723. // Box setters depend on box context because interpretation of width/height styles
  5724. // vary wrt box context.
  5725. //
  5726. // The value of dojo.boxModel is used to determine box context.
  5727. // dojo.boxModel can be set directly to change behavior.
  5728. //
  5729. // Beware of display: inline objects that have padding styles
  5730. // because the user agent ignores padding (it's a bogus setup anyway)
  5731. //
  5732. // Be careful with IMGs because they are inline or block depending on
  5733. // browser and browser mode.
  5734. //
  5735. // Elements other than DIV may have special quirks, like built-in
  5736. // margins or padding, or values not detectable via computedStyle.
  5737. // In particular, margins on TABLE do not seems to appear
  5738. // at all in computedStyle on Mozilla.
  5739. dojo._setBox = function(/*DomNode*/node, /*Number?*/l, /*Number?*/t, /*Number?*/w, /*Number?*/h, /*String?*/u){
  5740. // summary:
  5741. // sets width/height/left/top in the current (native) box-model
  5742. // dimentions. Uses the unit passed in u.
  5743. // node:
  5744. // DOM Node reference. Id string not supported for performance
  5745. // reasons.
  5746. // l:
  5747. // left offset from parent.
  5748. // t:
  5749. // top offset from parent.
  5750. // w:
  5751. // width in current box model.
  5752. // h:
  5753. // width in current box model.
  5754. // u:
  5755. // unit measure to use for other measures. Defaults to "px".
  5756. u = u || "px";
  5757. var s = node.style;
  5758. if(!isNaN(l)){ s.left = l + u; }
  5759. if(!isNaN(t)){ s.top = t + u; }
  5760. if(w >= 0){ s.width = w + u; }
  5761. if(h >= 0){ s.height = h + u; }
  5762. };
  5763. dojo._isButtonTag = function(/*DomNode*/node) {
  5764. // summary:
  5765. // True if the node is BUTTON or INPUT.type="button".
  5766. return node.tagName == "BUTTON"
  5767. || node.tagName=="INPUT" && (node.getAttribute("type")||'').toUpperCase() == "BUTTON"; // boolean
  5768. };
  5769. dojo._usesBorderBox = function(/*DomNode*/node){
  5770. // summary:
  5771. // True if the node uses border-box layout.
  5772. // We could test the computed style of node to see if a particular box
  5773. // has been specified, but there are details and we choose not to bother.
  5774. // TABLE and BUTTON (and INPUT type=button) are always border-box by default.
  5775. // If you have assigned a different box to either one via CSS then
  5776. // box functions will break.
  5777. var n = node.tagName;
  5778. return d.boxModel=="border-box" || n=="TABLE" || d._isButtonTag(node); // boolean
  5779. };
  5780. dojo._setContentSize = function(/*DomNode*/node, /*Number*/widthPx, /*Number*/heightPx, /*Object*/computedStyle){
  5781. // summary:
  5782. // Sets the size of the node's contents, irrespective of margins,
  5783. // padding, or borders.
  5784. if(d._usesBorderBox(node)){
  5785. var pb = d._getPadBorderExtents(node, computedStyle);
  5786. if(widthPx >= 0){ widthPx += pb.w; }
  5787. if(heightPx >= 0){ heightPx += pb.h; }
  5788. }
  5789. d._setBox(node, NaN, NaN, widthPx, heightPx);
  5790. };
  5791. dojo._setMarginBox = function(/*DomNode*/node, /*Number?*/leftPx, /*Number?*/topPx,
  5792. /*Number?*/widthPx, /*Number?*/heightPx,
  5793. /*Object*/computedStyle){
  5794. // summary:
  5795. // sets the size of the node's margin box and placement
  5796. // (left/top), irrespective of box model. Think of it as a
  5797. // passthrough to dojo._setBox that handles box-model vagaries for
  5798. // you.
  5799. var s = computedStyle || gcs(node),
  5800. // Some elements have special padding, margin, and box-model settings.
  5801. // To use box functions you may need to set padding, margin explicitly.
  5802. // Controlling box-model is harder, in a pinch you might set dojo.boxModel.
  5803. bb = d._usesBorderBox(node),
  5804. pb = bb ? _nilExtents : d._getPadBorderExtents(node, s)
  5805. ;
  5806. if(d.isWebKit){
  5807. // on Safari (3.1.2), button nodes with no explicit size have a default margin
  5808. // setting an explicit size eliminates the margin.
  5809. // We have to swizzle the width to get correct margin reading.
  5810. if(d._isButtonTag(node)){
  5811. var ns = node.style;
  5812. if(widthPx >= 0 && !ns.width) { ns.width = "4px"; }
  5813. if(heightPx >= 0 && !ns.height) { ns.height = "4px"; }
  5814. }
  5815. }
  5816. var mb = d._getMarginExtents(node, s);
  5817. if(widthPx >= 0){ widthPx = Math.max(widthPx - pb.w - mb.w, 0); }
  5818. if(heightPx >= 0){ heightPx = Math.max(heightPx - pb.h - mb.h, 0); }
  5819. d._setBox(node, leftPx, topPx, widthPx, heightPx);
  5820. };
  5821. var _nilExtents = { l:0, t:0, w:0, h:0 };
  5822. // public API
  5823. dojo.marginBox = function(/*DomNode|String*/node, /*Object?*/box){
  5824. // summary:
  5825. // Getter/setter for the margin-box of node.
  5826. // description:
  5827. // Getter/setter for the margin-box of node.
  5828. // Returns an object in the expected format of box (regardless
  5829. // if box is passed). The object might look like:
  5830. // `{ l: 50, t: 200, w: 300: h: 150 }`
  5831. // for a node offset from its parent 50px to the left, 200px from
  5832. // the top with a margin width of 300px and a margin-height of
  5833. // 150px.
  5834. // node:
  5835. // id or reference to DOM Node to get/set box for
  5836. // box:
  5837. // If passed, denotes that dojo.marginBox() should
  5838. // update/set the margin box for node. Box is an object in the
  5839. // above format. All properties are optional if passed.
  5840. // example:
  5841. // Retrieve the marginbox of a passed node
  5842. // | var box = dojo.marginBox("someNodeId");
  5843. // | console.dir(box);
  5844. //
  5845. // example:
  5846. // Set a node's marginbox to the size of another node
  5847. // | var box = dojo.marginBox("someNodeId");
  5848. // | dojo.marginBox("someOtherNode", box);
  5849. var n = byId(node), s = gcs(n), b = box;
  5850. return !b ? d._getMarginBox(n, s) : d._setMarginBox(n, b.l, b.t, b.w, b.h, s); // Object
  5851. };
  5852. dojo.contentBox = function(/*DomNode|String*/node, /*Object?*/box){
  5853. // summary:
  5854. // Getter/setter for the content-box of node.
  5855. // description:
  5856. // Returns an object in the expected format of box (regardless if box is passed).
  5857. // The object might look like:
  5858. // `{ l: 50, t: 200, w: 300: h: 150 }`
  5859. // for a node offset from its parent 50px to the left, 200px from
  5860. // the top with a content width of 300px and a content-height of
  5861. // 150px. Note that the content box may have a much larger border
  5862. // or margin box, depending on the box model currently in use and
  5863. // CSS values set/inherited for node.
  5864. // While the getter will return top and left values, the
  5865. // setter only accepts setting the width and height.
  5866. // node:
  5867. // id or reference to DOM Node to get/set box for
  5868. // box:
  5869. // If passed, denotes that dojo.contentBox() should
  5870. // update/set the content box for node. Box is an object in the
  5871. // above format, but only w (width) and h (height) are supported.
  5872. // All properties are optional if passed.
  5873. var n = byId(node), s = gcs(n), b = box;
  5874. return !b ? d._getContentBox(n, s) : d._setContentSize(n, b.w, b.h, s); // Object
  5875. };
  5876. // =============================
  5877. // Positioning
  5878. // =============================
  5879. var _sumAncestorProperties = function(node, prop){
  5880. if(!(node = (node||0).parentNode)){return 0;}
  5881. var val, retVal = 0, _b = d.body();
  5882. while(node && node.style){
  5883. if(gcs(node).position == "fixed"){
  5884. return 0;
  5885. }
  5886. val = node[prop];
  5887. if(val){
  5888. retVal += val - 0;
  5889. // opera and khtml #body & #html has the same values, we only
  5890. // need one value
  5891. if(node == _b){ break; }
  5892. }
  5893. node = node.parentNode;
  5894. }
  5895. return retVal; // integer
  5896. };
  5897. dojo._docScroll = function(){
  5898. var n = d.global;
  5899. return "pageXOffset" in n
  5900. ? { x:n.pageXOffset, y:n.pageYOffset }
  5901. : (n = d.isQuirks? d.doc.body : d.doc.documentElement, { x:d._fixIeBiDiScrollLeft(n.scrollLeft || 0), y:n.scrollTop || 0 });
  5902. };
  5903. dojo._isBodyLtr = function(){
  5904. return "_bodyLtr" in d? d._bodyLtr :
  5905. d._bodyLtr = ((d.body() && d.body().dir) || d.doc.documentElement.dir || "ltr").toLowerCase() == "ltr"; // Boolean
  5906. };
  5907. dojo._getIeDocumentElementOffset = function(){
  5908. // summary:
  5909. // returns the offset in x and y from the document body to the
  5910. // visual edge of the page
  5911. // description:
  5912. // The following values in IE contain an offset:
  5913. // | event.clientX
  5914. // | event.clientY
  5915. // | node.getBoundingClientRect().left
  5916. // | node.getBoundingClientRect().top
  5917. // But other position related values do not contain this offset,
  5918. // such as node.offsetLeft, node.offsetTop, node.style.left and
  5919. // node.style.top. The offset is always (2, 2) in LTR direction.
  5920. // When the body is in RTL direction, the offset counts the width
  5921. // of left scroll bar's width. This function computes the actual
  5922. // offset.
  5923. //NOTE: assumes we're being called in an IE browser
  5924. var de = d.doc.documentElement; // only deal with HTML element here, _abs handles body/quirks
  5925. if(d.isIE < 8){
  5926. var r = de.getBoundingClientRect(); // works well for IE6+
  5927. //console.debug('rect left,top = ' + r.left+','+r.top + ', html client left/top = ' + de.clientLeft+','+de.clientTop + ', rtl = ' + (!d._isBodyLtr()) + ', quirks = ' + d.isQuirks);
  5928. var l = r.left,
  5929. t = r.top;
  5930. if(d.isIE < 7){
  5931. l += de.clientLeft; // scrollbar size in strict/RTL, or,
  5932. t += de.clientTop; // HTML border size in strict
  5933. }
  5934. return {
  5935. x: l < 0? 0 : l, // FRAME element border size can lead to inaccurate negative values
  5936. y: t < 0? 0 : t
  5937. };
  5938. }else{
  5939. return {
  5940. x: 0,
  5941. y: 0
  5942. };
  5943. }
  5944. };
  5945. dojo._fixIeBiDiScrollLeft = function(/*Integer*/ scrollLeft){
  5946. // In RTL direction, scrollLeft should be a negative value, but IE
  5947. // returns a positive one. All codes using documentElement.scrollLeft
  5948. // must call this function to fix this error, otherwise the position
  5949. // will offset to right when there is a horizontal scrollbar.
  5950. var ie = d.isIE;
  5951. if(ie && !d._isBodyLtr()){
  5952. var qk = d.isQuirks,
  5953. de = qk ? d.doc.body : d.doc.documentElement;
  5954. if(ie == 6 && !qk && d.global.frameElement && de.scrollHeight > de.clientHeight){
  5955. scrollLeft += de.clientLeft; // workaround ie6+strict+rtl+iframe+vertical-scrollbar bug where clientWidth is too small by clientLeft pixels
  5956. }
  5957. return (ie < 8 || qk) ? (scrollLeft + de.clientWidth - de.scrollWidth) : -scrollLeft; // Integer
  5958. }
  5959. return scrollLeft; // Integer
  5960. };
  5961. // FIXME: need a setter for coords or a moveTo!!
  5962. dojo._abs = dojo.position = function(/*DomNode*/node, /*Boolean?*/includeScroll){
  5963. // summary:
  5964. // Gets the position and size of the passed element relative to
  5965. // the viewport (if includeScroll==false), or relative to the
  5966. // document root (if includeScroll==true).
  5967. //
  5968. // description:
  5969. // Returns an object of the form:
  5970. // { x: 100, y: 300, w: 20, h: 15 }
  5971. // If includeScroll==true, the x and y values will include any
  5972. // document offsets that may affect the position relative to the
  5973. // viewport.
  5974. // Uses the border-box model (inclusive of border and padding but
  5975. // not margin). Does not act as a setter.
  5976. node = byId(node);
  5977. var db = d.body(),
  5978. dh = db.parentNode,
  5979. ret = node.getBoundingClientRect();
  5980. ret = { x: ret.left, y: ret.top, w: ret.right - ret.left, h: ret.bottom - ret.top };
  5981. if(d.isIE < 9){
  5982. // On IE there's a 2px offset that we need to adjust for, see _getIeDocumentElementOffset()
  5983. var offset = d._getIeDocumentElementOffset();
  5984. // fixes the position in IE, quirks mode
  5985. ret.x -= offset.x + (d.isQuirks ? db.clientLeft+db.offsetLeft : 0);
  5986. ret.y -= offset.y + (d.isQuirks ? db.clientTop+db.offsetTop : 0);
  5987. }else if(d.isFF == 3){
  5988. // In FF3 you have to subtract the document element margins.
  5989. // Fixed in FF3.5 though.
  5990. var cs = gcs(dh);
  5991. ret.x -= px(dh, cs.marginLeft) + px(dh, cs.borderLeftWidth);
  5992. ret.y -= px(dh, cs.marginTop) + px(dh, cs.borderTopWidth);
  5993. }
  5994. // account for document scrolling
  5995. if(includeScroll){
  5996. var scroll = d._docScroll();
  5997. ret.x += scroll.x;
  5998. ret.y += scroll.y;
  5999. }
  6000. return ret; // Object
  6001. };
  6002. dojo.coords = function(/*DomNode|String*/node, /*Boolean?*/includeScroll){
  6003. // summary:
  6004. // Deprecated: Use position() for border-box x/y/w/h
  6005. // or marginBox() for margin-box w/h/l/t.
  6006. // Returns an object representing a node's size and position.
  6007. //
  6008. // description:
  6009. // Returns an object that measures margin-box (w)idth/(h)eight
  6010. // and absolute position x/y of the border-box. Also returned
  6011. // is computed (l)eft and (t)op values in pixels from the
  6012. // node's offsetParent as returned from marginBox().
  6013. // Return value will be in the form:
  6014. //| { l: 50, t: 200, w: 300: h: 150, x: 100, y: 300 }
  6015. // Does not act as a setter. If includeScroll is passed, the x and
  6016. // y params are affected as one would expect in dojo.position().
  6017. var n = byId(node), s = gcs(n), mb = d._getMarginBox(n, s);
  6018. var abs = d.position(n, includeScroll);
  6019. mb.x = abs.x;
  6020. mb.y = abs.y;
  6021. return mb;
  6022. };
  6023. // =============================
  6024. // Element attribute Functions
  6025. // =============================
  6026. // dojo.attr() should conform to http://www.w3.org/TR/DOM-Level-2-Core/
  6027. var _propNames = {
  6028. // properties renamed to avoid clashes with reserved words
  6029. "class": "className",
  6030. "for": "htmlFor",
  6031. // properties written as camelCase
  6032. tabindex: "tabIndex",
  6033. readonly: "readOnly",
  6034. colspan: "colSpan",
  6035. frameborder: "frameBorder",
  6036. rowspan: "rowSpan",
  6037. valuetype: "valueType"
  6038. },
  6039. _attrNames = {
  6040. // original attribute names
  6041. classname: "class",
  6042. htmlfor: "for",
  6043. // for IE
  6044. tabindex: "tabIndex",
  6045. readonly: "readOnly"
  6046. },
  6047. _forcePropNames = {
  6048. innerHTML: 1,
  6049. className: 1,
  6050. htmlFor: d.isIE,
  6051. value: 1
  6052. };
  6053. var _fixAttrName = function(/*String*/ name){
  6054. return _attrNames[name.toLowerCase()] || name;
  6055. };
  6056. var _hasAttr = function(node, name){
  6057. var attr = node.getAttributeNode && node.getAttributeNode(name);
  6058. return attr && attr.specified; // Boolean
  6059. };
  6060. // There is a difference in the presence of certain properties and their default values
  6061. // between browsers. For example, on IE "disabled" is present on all elements,
  6062. // but it is value is "false"; "tabIndex" of <div> returns 0 by default on IE, yet other browsers
  6063. // can return -1.
  6064. dojo.hasAttr = function(/*DomNode|String*/node, /*String*/name){
  6065. // summary:
  6066. // Returns true if the requested attribute is specified on the
  6067. // given element, and false otherwise.
  6068. // node:
  6069. // id or reference to the element to check
  6070. // name:
  6071. // the name of the attribute
  6072. // returns:
  6073. // true if the requested attribute is specified on the
  6074. // given element, and false otherwise
  6075. var lc = name.toLowerCase();
  6076. return _forcePropNames[_propNames[lc] || name] || _hasAttr(byId(node), _attrNames[lc] || name); // Boolean
  6077. };
  6078. var _evtHdlrMap = {}, _ctr = 0,
  6079. _attrId = dojo._scopeName + "attrid",
  6080. // the next dictionary lists elements with read-only innerHTML on IE
  6081. _roInnerHtml = {col: 1, colgroup: 1,
  6082. // frameset: 1, head: 1, html: 1, style: 1,
  6083. table: 1, tbody: 1, tfoot: 1, thead: 1, tr: 1, title: 1};
  6084. dojo.attr = function(/*DomNode|String*/node, /*String|Object*/name, /*String?*/value){
  6085. // summary:
  6086. // Gets or sets an attribute on an HTML element.
  6087. // description:
  6088. // Handles normalized getting and setting of attributes on DOM
  6089. // Nodes. If 2 arguments are passed, and a the second argumnt is a
  6090. // string, acts as a getter.
  6091. //
  6092. // If a third argument is passed, or if the second argument is a
  6093. // map of attributes, acts as a setter.
  6094. //
  6095. // When passing functions as values, note that they will not be
  6096. // directly assigned to slots on the node, but rather the default
  6097. // behavior will be removed and the new behavior will be added
  6098. // using `dojo.connect()`, meaning that event handler properties
  6099. // will be normalized and that some caveats with regards to
  6100. // non-standard behaviors for onsubmit apply. Namely that you
  6101. // should cancel form submission using `dojo.stopEvent()` on the
  6102. // passed event object instead of returning a boolean value from
  6103. // the handler itself.
  6104. // node:
  6105. // id or reference to the element to get or set the attribute on
  6106. // name:
  6107. // the name of the attribute to get or set.
  6108. // value:
  6109. // The value to set for the attribute
  6110. // returns:
  6111. // when used as a getter, the value of the requested attribute
  6112. // or null if that attribute does not have a specified or
  6113. // default value;
  6114. //
  6115. // when used as a setter, the DOM node
  6116. //
  6117. // example:
  6118. // | // get the current value of the "foo" attribute on a node
  6119. // | dojo.attr(dojo.byId("nodeId"), "foo");
  6120. // | // or we can just pass the id:
  6121. // | dojo.attr("nodeId", "foo");
  6122. //
  6123. // example:
  6124. // | // use attr() to set the tab index
  6125. // | dojo.attr("nodeId", "tabIndex", 3);
  6126. // |
  6127. //
  6128. // example:
  6129. // Set multiple values at once, including event handlers:
  6130. // | dojo.attr("formId", {
  6131. // | "foo": "bar",
  6132. // | "tabIndex": -1,
  6133. // | "method": "POST",
  6134. // | "onsubmit": function(e){
  6135. // | // stop submitting the form. Note that the IE behavior
  6136. // | // of returning true or false will have no effect here
  6137. // | // since our handler is connect()ed to the built-in
  6138. // | // onsubmit behavior and so we need to use
  6139. // | // dojo.stopEvent() to ensure that the submission
  6140. // | // doesn't proceed.
  6141. // | dojo.stopEvent(e);
  6142. // |
  6143. // | // submit the form with Ajax
  6144. // | dojo.xhrPost({ form: "formId" });
  6145. // | }
  6146. // | });
  6147. //
  6148. // example:
  6149. // Style is s special case: Only set with an object hash of styles
  6150. // | dojo.attr("someNode",{
  6151. // | id:"bar",
  6152. // | style:{
  6153. // | width:"200px", height:"100px", color:"#000"
  6154. // | }
  6155. // | });
  6156. //
  6157. // example:
  6158. // Again, only set style as an object hash of styles:
  6159. // | var obj = { color:"#fff", backgroundColor:"#000" };
  6160. // | dojo.attr("someNode", "style", obj);
  6161. // |
  6162. // | // though shorter to use `dojo.style()` in this case:
  6163. // | dojo.style("someNode", obj);
  6164. node = byId(node);
  6165. var args = arguments.length, prop;
  6166. if(args == 2 && typeof name != "string"){ // inline'd type check
  6167. // the object form of setter: the 2nd argument is a dictionary
  6168. for(var x in name){
  6169. d.attr(node, x, name[x]);
  6170. }
  6171. return node; // DomNode
  6172. }
  6173. var lc = name.toLowerCase(),
  6174. propName = _propNames[lc] || name,
  6175. forceProp = _forcePropNames[propName],
  6176. attrName = _attrNames[lc] || name;
  6177. if(args == 3){
  6178. // setter
  6179. do{
  6180. if(propName == "style" && typeof value != "string"){ // inline'd type check
  6181. // special case: setting a style
  6182. d.style(node, value);
  6183. break;
  6184. }
  6185. if(propName == "innerHTML"){
  6186. // special case: assigning HTML
  6187. if(d.isIE && node.tagName.toLowerCase() in _roInnerHtml){
  6188. d.empty(node);
  6189. node.appendChild(d._toDom(value, node.ownerDocument));
  6190. }else{
  6191. node[propName] = value;
  6192. }
  6193. break;
  6194. }
  6195. if(d.isFunction(value)){
  6196. // special case: assigning an event handler
  6197. // clobber if we can
  6198. var attrId = d.attr(node, _attrId);
  6199. if(!attrId){
  6200. attrId = _ctr++;
  6201. d.attr(node, _attrId, attrId);
  6202. }
  6203. if(!_evtHdlrMap[attrId]){
  6204. _evtHdlrMap[attrId] = {};
  6205. }
  6206. var h = _evtHdlrMap[attrId][propName];
  6207. if(h){
  6208. d.disconnect(h);
  6209. }else{
  6210. try{
  6211. delete node[propName];
  6212. }catch(e){}
  6213. }
  6214. // ensure that event objects are normalized, etc.
  6215. _evtHdlrMap[attrId][propName] = d.connect(node, propName, value);
  6216. break;
  6217. }
  6218. if(forceProp || typeof value == "boolean"){
  6219. // special case: forcing assignment to the property
  6220. // special case: setting boolean to a property instead of attribute
  6221. node[propName] = value;
  6222. break;
  6223. }
  6224. // node's attribute
  6225. node.setAttribute(attrName, value);
  6226. }while(false);
  6227. return node; // DomNode
  6228. }
  6229. // getter
  6230. // should we access this attribute via a property or
  6231. // via getAttribute()?
  6232. value = node[propName];
  6233. if(forceProp && typeof value != "undefined"){
  6234. // node's property
  6235. return value; // Anything
  6236. }
  6237. if(propName != "href" && (typeof value == "boolean" || d.isFunction(value))){
  6238. // node's property
  6239. return value; // Anything
  6240. }
  6241. // node's attribute
  6242. // we need _hasAttr() here to guard against IE returning a default value
  6243. return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything
  6244. };
  6245. dojo.removeAttr = function(/*DomNode|String*/ node, /*String*/ name){
  6246. // summary:
  6247. // Removes an attribute from an HTML element.
  6248. // node:
  6249. // id or reference to the element to remove the attribute from
  6250. // name:
  6251. // the name of the attribute to remove
  6252. byId(node).removeAttribute(_fixAttrName(name));
  6253. };
  6254. dojo.getNodeProp = function(/*DomNode|String*/ node, /*String*/ name){
  6255. // summary:
  6256. // Returns an effective value of a property or an attribute.
  6257. // node:
  6258. // id or reference to the element to remove the attribute from
  6259. // name:
  6260. // the name of the attribute
  6261. node = byId(node);
  6262. var lc = name.toLowerCase(),
  6263. propName = _propNames[lc] || name;
  6264. if((propName in node) && propName != "href"){
  6265. // node's property
  6266. return node[propName]; // Anything
  6267. }
  6268. // node's attribute
  6269. var attrName = _attrNames[lc] || name;
  6270. return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything
  6271. };
  6272. dojo.create = function(tag, attrs, refNode, pos){
  6273. // summary:
  6274. // Create an element, allowing for optional attribute decoration
  6275. // and placement.
  6276. //
  6277. // description:
  6278. // A DOM Element creation function. A shorthand method for creating a node or
  6279. // a fragment, and allowing for a convenient optional attribute setting step,
  6280. // as well as an optional DOM placement reference.
  6281. //|
  6282. // Attributes are set by passing the optional object through `dojo.attr`.
  6283. // See `dojo.attr` for noted caveats and nuances, and API if applicable.
  6284. //|
  6285. // Placement is done via `dojo.place`, assuming the new node to be the action
  6286. // node, passing along the optional reference node and position.
  6287. //
  6288. // tag: String|DomNode
  6289. // A string of the element to create (eg: "div", "a", "p", "li", "script", "br"),
  6290. // or an existing DOM node to process.
  6291. //
  6292. // attrs: Object
  6293. // An object-hash of attributes to set on the newly created node.
  6294. // Can be null, if you don't want to set any attributes/styles.
  6295. // See: `dojo.attr` for a description of available attributes.
  6296. //
  6297. // refNode: String?|DomNode?
  6298. // Optional reference node. Used by `dojo.place` to place the newly created
  6299. // node somewhere in the dom relative to refNode. Can be a DomNode reference
  6300. // or String ID of a node.
  6301. //
  6302. // pos: String?
  6303. // Optional positional reference. Defaults to "last" by way of `dojo.place`,
  6304. // though can be set to "first","after","before","last", "replace" or "only"
  6305. // to further control the placement of the new node relative to the refNode.
  6306. // 'refNode' is required if a 'pos' is specified.
  6307. //
  6308. // returns: DomNode
  6309. //
  6310. // example:
  6311. // Create a DIV:
  6312. // | var n = dojo.create("div");
  6313. //
  6314. // example:
  6315. // Create a DIV with content:
  6316. // | var n = dojo.create("div", { innerHTML:"<p>hi</p>" });
  6317. //
  6318. // example:
  6319. // Place a new DIV in the BODY, with no attributes set
  6320. // | var n = dojo.create("div", null, dojo.body());
  6321. //
  6322. // example:
  6323. // Create an UL, and populate it with LI's. Place the list as the first-child of a
  6324. // node with id="someId":
  6325. // | var ul = dojo.create("ul", null, "someId", "first");
  6326. // | var items = ["one", "two", "three", "four"];
  6327. // | dojo.forEach(items, function(data){
  6328. // | dojo.create("li", { innerHTML: data }, ul);
  6329. // | });
  6330. //
  6331. // example:
  6332. // Create an anchor, with an href. Place in BODY:
  6333. // | dojo.create("a", { href:"foo.html", title:"Goto FOO!" }, dojo.body());
  6334. //
  6335. // example:
  6336. // Create a `dojo.NodeList()` from a new element (for syntatic sugar):
  6337. // | dojo.query(dojo.create('div'))
  6338. // | .addClass("newDiv")
  6339. // | .onclick(function(e){ console.log('clicked', e.target) })
  6340. // | .place("#someNode"); // redundant, but cleaner.
  6341. var doc = d.doc;
  6342. if(refNode){
  6343. refNode = byId(refNode);
  6344. doc = refNode.ownerDocument;
  6345. }
  6346. if(typeof tag == "string"){ // inline'd type check
  6347. tag = doc.createElement(tag);
  6348. }
  6349. if(attrs){ d.attr(tag, attrs); }
  6350. if(refNode){ d.place(tag, refNode, pos); }
  6351. return tag; // DomNode
  6352. };
  6353. /*=====
  6354. dojo.empty = function(node){
  6355. // summary:
  6356. // safely removes all children of the node.
  6357. // node: DOMNode|String
  6358. // a reference to a DOM node or an id.
  6359. // example:
  6360. // Destroy node's children byId:
  6361. // | dojo.empty("someId");
  6362. //
  6363. // example:
  6364. // Destroy all nodes' children in a list by reference:
  6365. // | dojo.query(".someNode").forEach(dojo.empty);
  6366. }
  6367. =====*/
  6368. function _empty(/*DomNode*/ node){
  6369. if(node.canHaveChildren){
  6370. try{
  6371. // fast path
  6372. node.innerHTML = "";
  6373. return;
  6374. }catch(e){
  6375. // innerHTML is readOnly (e.g. TABLE (sub)elements in quirks mode)
  6376. // Fall through (saves bytes)
  6377. }
  6378. }
  6379. // SVG/strict elements don't support innerHTML/canHaveChildren, and OBJECT/APPLET elements in quirks node have canHaveChildren=false
  6380. for(var c; c = node.lastChild;){ // intentional assignment
  6381. _destroy(c, node); // destroy is better than removeChild so TABLE subelements are removed in proper order
  6382. }
  6383. }
  6384. d.empty = function(node){
  6385. _empty(byId(node));
  6386. };
  6387. /*=====
  6388. dojo._toDom = function(frag, doc){
  6389. // summary:
  6390. // instantiates an HTML fragment returning the corresponding DOM.
  6391. // frag: String
  6392. // the HTML fragment
  6393. // doc: DocumentNode?
  6394. // optional document to use when creating DOM nodes, defaults to
  6395. // dojo.doc if not specified.
  6396. // returns: DocumentFragment
  6397. //
  6398. // example:
  6399. // Create a table row:
  6400. // | var tr = dojo._toDom("<tr><td>First!</td></tr>");
  6401. }
  6402. =====*/
  6403. // support stuff for dojo._toDom
  6404. var tagWrap = {
  6405. option: ["select"],
  6406. tbody: ["table"],
  6407. thead: ["table"],
  6408. tfoot: ["table"],
  6409. tr: ["table", "tbody"],
  6410. td: ["table", "tbody", "tr"],
  6411. th: ["table", "thead", "tr"],
  6412. legend: ["fieldset"],
  6413. caption: ["table"],
  6414. colgroup: ["table"],
  6415. col: ["table", "colgroup"],
  6416. li: ["ul"]
  6417. },
  6418. reTag = /<\s*([\w\:]+)/,
  6419. masterNode = {}, masterNum = 0,
  6420. masterName = "__" + d._scopeName + "ToDomId";
  6421. // generate start/end tag strings to use
  6422. // for the injection for each special tag wrap case.
  6423. for(var param in tagWrap){
  6424. if(tagWrap.hasOwnProperty(param)){
  6425. var tw = tagWrap[param];
  6426. tw.pre = param == "option" ? '<select multiple="multiple">' : "<" + tw.join("><") + ">";
  6427. tw.post = "</" + tw.reverse().join("></") + ">";
  6428. // the last line is destructive: it reverses the array,
  6429. // but we don't care at this point
  6430. }
  6431. }
  6432. d._toDom = function(frag, doc){
  6433. // summary:
  6434. // converts HTML string into DOM nodes.
  6435. doc = doc || d.doc;
  6436. var masterId = doc[masterName];
  6437. if(!masterId){
  6438. doc[masterName] = masterId = ++masterNum + "";
  6439. masterNode[masterId] = doc.createElement("div");
  6440. }
  6441. // make sure the frag is a string.
  6442. frag += "";
  6443. // find the starting tag, and get node wrapper
  6444. var match = frag.match(reTag),
  6445. tag = match ? match[1].toLowerCase() : "",
  6446. master = masterNode[masterId],
  6447. wrap, i, fc, df;
  6448. if(match && tagWrap[tag]){
  6449. wrap = tagWrap[tag];
  6450. master.innerHTML = wrap.pre + frag + wrap.post;
  6451. for(i = wrap.length; i; --i){
  6452. master = master.firstChild;
  6453. }
  6454. }else{
  6455. master.innerHTML = frag;
  6456. }
  6457. // one node shortcut => return the node itself
  6458. if(master.childNodes.length == 1){
  6459. return master.removeChild(master.firstChild); // DOMNode
  6460. }
  6461. // return multiple nodes as a document fragment
  6462. df = doc.createDocumentFragment();
  6463. while((fc = master.firstChild)){ // intentional assignment
  6464. df.appendChild(fc);
  6465. }
  6466. return df; // DOMNode
  6467. };
  6468. // =============================
  6469. // (CSS) Class Functions
  6470. // =============================
  6471. var _className = "className";
  6472. dojo.hasClass = function(/*DomNode|String*/node, /*String*/classStr){
  6473. // summary:
  6474. // Returns whether or not the specified classes are a portion of the
  6475. // class list currently applied to the node.
  6476. //
  6477. // node:
  6478. // String ID or DomNode reference to check the class for.
  6479. //
  6480. // classStr:
  6481. // A string class name to look for.
  6482. //
  6483. // example:
  6484. // Do something if a node with id="someNode" has class="aSillyClassName" present
  6485. // | if(dojo.hasClass("someNode","aSillyClassName")){ ... }
  6486. return ((" "+ byId(node)[_className] +" ").indexOf(" " + classStr + " ") >= 0); // Boolean
  6487. };
  6488. var spaces = /\s+/, a1 = [""],
  6489. fakeNode = {},
  6490. str2array = function(s){
  6491. if(typeof s == "string" || s instanceof String){
  6492. if(s.indexOf(" ") < 0){
  6493. a1[0] = s;
  6494. return a1;
  6495. }else{
  6496. return s.split(spaces);
  6497. }
  6498. }
  6499. // assumed to be an array
  6500. return s || "";
  6501. };
  6502. dojo.addClass = function(/*DomNode|String*/node, /*String|Array*/classStr){
  6503. // summary:
  6504. // Adds the specified classes to the end of the class list on the
  6505. // passed node. Will not re-apply duplicate classes.
  6506. //
  6507. // node:
  6508. // String ID or DomNode reference to add a class string too
  6509. //
  6510. // classStr:
  6511. // A String class name to add, or several space-separated class names,
  6512. // or an array of class names.
  6513. //
  6514. // example:
  6515. // Add a class to some node:
  6516. // | dojo.addClass("someNode", "anewClass");
  6517. //
  6518. // example:
  6519. // Add two classes at once:
  6520. // | dojo.addClass("someNode", "firstClass secondClass");
  6521. //
  6522. // example:
  6523. // Add two classes at once (using array):
  6524. // | dojo.addClass("someNode", ["firstClass", "secondClass"]);
  6525. //
  6526. // example:
  6527. // Available in `dojo.NodeList` for multiple additions
  6528. // | dojo.query("ul > li").addClass("firstLevel");
  6529. node = byId(node);
  6530. classStr = str2array(classStr);
  6531. var cls = node[_className], oldLen;
  6532. cls = cls ? " " + cls + " " : " ";
  6533. oldLen = cls.length;
  6534. for(var i = 0, len = classStr.length, c; i < len; ++i){
  6535. c = classStr[i];
  6536. if(c && cls.indexOf(" " + c + " ") < 0){
  6537. cls += c + " ";
  6538. }
  6539. }
  6540. if(oldLen < cls.length){
  6541. node[_className] = cls.substr(1, cls.length - 2);
  6542. }
  6543. };
  6544. dojo.removeClass = function(/*DomNode|String*/node, /*String|Array?*/classStr){
  6545. // summary:
  6546. // Removes the specified classes from node. No `dojo.hasClass`
  6547. // check is required.
  6548. //
  6549. // node:
  6550. // String ID or DomNode reference to remove the class from.
  6551. //
  6552. // classStr:
  6553. // An optional String class name to remove, or several space-separated
  6554. // class names, or an array of class names. If omitted, all class names
  6555. // will be deleted.
  6556. //
  6557. // example:
  6558. // Remove a class from some node:
  6559. // | dojo.removeClass("someNode", "firstClass");
  6560. //
  6561. // example:
  6562. // Remove two classes from some node:
  6563. // | dojo.removeClass("someNode", "firstClass secondClass");
  6564. //
  6565. // example:
  6566. // Remove two classes from some node (using array):
  6567. // | dojo.removeClass("someNode", ["firstClass", "secondClass"]);
  6568. //
  6569. // example:
  6570. // Remove all classes from some node:
  6571. // | dojo.removeClass("someNode");
  6572. //
  6573. // example:
  6574. // Available in `dojo.NodeList()` for multiple removal
  6575. // | dojo.query(".foo").removeClass("foo");
  6576. node = byId(node);
  6577. var cls;
  6578. if(classStr !== undefined){
  6579. classStr = str2array(classStr);
  6580. cls = " " + node[_className] + " ";
  6581. for(var i = 0, len = classStr.length; i < len; ++i){
  6582. cls = cls.replace(" " + classStr[i] + " ", " ");
  6583. }
  6584. cls = d.trim(cls);
  6585. }else{
  6586. cls = "";
  6587. }
  6588. if(node[_className] != cls){ node[_className] = cls; }
  6589. };
  6590. dojo.replaceClass = function(/*DomNode|String*/node, /*String|Array*/addClassStr, /*String|Array?*/removeClassStr){
  6591. // summary:
  6592. // Replaces one or more classes on a node if not present.
  6593. // Operates more quickly than calling dojo.removeClass and dojo.addClass
  6594. // node:
  6595. // String ID or DomNode reference to remove the class from.
  6596. // addClassStr:
  6597. // A String class name to add, or several space-separated class names,
  6598. // or an array of class names.
  6599. // removeClassStr:
  6600. // A String class name to remove, or several space-separated class names,
  6601. // or an array of class names.
  6602. //
  6603. // example:
  6604. // | dojo.replaceClass("someNode", "add1 add2", "remove1 remove2");
  6605. //
  6606. // example:
  6607. // Replace all classes with addMe
  6608. // | dojo.replaceClass("someNode", "addMe");
  6609. //
  6610. // example:
  6611. // Available in `dojo.NodeList()` for multiple toggles
  6612. // | dojo.query(".findMe").replaceClass("addMe", "removeMe");
  6613. node = byId(node);
  6614. fakeNode.className = node.className;
  6615. dojo.removeClass(fakeNode, removeClassStr);
  6616. dojo.addClass(fakeNode, addClassStr);
  6617. if(node.className !== fakeNode.className){
  6618. node.className = fakeNode.className;
  6619. }
  6620. };
  6621. dojo.toggleClass = function(/*DomNode|String*/node, /*String|Array*/classStr, /*Boolean?*/condition){
  6622. // summary:
  6623. // Adds a class to node if not present, or removes if present.
  6624. // Pass a boolean condition if you want to explicitly add or remove.
  6625. // condition:
  6626. // If passed, true means to add the class, false means to remove.
  6627. //
  6628. // example:
  6629. // | dojo.toggleClass("someNode", "hovered");
  6630. //
  6631. // example:
  6632. // Forcefully add a class
  6633. // | dojo.toggleClass("someNode", "hovered", true);
  6634. //
  6635. // example:
  6636. // Available in `dojo.NodeList()` for multiple toggles
  6637. // | dojo.query(".toggleMe").toggleClass("toggleMe");
  6638. if(condition === undefined){
  6639. condition = !d.hasClass(node, classStr);
  6640. }
  6641. d[condition ? "addClass" : "removeClass"](node, classStr);
  6642. };
  6643. })();
  6644. }
  6645. if(!dojo._hasResource["dojo._base.NodeList"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  6646. dojo._hasResource["dojo._base.NodeList"] = true;
  6647. dojo.provide("dojo._base.NodeList");
  6648. (function(){
  6649. var d = dojo;
  6650. var ap = Array.prototype, aps = ap.slice, apc = ap.concat;
  6651. var tnl = function(/*Array*/ a, /*dojo.NodeList?*/ parent, /*Function?*/ NodeListCtor){
  6652. // summary:
  6653. // decorate an array to make it look like a `dojo.NodeList`.
  6654. // a:
  6655. // Array of nodes to decorate.
  6656. // parent:
  6657. // An optional parent NodeList that generated the current
  6658. // list of nodes. Used to call _stash() so the parent NodeList
  6659. // can be accessed via end() later.
  6660. // NodeListCtor:
  6661. // An optional constructor function to use for any
  6662. // new NodeList calls. This allows a certain chain of
  6663. // NodeList calls to use a different object than dojo.NodeList.
  6664. if(!a.sort){
  6665. // make sure it's a real array before we pass it on to be wrapped
  6666. a = aps.call(a, 0);
  6667. }
  6668. var ctor = NodeListCtor || this._NodeListCtor || d._NodeListCtor;
  6669. a.constructor = ctor;
  6670. dojo._mixin(a, ctor.prototype);
  6671. a._NodeListCtor = ctor;
  6672. return parent ? a._stash(parent) : a;
  6673. };
  6674. var loopBody = function(f, a, o){
  6675. a = [0].concat(aps.call(a, 0));
  6676. o = o || d.global;
  6677. return function(node){
  6678. a[0] = node;
  6679. return f.apply(o, a);
  6680. };
  6681. };
  6682. // adapters
  6683. var adaptAsForEach = function(f, o){
  6684. // summary:
  6685. // adapts a single node function to be used in the forEach-type
  6686. // actions. The initial object is returned from the specialized
  6687. // function.
  6688. // f: Function
  6689. // a function to adapt
  6690. // o: Object?
  6691. // an optional context for f
  6692. return function(){
  6693. this.forEach(loopBody(f, arguments, o));
  6694. return this; // Object
  6695. };
  6696. };
  6697. var adaptAsMap = function(f, o){
  6698. // summary:
  6699. // adapts a single node function to be used in the map-type
  6700. // actions. The return is a new array of values, as via `dojo.map`
  6701. // f: Function
  6702. // a function to adapt
  6703. // o: Object?
  6704. // an optional context for f
  6705. return function(){
  6706. return this.map(loopBody(f, arguments, o));
  6707. };
  6708. };
  6709. var adaptAsFilter = function(f, o){
  6710. // summary:
  6711. // adapts a single node function to be used in the filter-type actions
  6712. // f: Function
  6713. // a function to adapt
  6714. // o: Object?
  6715. // an optional context for f
  6716. return function(){
  6717. return this.filter(loopBody(f, arguments, o));
  6718. };
  6719. };
  6720. var adaptWithCondition = function(f, g, o){
  6721. // summary:
  6722. // adapts a single node function to be used in the map-type
  6723. // actions, behaves like forEach() or map() depending on arguments
  6724. // f: Function
  6725. // a function to adapt
  6726. // g: Function
  6727. // a condition function, if true runs as map(), otherwise runs as forEach()
  6728. // o: Object?
  6729. // an optional context for f and g
  6730. return function(){
  6731. var a = arguments, body = loopBody(f, a, o);
  6732. if(g.call(o || d.global, a)){
  6733. return this.map(body); // self
  6734. }
  6735. this.forEach(body);
  6736. return this; // self
  6737. };
  6738. };
  6739. var magicGuard = function(a){
  6740. // summary:
  6741. // the guard function for dojo.attr() and dojo.style()
  6742. return a.length == 1 && (typeof a[0] == "string"); // inline'd type check
  6743. };
  6744. var orphan = function(node){
  6745. // summary:
  6746. // function to orphan nodes
  6747. var p = node.parentNode;
  6748. if(p){
  6749. p.removeChild(node);
  6750. }
  6751. };
  6752. // FIXME: should we move orphan() to dojo.html?
  6753. dojo.NodeList = function(){
  6754. // summary:
  6755. // dojo.NodeList is an of Array subclass which adds syntactic
  6756. // sugar for chaining, common iteration operations, animation, and
  6757. // node manipulation. NodeLists are most often returned as the
  6758. // result of dojo.query() calls.
  6759. // description:
  6760. // dojo.NodeList instances provide many utilities that reflect
  6761. // core Dojo APIs for Array iteration and manipulation, DOM
  6762. // manipulation, and event handling. Instead of needing to dig up
  6763. // functions in the dojo.* namespace, NodeLists generally make the
  6764. // full power of Dojo available for DOM manipulation tasks in a
  6765. // simple, chainable way.
  6766. // example:
  6767. // create a node list from a node
  6768. // | new dojo.NodeList(dojo.byId("foo"));
  6769. // example:
  6770. // get a NodeList from a CSS query and iterate on it
  6771. // | var l = dojo.query(".thinger");
  6772. // | l.forEach(function(node, index, nodeList){
  6773. // | console.log(index, node.innerHTML);
  6774. // | });
  6775. // example:
  6776. // use native and Dojo-provided array methods to manipulate a
  6777. // NodeList without needing to use dojo.* functions explicitly:
  6778. // | var l = dojo.query(".thinger");
  6779. // | // since NodeLists are real arrays, they have a length
  6780. // | // property that is both readable and writable and
  6781. // | // push/pop/shift/unshift methods
  6782. // | console.log(l.length);
  6783. // | l.push(dojo.create("span"));
  6784. // |
  6785. // | // dojo's normalized array methods work too:
  6786. // | console.log( l.indexOf(dojo.byId("foo")) );
  6787. // | // ...including the special "function as string" shorthand
  6788. // | console.log( l.every("item.nodeType == 1") );
  6789. // |
  6790. // | // NodeLists can be [..] indexed, or you can use the at()
  6791. // | // function to get specific items wrapped in a new NodeList:
  6792. // | var node = l[3]; // the 4th element
  6793. // | var newList = l.at(1, 3); // the 2nd and 4th elements
  6794. // example:
  6795. // the style functions you expect are all there too:
  6796. // | // style() as a getter...
  6797. // | var borders = dojo.query(".thinger").style("border");
  6798. // | // ...and as a setter:
  6799. // | dojo.query(".thinger").style("border", "1px solid black");
  6800. // | // class manipulation
  6801. // | dojo.query("li:nth-child(even)").addClass("even");
  6802. // | // even getting the coordinates of all the items
  6803. // | var coords = dojo.query(".thinger").coords();
  6804. // example:
  6805. // DOM manipulation functions from the dojo.* namespace area also
  6806. // available:
  6807. // | // remove all of the elements in the list from their
  6808. // | // parents (akin to "deleting" them from the document)
  6809. // | dojo.query(".thinger").orphan();
  6810. // | // place all elements in the list at the front of #foo
  6811. // | dojo.query(".thinger").place("foo", "first");
  6812. // example:
  6813. // Event handling couldn't be easier. `dojo.connect` is mapped in,
  6814. // and shortcut handlers are provided for most DOM events:
  6815. // | // like dojo.connect(), but with implicit scope
  6816. // | dojo.query("li").connect("onclick", console, "log");
  6817. // |
  6818. // | // many common event handlers are already available directly:
  6819. // | dojo.query("li").onclick(console, "log");
  6820. // | var toggleHovered = dojo.hitch(dojo, "toggleClass", "hovered");
  6821. // | dojo.query("p")
  6822. // | .onmouseenter(toggleHovered)
  6823. // | .onmouseleave(toggleHovered);
  6824. // example:
  6825. // chainability is a key advantage of NodeLists:
  6826. // | dojo.query(".thinger")
  6827. // | .onclick(function(e){ /* ... */ })
  6828. // | .at(1, 3, 8) // get a subset
  6829. // | .style("padding", "5px")
  6830. // | .forEach(console.log);
  6831. return tnl(Array.apply(null, arguments));
  6832. };
  6833. //Allow things that new up a NodeList to use a delegated or alternate NodeList implementation.
  6834. d._NodeListCtor = d.NodeList;
  6835. var nl = d.NodeList, nlp = nl.prototype;
  6836. // expose adapters and the wrapper as private functions
  6837. nl._wrap = nlp._wrap = tnl;
  6838. nl._adaptAsMap = adaptAsMap;
  6839. nl._adaptAsForEach = adaptAsForEach;
  6840. nl._adaptAsFilter = adaptAsFilter;
  6841. nl._adaptWithCondition = adaptWithCondition;
  6842. // mass assignment
  6843. // add array redirectors
  6844. d.forEach(["slice", "splice"], function(name){
  6845. var f = ap[name];
  6846. //Use a copy of the this array via this.slice() to allow .end() to work right in the splice case.
  6847. // CANNOT apply ._stash()/end() to splice since it currently modifies
  6848. // the existing this array -- it would break backward compatibility if we copy the array before
  6849. // the splice so that we can use .end(). So only doing the stash option to this._wrap for slice.
  6850. nlp[name] = function(){ return this._wrap(f.apply(this, arguments), name == "slice" ? this : null); };
  6851. });
  6852. // concat should be here but some browsers with native NodeList have problems with it
  6853. // add array.js redirectors
  6854. d.forEach(["indexOf", "lastIndexOf", "every", "some"], function(name){
  6855. var f = d[name];
  6856. nlp[name] = function(){ return f.apply(d, [this].concat(aps.call(arguments, 0))); };
  6857. });
  6858. // add conditional methods
  6859. d.forEach(["attr", "style"], function(name){
  6860. nlp[name] = adaptWithCondition(d[name], magicGuard);
  6861. });
  6862. // add forEach actions
  6863. d.forEach(["connect", "addClass", "removeClass", "replaceClass", "toggleClass", "empty", "removeAttr"], function(name){
  6864. nlp[name] = adaptAsForEach(d[name]);
  6865. });
  6866. dojo.extend(dojo.NodeList, {
  6867. _normalize: function(/*String||Element||Object||NodeList*/content, /*DOMNode?*/refNode){
  6868. // summary:
  6869. // normalizes data to an array of items to insert.
  6870. // description:
  6871. // If content is an object, it can have special properties "template" and
  6872. // "parse". If "template" is defined, then the template value is run through
  6873. // dojo.string.substitute (if dojo.string.substitute has been dojo.required elsewhere),
  6874. // or if templateFunc is a function on the content, that function will be used to
  6875. // transform the template into a final string to be used for for passing to dojo._toDom.
  6876. // If content.parse is true, then it is remembered for later, for when the content
  6877. // nodes are inserted into the DOM. At that point, the nodes will be parsed for widgets
  6878. // (if dojo.parser has been dojo.required elsewhere).
  6879. //Wanted to just use a DocumentFragment, but for the array/NodeList
  6880. //case that meant using cloneNode, but we may not want that.
  6881. //Cloning should only happen if the node operations span
  6882. //multiple refNodes. Also, need a real array, not a NodeList from the
  6883. //DOM since the node movements could change those NodeLists.
  6884. var parse = content.parse === true ? true : false;
  6885. //Do we have an object that needs to be run through a template?
  6886. if(typeof content.template == "string"){
  6887. var templateFunc = content.templateFunc || (dojo.string && dojo.string.substitute);
  6888. content = templateFunc ? templateFunc(content.template, content) : content;
  6889. }
  6890. var type = (typeof content);
  6891. if(type == "string" || type == "number"){
  6892. content = dojo._toDom(content, (refNode && refNode.ownerDocument));
  6893. if(content.nodeType == 11){
  6894. //DocumentFragment. It cannot handle cloneNode calls, so pull out the children.
  6895. content = dojo._toArray(content.childNodes);
  6896. }else{
  6897. content = [content];
  6898. }
  6899. }else if(!dojo.isArrayLike(content)){
  6900. content = [content];
  6901. }else if(!dojo.isArray(content)){
  6902. //To get to this point, content is array-like, but
  6903. //not an array, which likely means a DOM NodeList. Convert it now.
  6904. content = dojo._toArray(content);
  6905. }
  6906. //Pass around the parse info
  6907. if(parse){
  6908. content._runParse = true;
  6909. }
  6910. return content; //Array
  6911. },
  6912. _cloneNode: function(/*DOMNode*/ node){
  6913. // summary:
  6914. // private utility to clone a node. Not very interesting in the vanilla
  6915. // dojo.NodeList case, but delegates could do interesting things like
  6916. // clone event handlers if that is derivable from the node.
  6917. return node.cloneNode(true);
  6918. },
  6919. _place: function(/*Array*/ary, /*DOMNode*/refNode, /*String*/position, /*Boolean*/useClone){
  6920. // summary:
  6921. // private utility to handle placing an array of nodes relative to another node.
  6922. // description:
  6923. // Allows for cloning the nodes in the array, and for
  6924. // optionally parsing widgets, if ary._runParse is true.
  6925. //Avoid a disallowed operation if trying to do an innerHTML on a non-element node.
  6926. if(refNode.nodeType != 1 && position == "only"){
  6927. return;
  6928. }
  6929. var rNode = refNode, tempNode;
  6930. //Always cycle backwards in case the array is really a
  6931. //DOM NodeList and the DOM operations take it out of the live collection.
  6932. var length = ary.length;
  6933. for(var i = length - 1; i >= 0; i--){
  6934. var node = (useClone ? this._cloneNode(ary[i]) : ary[i]);
  6935. //If need widget parsing, use a temp node, instead of waiting after inserting into
  6936. //real DOM because we need to start widget parsing at one node up from current node,
  6937. //which could cause some already parsed widgets to be parsed again.
  6938. if(ary._runParse && dojo.parser && dojo.parser.parse){
  6939. if(!tempNode){
  6940. tempNode = rNode.ownerDocument.createElement("div");
  6941. }
  6942. tempNode.appendChild(node);
  6943. dojo.parser.parse(tempNode);
  6944. node = tempNode.firstChild;
  6945. while(tempNode.firstChild){
  6946. tempNode.removeChild(tempNode.firstChild);
  6947. }
  6948. }
  6949. if(i == length - 1){
  6950. dojo.place(node, rNode, position);
  6951. }else{
  6952. rNode.parentNode.insertBefore(node, rNode);
  6953. }
  6954. rNode = node;
  6955. }
  6956. },
  6957. _stash: function(parent){
  6958. // summary:
  6959. // private function to hold to a parent NodeList. end() to return the parent NodeList.
  6960. //
  6961. // example:
  6962. // How to make a `dojo.NodeList` method that only returns the third node in
  6963. // the dojo.NodeList but allows access to the original NodeList by using this._stash:
  6964. // | dojo.extend(dojo.NodeList, {
  6965. // | third: function(){
  6966. // | var newNodeList = dojo.NodeList(this[2]);
  6967. // | return newNodeList._stash(this);
  6968. // | }
  6969. // | });
  6970. // | // then see how _stash applies a sub-list, to be .end()'ed out of
  6971. // | dojo.query(".foo")
  6972. // | .third()
  6973. // | .addClass("thirdFoo")
  6974. // | .end()
  6975. // | // access to the orig .foo list
  6976. // | .removeClass("foo")
  6977. // |
  6978. //
  6979. this._parent = parent;
  6980. return this; //dojo.NodeList
  6981. },
  6982. end: function(){
  6983. // summary:
  6984. // Ends use of the current `dojo.NodeList` by returning the previous dojo.NodeList
  6985. // that generated the current dojo.NodeList.
  6986. // description:
  6987. // Returns the `dojo.NodeList` that generated the current `dojo.NodeList`. If there
  6988. // is no parent dojo.NodeList, an empty dojo.NodeList is returned.
  6989. // example:
  6990. // | dojo.query("a")
  6991. // | .filter(".disabled")
  6992. // | // operate on the anchors that only have a disabled class
  6993. // | .style("color", "grey")
  6994. // | .end()
  6995. // | // jump back to the list of anchors
  6996. // | .style(...)
  6997. //
  6998. if(this._parent){
  6999. return this._parent;
  7000. }else{
  7001. //Just return empty list.
  7002. return new this._NodeListCtor();
  7003. }
  7004. },
  7005. // http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array#Methods
  7006. // FIXME: handle return values for #3244
  7007. // http://trac.dojotoolkit.org/ticket/3244
  7008. // FIXME:
  7009. // need to wrap or implement:
  7010. // join (perhaps w/ innerHTML/outerHTML overload for toString() of items?)
  7011. // reduce
  7012. // reduceRight
  7013. /*=====
  7014. slice: function(begin, end){
  7015. // summary:
  7016. // Returns a new NodeList, maintaining this one in place
  7017. // description:
  7018. // This method behaves exactly like the Array.slice method
  7019. // with the caveat that it returns a dojo.NodeList and not a
  7020. // raw Array. For more details, see Mozilla's (slice
  7021. // documentation)[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:slice]
  7022. // begin: Integer
  7023. // Can be a positive or negative integer, with positive
  7024. // integers noting the offset to begin at, and negative
  7025. // integers denoting an offset from the end (i.e., to the left
  7026. // of the end)
  7027. // end: Integer?
  7028. // Optional parameter to describe what position relative to
  7029. // the NodeList's zero index to end the slice at. Like begin,
  7030. // can be positive or negative.
  7031. return this._wrap(a.slice.apply(this, arguments));
  7032. },
  7033. splice: function(index, howmany, item){
  7034. // summary:
  7035. // Returns a new NodeList, manipulating this NodeList based on
  7036. // the arguments passed, potentially splicing in new elements
  7037. // at an offset, optionally deleting elements
  7038. // description:
  7039. // This method behaves exactly like the Array.splice method
  7040. // with the caveat that it returns a dojo.NodeList and not a
  7041. // raw Array. For more details, see Mozilla's (splice
  7042. // documentation)[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:splice]
  7043. // For backwards compatibility, calling .end() on the spliced NodeList
  7044. // does not return the original NodeList -- splice alters the NodeList in place.
  7045. // index: Integer
  7046. // begin can be a positive or negative integer, with positive
  7047. // integers noting the offset to begin at, and negative
  7048. // integers denoting an offset from the end (i.e., to the left
  7049. // of the end)
  7050. // howmany: Integer?
  7051. // Optional parameter to describe what position relative to
  7052. // the NodeList's zero index to end the slice at. Like begin,
  7053. // can be positive or negative.
  7054. // item: Object...?
  7055. // Any number of optional parameters may be passed in to be
  7056. // spliced into the NodeList
  7057. // returns:
  7058. // dojo.NodeList
  7059. return this._wrap(a.splice.apply(this, arguments));
  7060. },
  7061. indexOf: function(value, fromIndex){
  7062. // summary:
  7063. // see dojo.indexOf(). The primary difference is that the acted-on
  7064. // array is implicitly this NodeList
  7065. // value: Object:
  7066. // The value to search for.
  7067. // fromIndex: Integer?:
  7068. // The location to start searching from. Optional. Defaults to 0.
  7069. // description:
  7070. // For more details on the behavior of indexOf, see Mozilla's
  7071. // (indexOf
  7072. // docs)[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf]
  7073. // returns:
  7074. // Positive Integer or 0 for a match, -1 of not found.
  7075. return d.indexOf(this, value, fromIndex); // Integer
  7076. },
  7077. lastIndexOf: function(value, fromIndex){
  7078. // summary:
  7079. // see dojo.lastIndexOf(). The primary difference is that the
  7080. // acted-on array is implicitly this NodeList
  7081. // description:
  7082. // For more details on the behavior of lastIndexOf, see
  7083. // Mozilla's (lastIndexOf
  7084. // docs)[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:lastIndexOf]
  7085. // value: Object
  7086. // The value to search for.
  7087. // fromIndex: Integer?
  7088. // The location to start searching from. Optional. Defaults to 0.
  7089. // returns:
  7090. // Positive Integer or 0 for a match, -1 of not found.
  7091. return d.lastIndexOf(this, value, fromIndex); // Integer
  7092. },
  7093. every: function(callback, thisObject){
  7094. // summary:
  7095. // see `dojo.every()` and the (Array.every
  7096. // docs)[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:every].
  7097. // Takes the same structure of arguments and returns as
  7098. // dojo.every() with the caveat that the passed array is
  7099. // implicitly this NodeList
  7100. // callback: Function: the callback
  7101. // thisObject: Object?: the context
  7102. return d.every(this, callback, thisObject); // Boolean
  7103. },
  7104. some: function(callback, thisObject){
  7105. // summary:
  7106. // Takes the same structure of arguments and returns as
  7107. // `dojo.some()` with the caveat that the passed array is
  7108. // implicitly this NodeList. See `dojo.some()` and Mozilla's
  7109. // (Array.some
  7110. // documentation)[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:some].
  7111. // callback: Function: the callback
  7112. // thisObject: Object?: the context
  7113. return d.some(this, callback, thisObject); // Boolean
  7114. },
  7115. =====*/
  7116. concat: function(item){
  7117. // summary:
  7118. // Returns a new NodeList comprised of items in this NodeList
  7119. // as well as items passed in as parameters
  7120. // description:
  7121. // This method behaves exactly like the Array.concat method
  7122. // with the caveat that it returns a `dojo.NodeList` and not a
  7123. // raw Array. For more details, see the (Array.concat
  7124. // docs)[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:concat]
  7125. // item: Object?
  7126. // Any number of optional parameters may be passed in to be
  7127. // spliced into the NodeList
  7128. // returns:
  7129. // dojo.NodeList
  7130. //return this._wrap(apc.apply(this, arguments));
  7131. // the line above won't work for the native NodeList :-(
  7132. // implementation notes:
  7133. // 1) Native NodeList is not an array, and cannot be used directly
  7134. // in concat() --- the latter doesn't recognize it as an array, and
  7135. // does not inline it, but append as a single entity.
  7136. // 2) On some browsers (e.g., Safari) the "constructor" property is
  7137. // read-only and cannot be changed. So we have to test for both
  7138. // native NodeList and dojo.NodeList in this property to recognize
  7139. // the node list.
  7140. var t = d.isArray(this) ? this : aps.call(this, 0),
  7141. m = d.map(arguments, function(a){
  7142. return a && !d.isArray(a) &&
  7143. (typeof NodeList != "undefined" && a.constructor === NodeList || a.constructor === this._NodeListCtor) ?
  7144. aps.call(a, 0) : a;
  7145. });
  7146. return this._wrap(apc.apply(t, m), this); // dojo.NodeList
  7147. },
  7148. map: function(/*Function*/ func, /*Function?*/ obj){
  7149. // summary:
  7150. // see dojo.map(). The primary difference is that the acted-on
  7151. // array is implicitly this NodeList and the return is a
  7152. // dojo.NodeList (a subclass of Array)
  7153. ///return d.map(this, func, obj, d.NodeList); // dojo.NodeList
  7154. return this._wrap(d.map(this, func, obj), this); // dojo.NodeList
  7155. },
  7156. forEach: function(callback, thisObj){
  7157. // summary:
  7158. // see `dojo.forEach()`. The primary difference is that the acted-on
  7159. // array is implicitly this NodeList. If you want the option to break out
  7160. // of the forEach loop, use every() or some() instead.
  7161. d.forEach(this, callback, thisObj);
  7162. // non-standard return to allow easier chaining
  7163. return this; // dojo.NodeList
  7164. },
  7165. /*=====
  7166. coords: function(){
  7167. // summary:
  7168. // Returns the box objects of all elements in a node list as
  7169. // an Array (*not* a NodeList). Acts like `dojo.coords`, though assumes
  7170. // the node passed is each node in this list.
  7171. return d.map(this, d.coords); // Array
  7172. },
  7173. position: function(){
  7174. // summary:
  7175. // Returns border-box objects (x/y/w/h) of all elements in a node list
  7176. // as an Array (*not* a NodeList). Acts like `dojo.position`, though
  7177. // assumes the node passed is each node in this list.
  7178. return d.map(this, d.position); // Array
  7179. },
  7180. attr: function(property, value){
  7181. // summary:
  7182. // gets or sets the DOM attribute for every element in the
  7183. // NodeList. See also `dojo.attr`
  7184. // property: String
  7185. // the attribute to get/set
  7186. // value: String?
  7187. // optional. The value to set the property to
  7188. // returns:
  7189. // if no value is passed, the result is an array of attribute values
  7190. // If a value is passed, the return is this NodeList
  7191. // example:
  7192. // Make all nodes with a particular class focusable:
  7193. // | dojo.query(".focusable").attr("tabIndex", -1);
  7194. // example:
  7195. // Disable a group of buttons:
  7196. // | dojo.query("button.group").attr("disabled", true);
  7197. // example:
  7198. // innerHTML can be assigned or retrieved as well:
  7199. // | // get the innerHTML (as an array) for each list item
  7200. // | var ih = dojo.query("li.replaceable").attr("innerHTML");
  7201. return; // dojo.NodeList
  7202. return; // Array
  7203. },
  7204. style: function(property, value){
  7205. // summary:
  7206. // gets or sets the CSS property for every element in the NodeList
  7207. // property: String
  7208. // the CSS property to get/set, in JavaScript notation
  7209. // ("lineHieght" instead of "line-height")
  7210. // value: String?
  7211. // optional. The value to set the property to
  7212. // returns:
  7213. // if no value is passed, the result is an array of strings.
  7214. // If a value is passed, the return is this NodeList
  7215. return; // dojo.NodeList
  7216. return; // Array
  7217. },
  7218. addClass: function(className){
  7219. // summary:
  7220. // adds the specified class to every node in the list
  7221. // className: String|Array
  7222. // A String class name to add, or several space-separated class names,
  7223. // or an array of class names.
  7224. return; // dojo.NodeList
  7225. },
  7226. removeClass: function(className){
  7227. // summary:
  7228. // removes the specified class from every node in the list
  7229. // className: String|Array?
  7230. // An optional String class name to remove, or several space-separated
  7231. // class names, or an array of class names. If omitted, all class names
  7232. // will be deleted.
  7233. // returns:
  7234. // dojo.NodeList, this list
  7235. return; // dojo.NodeList
  7236. },
  7237. toggleClass: function(className, condition){
  7238. // summary:
  7239. // Adds a class to node if not present, or removes if present.
  7240. // Pass a boolean condition if you want to explicitly add or remove.
  7241. // condition: Boolean?
  7242. // If passed, true means to add the class, false means to remove.
  7243. // className: String
  7244. // the CSS class to add
  7245. return; // dojo.NodeList
  7246. },
  7247. connect: function(methodName, objOrFunc, funcName){
  7248. // summary:
  7249. // attach event handlers to every item of the NodeList. Uses dojo.connect()
  7250. // so event properties are normalized
  7251. // methodName: String
  7252. // the name of the method to attach to. For DOM events, this should be
  7253. // the lower-case name of the event
  7254. // objOrFunc: Object|Function|String
  7255. // if 2 arguments are passed (methodName, objOrFunc), objOrFunc should
  7256. // reference a function or be the name of the function in the global
  7257. // namespace to attach. If 3 arguments are provided
  7258. // (methodName, objOrFunc, funcName), objOrFunc must be the scope to
  7259. // locate the bound function in
  7260. // funcName: String?
  7261. // optional. A string naming the function in objOrFunc to bind to the
  7262. // event. May also be a function reference.
  7263. // example:
  7264. // add an onclick handler to every button on the page
  7265. // | dojo.query("div:nth-child(odd)").connect("onclick", function(e){
  7266. // | console.log("clicked!");
  7267. // | });
  7268. // example:
  7269. // attach foo.bar() to every odd div's onmouseover
  7270. // | dojo.query("div:nth-child(odd)").connect("onmouseover", foo, "bar");
  7271. },
  7272. empty: function(){
  7273. // summary:
  7274. // clears all content from each node in the list. Effectively
  7275. // equivalent to removing all child nodes from every item in
  7276. // the list.
  7277. return this.forEach("item.innerHTML='';"); // dojo.NodeList
  7278. // FIXME: should we be checking for and/or disposing of widgets below these nodes?
  7279. },
  7280. =====*/
  7281. // useful html methods
  7282. coords: adaptAsMap(d.coords),
  7283. position: adaptAsMap(d.position),
  7284. // FIXME: connectPublisher()? connectRunOnce()?
  7285. /*
  7286. destroy: function(){
  7287. // summary:
  7288. // destroys every item in the list.
  7289. this.forEach(d.destroy);
  7290. // FIXME: should we be checking for and/or disposing of widgets below these nodes?
  7291. },
  7292. */
  7293. place: function(/*String||Node*/ queryOrNode, /*String*/ position){
  7294. // summary:
  7295. // places elements of this node list relative to the first element matched
  7296. // by queryOrNode. Returns the original NodeList. See: `dojo.place`
  7297. // queryOrNode:
  7298. // may be a string representing any valid CSS3 selector or a DOM node.
  7299. // In the selector case, only the first matching element will be used
  7300. // for relative positioning.
  7301. // position:
  7302. // can be one of:
  7303. // | "last" (default)
  7304. // | "first"
  7305. // | "before"
  7306. // | "after"
  7307. // | "only"
  7308. // | "replace"
  7309. // or an offset in the childNodes property
  7310. var item = d.query(queryOrNode)[0];
  7311. return this.forEach(function(node){ d.place(node, item, position); }); // dojo.NodeList
  7312. },
  7313. orphan: function(/*String?*/ filter){
  7314. // summary:
  7315. // removes elements in this list that match the filter
  7316. // from their parents and returns them as a new NodeList.
  7317. // filter:
  7318. // CSS selector like ".foo" or "div > span"
  7319. // returns:
  7320. // `dojo.NodeList` containing the orphaned elements
  7321. return (filter ? d._filterQueryResult(this, filter) : this).forEach(orphan); // dojo.NodeList
  7322. },
  7323. adopt: function(/*String||Array||DomNode*/ queryOrListOrNode, /*String?*/ position){
  7324. // summary:
  7325. // places any/all elements in queryOrListOrNode at a
  7326. // position relative to the first element in this list.
  7327. // Returns a dojo.NodeList of the adopted elements.
  7328. // queryOrListOrNode:
  7329. // a DOM node or a query string or a query result.
  7330. // Represents the nodes to be adopted relative to the
  7331. // first element of this NodeList.
  7332. // position:
  7333. // can be one of:
  7334. // | "last" (default)
  7335. // | "first"
  7336. // | "before"
  7337. // | "after"
  7338. // | "only"
  7339. // | "replace"
  7340. // or an offset in the childNodes property
  7341. return d.query(queryOrListOrNode).place(this[0], position)._stash(this); // dojo.NodeList
  7342. },
  7343. // FIXME: do we need this?
  7344. query: function(/*String*/ queryStr){
  7345. // summary:
  7346. // Returns a new list whose members match the passed query,
  7347. // assuming elements of the current NodeList as the root for
  7348. // each search.
  7349. // example:
  7350. // assume a DOM created by this markup:
  7351. // | <div id="foo">
  7352. // | <p>
  7353. // | bacon is tasty, <span>dontcha think?</span>
  7354. // | </p>
  7355. // | </div>
  7356. // | <div id="bar">
  7357. // | <p>great comedians may not be funny <span>in person</span></p>
  7358. // | </div>
  7359. // If we are presented with the following definition for a NodeList:
  7360. // | var l = new dojo.NodeList(dojo.byId("foo"), dojo.byId("bar"));
  7361. // it's possible to find all span elements under paragraphs
  7362. // contained by these elements with this sub-query:
  7363. // | var spans = l.query("p span");
  7364. // FIXME: probably slow
  7365. if(!queryStr){ return this; }
  7366. var ret = this.map(function(node){
  7367. // FIXME: why would we ever get undefined here?
  7368. return d.query(queryStr, node).filter(function(subNode){ return subNode !== undefined; });
  7369. });
  7370. return this._wrap(apc.apply([], ret), this); // dojo.NodeList
  7371. },
  7372. filter: function(/*String|Function*/ filter){
  7373. // summary:
  7374. // "masks" the built-in javascript filter() method (supported
  7375. // in Dojo via `dojo.filter`) to support passing a simple
  7376. // string filter in addition to supporting filtering function
  7377. // objects.
  7378. // filter:
  7379. // If a string, a CSS rule like ".thinger" or "div > span".
  7380. // example:
  7381. // "regular" JS filter syntax as exposed in dojo.filter:
  7382. // | dojo.query("*").filter(function(item){
  7383. // | // highlight every paragraph
  7384. // | return (item.nodeName == "p");
  7385. // | }).style("backgroundColor", "yellow");
  7386. // example:
  7387. // the same filtering using a CSS selector
  7388. // | dojo.query("*").filter("p").styles("backgroundColor", "yellow");
  7389. var a = arguments, items = this, start = 0;
  7390. if(typeof filter == "string"){ // inline'd type check
  7391. items = d._filterQueryResult(this, a[0]);
  7392. if(a.length == 1){
  7393. // if we only got a string query, pass back the filtered results
  7394. return items._stash(this); // dojo.NodeList
  7395. }
  7396. // if we got a callback, run it over the filtered items
  7397. start = 1;
  7398. }
  7399. return this._wrap(d.filter(items, a[start], a[start + 1]), this); // dojo.NodeList
  7400. },
  7401. /*
  7402. // FIXME: should this be "copyTo" and include parenting info?
  7403. clone: function(){
  7404. // summary:
  7405. // creates node clones of each element of this list
  7406. // and returns a new list containing the clones
  7407. },
  7408. */
  7409. addContent: function(/*String||DomNode||Object||dojo.NodeList*/ content, /*String||Integer?*/ position){
  7410. // summary:
  7411. // add a node, NodeList or some HTML as a string to every item in the
  7412. // list. Returns the original list.
  7413. // description:
  7414. // a copy of the HTML content is added to each item in the
  7415. // list, with an optional position argument. If no position
  7416. // argument is provided, the content is appended to the end of
  7417. // each item.
  7418. // content:
  7419. // DOM node, HTML in string format, a NodeList or an Object. If a DOM node or
  7420. // NodeList, the content will be cloned if the current NodeList has more than one
  7421. // element. Only the DOM nodes are cloned, no event handlers. If it is an Object,
  7422. // it should be an object with at "template" String property that has the HTML string
  7423. // to insert. If dojo.string has already been dojo.required, then dojo.string.substitute
  7424. // will be used on the "template" to generate the final HTML string. Other allowed
  7425. // properties on the object are: "parse" if the HTML
  7426. // string should be parsed for widgets (dojo.require("dojo.parser") to get that
  7427. // option to work), and "templateFunc" if a template function besides dojo.string.substitute
  7428. // should be used to transform the "template".
  7429. // position:
  7430. // can be one of:
  7431. // | "last"||"end" (default)
  7432. // | "first||"start"
  7433. // | "before"
  7434. // | "after"
  7435. // | "replace" (replaces nodes in this NodeList with new content)
  7436. // | "only" (removes other children of the nodes so new content is the only child)
  7437. // or an offset in the childNodes property
  7438. // example:
  7439. // appends content to the end if the position is omitted
  7440. // | dojo.query("h3 > p").addContent("hey there!");
  7441. // example:
  7442. // add something to the front of each element that has a
  7443. // "thinger" property:
  7444. // | dojo.query("[thinger]").addContent("...", "first");
  7445. // example:
  7446. // adds a header before each element of the list
  7447. // | dojo.query(".note").addContent("<h4>NOTE:</h4>", "before");
  7448. // example:
  7449. // add a clone of a DOM node to the end of every element in
  7450. // the list, removing it from its existing parent.
  7451. // | dojo.query(".note").addContent(dojo.byId("foo"));
  7452. // example:
  7453. // Append nodes from a templatized string.
  7454. // dojo.require("dojo.string");
  7455. // dojo.query(".note").addContent({
  7456. // template: '<b>${id}: </b><span>${name}</span>',
  7457. // id: "user332",
  7458. // name: "Mr. Anderson"
  7459. // });
  7460. // example:
  7461. // Append nodes from a templatized string that also has widgets parsed.
  7462. // dojo.require("dojo.string");
  7463. // dojo.require("dojo.parser");
  7464. // var notes = dojo.query(".note").addContent({
  7465. // template: '<button dojoType="dijit.form.Button">${text}</button>',
  7466. // parse: true,
  7467. // text: "Send"
  7468. // });
  7469. content = this._normalize(content, this[0]);
  7470. for(var i = 0, node; (node = this[i]); i++){
  7471. this._place(content, node, position, i > 0);
  7472. }
  7473. return this; //dojo.NodeList
  7474. },
  7475. instantiate: function(/*String|Object*/ declaredClass, /*Object?*/ properties){
  7476. // summary:
  7477. // Create a new instance of a specified class, using the
  7478. // specified properties and each node in the nodeList as a
  7479. // srcNodeRef.
  7480. // example:
  7481. // Grabs all buttons in the page and converts them to diji.form.Buttons.
  7482. // | var buttons = dojo.query("button").instantiate("dijit.form.Button", {showLabel: true});
  7483. var c = d.isFunction(declaredClass) ? declaredClass : d.getObject(declaredClass);
  7484. properties = properties || {};
  7485. return this.forEach(function(node){
  7486. new c(properties, node);
  7487. }); // dojo.NodeList
  7488. },
  7489. at: function(/*===== index =====*/){
  7490. // summary:
  7491. // Returns a new NodeList comprised of items in this NodeList
  7492. // at the given index or indices.
  7493. //
  7494. // index: Integer...
  7495. // One or more 0-based indices of items in the current
  7496. // NodeList. A negative index will start at the end of the
  7497. // list and go backwards.
  7498. //
  7499. // example:
  7500. // Shorten the list to the first, second, and third elements
  7501. // | dojo.query("a").at(0, 1, 2).forEach(fn);
  7502. //
  7503. // example:
  7504. // Retrieve the first and last elements of a unordered list:
  7505. // | dojo.query("ul > li").at(0, -1).forEach(cb);
  7506. //
  7507. // example:
  7508. // Do something for the first element only, but end() out back to
  7509. // the original list and continue chaining:
  7510. // | dojo.query("a").at(0).onclick(fn).end().forEach(function(n){
  7511. // | console.log(n); // all anchors on the page.
  7512. // | })
  7513. //
  7514. // returns:
  7515. // dojo.NodeList
  7516. var t = new this._NodeListCtor();
  7517. d.forEach(arguments, function(i){
  7518. if(i < 0){ i = this.length + i }
  7519. if(this[i]){ t.push(this[i]); }
  7520. }, this);
  7521. return t._stash(this); // dojo.NodeList
  7522. }
  7523. });
  7524. nl.events = [
  7525. // summary:
  7526. // list of all DOM events used in NodeList
  7527. "blur", "focus", "change", "click", "error", "keydown", "keypress",
  7528. "keyup", "load", "mousedown", "mouseenter", "mouseleave", "mousemove",
  7529. "mouseout", "mouseover", "mouseup", "submit"
  7530. ];
  7531. // FIXME: pseudo-doc the above automatically generated on-event functions
  7532. // syntactic sugar for DOM events
  7533. d.forEach(nl.events, function(evt){
  7534. var _oe = "on" + evt;
  7535. nlp[_oe] = function(a, b){
  7536. return this.connect(_oe, a, b);
  7537. };
  7538. // FIXME: should these events trigger publishes?
  7539. /*
  7540. return (a ? this.connect(_oe, a, b) :
  7541. this.forEach(function(n){
  7542. // FIXME:
  7543. // listeners get buried by
  7544. // addEventListener and can't be dug back
  7545. // out to be triggered externally.
  7546. // see:
  7547. // http://developer.mozilla.org/en/docs/DOM:element
  7548. console.log(n, evt, _oe);
  7549. // FIXME: need synthetic event support!
  7550. var _e = { target: n, faux: true, type: evt };
  7551. // dojo._event_listener._synthesizeEvent({}, { target: n, faux: true, type: evt });
  7552. try{ n[evt](_e); }catch(e){ console.log(e); }
  7553. try{ n[_oe](_e); }catch(e){ console.log(e); }
  7554. })
  7555. );
  7556. */
  7557. }
  7558. );
  7559. })();
  7560. }
  7561. if(!dojo._hasResource["dojo._base.query"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7562. dojo._hasResource["dojo._base.query"] = true;
  7563. (function(){
  7564. /*
  7565. dojo.query() architectural overview:
  7566. dojo.query is a relatively full-featured CSS3 query library. It is
  7567. designed to take any valid CSS3 selector and return the nodes matching
  7568. the selector. To do this quickly, it processes queries in several
  7569. steps, applying caching where profitable.
  7570. The steps (roughly in reverse order of the way they appear in the code):
  7571. 1.) check to see if we already have a "query dispatcher"
  7572. - if so, use that with the given parameterization. Skip to step 4.
  7573. 2.) attempt to determine which branch to dispatch the query to:
  7574. - JS (optimized DOM iteration)
  7575. - native (FF3.1+, Safari 3.1+, IE 8+)
  7576. 3.) tokenize and convert to executable "query dispatcher"
  7577. - this is where the lion's share of the complexity in the
  7578. system lies. In the DOM version, the query dispatcher is
  7579. assembled as a chain of "yes/no" test functions pertaining to
  7580. a section of a simple query statement (".blah:nth-child(odd)"
  7581. but not "div div", which is 2 simple statements). Individual
  7582. statement dispatchers are cached (to prevent re-definition)
  7583. as are entire dispatch chains (to make re-execution of the
  7584. same query fast)
  7585. 4.) the resulting query dispatcher is called in the passed scope
  7586. (by default the top-level document)
  7587. - for DOM queries, this results in a recursive, top-down
  7588. evaluation of nodes based on each simple query section
  7589. - for native implementations, this may mean working around spec
  7590. bugs. So be it.
  7591. 5.) matched nodes are pruned to ensure they are unique (if necessary)
  7592. */
  7593. var defineQuery= function(d){
  7594. // define everything in a closure for compressability reasons. "d" is an
  7595. // alias to "dojo" (or the toolkit alias object, e.g., "acme").
  7596. ////////////////////////////////////////////////////////////////////////
  7597. // Toolkit aliases
  7598. ////////////////////////////////////////////////////////////////////////
  7599. // if you are extracting dojo.query for use in your own system, you will
  7600. // need to provide these methods and properties. No other porting should be
  7601. // necessary, save for configuring the system to use a class other than
  7602. // dojo.NodeList as the return instance instantiator
  7603. var trim = d.trim;
  7604. var each = d.forEach;
  7605. // d.isIE; // float
  7606. // d.isSafari; // float
  7607. // d.isOpera; // float
  7608. // d.isWebKit; // float
  7609. // d.doc ; // document element
  7610. var qlc = (d._NodeListCtor = d.NodeList);
  7611. var getDoc = function(){ return d.doc; };
  7612. // NOTE(alex): the spec is idiotic. CSS queries should ALWAYS be case-sensitive, but nooooooo
  7613. var cssCaseBug = (getDoc().compatMode) == "BackCompat";
  7614. ////////////////////////////////////////////////////////////////////////
  7615. // Global utilities
  7616. ////////////////////////////////////////////////////////////////////////
  7617. var specials = ">~+";
  7618. // global thunk to determine whether we should treat the current query as
  7619. // case sensitive or not. This switch is flipped by the query evaluator
  7620. // based on the document passed as the context to search.
  7621. var caseSensitive = false;
  7622. // how high?
  7623. var yesman = function(){ return true; };
  7624. ////////////////////////////////////////////////////////////////////////
  7625. // Tokenizer
  7626. ////////////////////////////////////////////////////////////////////////
  7627. var getQueryParts = function(query){
  7628. // summary:
  7629. // state machine for query tokenization
  7630. // description:
  7631. // instead of using a brittle and slow regex-based CSS parser,
  7632. // dojo.query implements an AST-style query representation. This
  7633. // representation is only generated once per query. For example,
  7634. // the same query run multiple times or under different root nodes
  7635. // does not re-parse the selector expression but instead uses the
  7636. // cached data structure. The state machine implemented here
  7637. // terminates on the last " " (space) character and returns an
  7638. // ordered array of query component structures (or "parts"). Each
  7639. // part represents an operator or a simple CSS filtering
  7640. // expression. The structure for parts is documented in the code
  7641. // below.
  7642. // NOTE:
  7643. // this code is designed to run fast and compress well. Sacrifices
  7644. // to readability and maintainability have been made. Your best
  7645. // bet when hacking the tokenizer is to put The Donnas on *really*
  7646. // loud (may we recommend their "Spend The Night" release?) and
  7647. // just assume you're gonna make mistakes. Keep the unit tests
  7648. // open and run them frequently. Knowing is half the battle ;-)
  7649. if(specials.indexOf(query.slice(-1)) >= 0){
  7650. // if we end with a ">", "+", or "~", that means we're implicitly
  7651. // searching all children, so make it explicit
  7652. query += " * "
  7653. }else{
  7654. // if you have not provided a terminator, one will be provided for
  7655. // you...
  7656. query += " ";
  7657. }
  7658. var ts = function(/*Integer*/ s, /*Integer*/ e){
  7659. // trim and slice.
  7660. // take an index to start a string slice from and an end position
  7661. // and return a trimmed copy of that sub-string
  7662. return trim(query.slice(s, e));
  7663. }
  7664. // the overall data graph of the full query, as represented by queryPart objects
  7665. var queryParts = [];
  7666. // state keeping vars
  7667. var inBrackets = -1, inParens = -1, inMatchFor = -1,
  7668. inPseudo = -1, inClass = -1, inId = -1, inTag = -1,
  7669. lc = "", cc = "", pStart;
  7670. // iteration vars
  7671. var x = 0, // index in the query
  7672. ql = query.length,
  7673. currentPart = null, // data structure representing the entire clause
  7674. _cp = null; // the current pseudo or attr matcher
  7675. // several temporary variables are assigned to this structure during a
  7676. // potential sub-expression match:
  7677. // attr:
  7678. // a string representing the current full attribute match in a
  7679. // bracket expression
  7680. // type:
  7681. // if there's an operator in a bracket expression, this is
  7682. // used to keep track of it
  7683. // value:
  7684. // the internals of parenthetical expression for a pseudo. for
  7685. // :nth-child(2n+1), value might be "2n+1"
  7686. var endTag = function(){
  7687. // called when the tokenizer hits the end of a particular tag name.
  7688. // Re-sets state variables for tag matching and sets up the matcher
  7689. // to handle the next type of token (tag or operator).
  7690. if(inTag >= 0){
  7691. var tv = (inTag == x) ? null : ts(inTag, x); // .toLowerCase();
  7692. currentPart[ (specials.indexOf(tv) < 0) ? "tag" : "oper" ] = tv;
  7693. inTag = -1;
  7694. }
  7695. }
  7696. var endId = function(){
  7697. // called when the tokenizer might be at the end of an ID portion of a match
  7698. if(inId >= 0){
  7699. currentPart.id = ts(inId, x).replace(/\\/g, "");
  7700. inId = -1;
  7701. }
  7702. }
  7703. var endClass = function(){
  7704. // called when the tokenizer might be at the end of a class name
  7705. // match. CSS allows for multiple classes, so we augment the
  7706. // current item with another class in its list
  7707. if(inClass >= 0){
  7708. currentPart.classes.push(ts(inClass+1, x).replace(/\\/g, ""));
  7709. inClass = -1;
  7710. }
  7711. }
  7712. var endAll = function(){
  7713. // at the end of a simple fragment, so wall off the matches
  7714. endId(); endTag(); endClass();
  7715. }
  7716. var endPart = function(){
  7717. endAll();
  7718. if(inPseudo >= 0){
  7719. currentPart.pseudos.push({ name: ts(inPseudo+1, x) });
  7720. }
  7721. // hint to the selector engine to tell it whether or not it
  7722. // needs to do any iteration. Many simple selectors don't, and
  7723. // we can avoid significant construction-time work by advising
  7724. // the system to skip them
  7725. currentPart.loops = (
  7726. currentPart.pseudos.length ||
  7727. currentPart.attrs.length ||
  7728. currentPart.classes.length );
  7729. currentPart.oquery = currentPart.query = ts(pStart, x); // save the full expression as a string
  7730. // otag/tag are hints to suggest to the system whether or not
  7731. // it's an operator or a tag. We save a copy of otag since the
  7732. // tag name is cast to upper-case in regular HTML matches. The
  7733. // system has a global switch to figure out if the current
  7734. // expression needs to be case sensitive or not and it will use
  7735. // otag or tag accordingly
  7736. currentPart.otag = currentPart.tag = (currentPart["oper"]) ? null : (currentPart.tag || "*");
  7737. if(currentPart.tag){
  7738. // if we're in a case-insensitive HTML doc, we likely want
  7739. // the toUpperCase when matching on element.tagName. If we
  7740. // do it here, we can skip the string op per node
  7741. // comparison
  7742. currentPart.tag = currentPart.tag.toUpperCase();
  7743. }
  7744. // add the part to the list
  7745. if(queryParts.length && (queryParts[queryParts.length-1].oper)){
  7746. // operators are always infix, so we remove them from the
  7747. // list and attach them to the next match. The evaluator is
  7748. // responsible for sorting out how to handle them.
  7749. currentPart.infixOper = queryParts.pop();
  7750. currentPart.query = currentPart.infixOper.query + " " + currentPart.query;
  7751. /*
  7752. console.debug( "swapping out the infix",
  7753. currentPart.infixOper,
  7754. "and attaching it to",
  7755. currentPart);
  7756. */
  7757. }
  7758. queryParts.push(currentPart);
  7759. currentPart = null;
  7760. }
  7761. // iterate over the query, character by character, building up a
  7762. // list of query part objects
  7763. for(; lc=cc, cc=query.charAt(x), x < ql; x++){
  7764. // cc: the current character in the match
  7765. // lc: the last character (if any)
  7766. // someone is trying to escape something, so don't try to match any
  7767. // fragments. We assume we're inside a literal.
  7768. if(lc == "\\"){ continue; }
  7769. if(!currentPart){ // a part was just ended or none has yet been created
  7770. // NOTE: I hate all this alloc, but it's shorter than writing tons of if's
  7771. pStart = x;
  7772. // rules describe full CSS sub-expressions, like:
  7773. // #someId
  7774. // .className:first-child
  7775. // but not:
  7776. // thinger > div.howdy[type=thinger]
  7777. // the indidual components of the previous query would be
  7778. // split into 3 parts that would be represented a structure
  7779. // like:
  7780. // [
  7781. // {
  7782. // query: "thinger",
  7783. // tag: "thinger",
  7784. // },
  7785. // {
  7786. // query: "div.howdy[type=thinger]",
  7787. // classes: ["howdy"],
  7788. // infixOper: {
  7789. // query: ">",
  7790. // oper: ">",
  7791. // }
  7792. // },
  7793. // ]
  7794. currentPart = {
  7795. query: null, // the full text of the part's rule
  7796. pseudos: [], // CSS supports multiple pseud-class matches in a single rule
  7797. attrs: [], // CSS supports multi-attribute match, so we need an array
  7798. classes: [], // class matches may be additive, e.g.: .thinger.blah.howdy
  7799. tag: null, // only one tag...
  7800. oper: null, // ...or operator per component. Note that these wind up being exclusive.
  7801. id: null, // the id component of a rule
  7802. getTag: function(){
  7803. return (caseSensitive) ? this.otag : this.tag;
  7804. }
  7805. };
  7806. // if we don't have a part, we assume we're going to start at
  7807. // the beginning of a match, which should be a tag name. This
  7808. // might fault a little later on, but we detect that and this
  7809. // iteration will still be fine.
  7810. inTag = x;
  7811. }
  7812. if(inBrackets >= 0){
  7813. // look for a the close first
  7814. if(cc == "]"){ // if we're in a [...] clause and we end, do assignment
  7815. if(!_cp.attr){
  7816. // no attribute match was previously begun, so we
  7817. // assume this is an attribute existence match in the
  7818. // form of [someAttributeName]
  7819. _cp.attr = ts(inBrackets+1, x);
  7820. }else{
  7821. // we had an attribute already, so we know that we're
  7822. // matching some sort of value, as in [attrName=howdy]
  7823. _cp.matchFor = ts((inMatchFor||inBrackets+1), x);
  7824. }
  7825. var cmf = _cp.matchFor;
  7826. if(cmf){
  7827. // try to strip quotes from the matchFor value. We want
  7828. // [attrName=howdy] to match the same
  7829. // as [attrName = 'howdy' ]
  7830. if( (cmf.charAt(0) == '"') || (cmf.charAt(0) == "'") ){
  7831. _cp.matchFor = cmf.slice(1, -1);
  7832. }
  7833. }
  7834. // end the attribute by adding it to the list of attributes.
  7835. currentPart.attrs.push(_cp);
  7836. _cp = null; // necessary?
  7837. inBrackets = inMatchFor = -1;
  7838. }else if(cc == "="){
  7839. // if the last char was an operator prefix, make sure we
  7840. // record it along with the "=" operator.
  7841. var addToCc = ("|~^$*".indexOf(lc) >=0 ) ? lc : "";
  7842. _cp.type = addToCc+cc;
  7843. _cp.attr = ts(inBrackets+1, x-addToCc.length);
  7844. inMatchFor = x+1;
  7845. }
  7846. // now look for other clause parts
  7847. }else if(inParens >= 0){
  7848. // if we're in a parenthetical expression, we need to figure
  7849. // out if it's attached to a pseudo-selector rule like
  7850. // :nth-child(1)
  7851. if(cc == ")"){
  7852. if(inPseudo >= 0){
  7853. _cp.value = ts(inParens+1, x);
  7854. }
  7855. inPseudo = inParens = -1;
  7856. }
  7857. }else if(cc == "#"){
  7858. // start of an ID match
  7859. endAll();
  7860. inId = x+1;
  7861. }else if(cc == "."){
  7862. // start of a class match
  7863. endAll();
  7864. inClass = x;
  7865. }else if(cc == ":"){
  7866. // start of a pseudo-selector match
  7867. endAll();
  7868. inPseudo = x;
  7869. }else if(cc == "["){
  7870. // start of an attribute match.
  7871. endAll();
  7872. inBrackets = x;
  7873. // provide a new structure for the attribute match to fill-in
  7874. _cp = {
  7875. /*=====
  7876. attr: null, type: null, matchFor: null
  7877. =====*/
  7878. };
  7879. }else if(cc == "("){
  7880. // we really only care if we've entered a parenthetical
  7881. // expression if we're already inside a pseudo-selector match
  7882. if(inPseudo >= 0){
  7883. // provide a new structure for the pseudo match to fill-in
  7884. _cp = {
  7885. name: ts(inPseudo+1, x),
  7886. value: null
  7887. }
  7888. currentPart.pseudos.push(_cp);
  7889. }
  7890. inParens = x;
  7891. }else if(
  7892. (cc == " ") &&
  7893. // if it's a space char and the last char is too, consume the
  7894. // current one without doing more work
  7895. (lc != cc)
  7896. ){
  7897. endPart();
  7898. }
  7899. }
  7900. return queryParts;
  7901. };
  7902. ////////////////////////////////////////////////////////////////////////
  7903. // DOM query infrastructure
  7904. ////////////////////////////////////////////////////////////////////////
  7905. var agree = function(first, second){
  7906. // the basic building block of the yes/no chaining system. agree(f1,
  7907. // f2) generates a new function which returns the boolean results of
  7908. // both of the passed functions to a single logical-anded result. If
  7909. // either are not passed, the other is used exclusively.
  7910. if(!first){ return second; }
  7911. if(!second){ return first; }
  7912. return function(){
  7913. return first.apply(window, arguments) && second.apply(window, arguments);
  7914. }
  7915. };
  7916. var getArr = function(i, arr){
  7917. // helps us avoid array alloc when we don't need it
  7918. var r = arr||[]; // FIXME: should this be 'new d._NodeListCtor()' ?
  7919. if(i){ r.push(i); }
  7920. return r;
  7921. };
  7922. var _isElement = function(n){ return (1 == n.nodeType); };
  7923. // FIXME: need to coalesce _getAttr with defaultGetter
  7924. var blank = "";
  7925. var _getAttr = function(elem, attr){
  7926. if(!elem){ return blank; }
  7927. if(attr == "class"){
  7928. return elem.className || blank;
  7929. }
  7930. if(attr == "for"){
  7931. return elem.htmlFor || blank;
  7932. }
  7933. if(attr == "style"){
  7934. return elem.style.cssText || blank;
  7935. }
  7936. return (caseSensitive ? elem.getAttribute(attr) : elem.getAttribute(attr, 2)) || blank;
  7937. };
  7938. var attrs = {
  7939. "*=": function(attr, value){
  7940. return function(elem){
  7941. // E[foo*="bar"]
  7942. // an E element whose "foo" attribute value contains
  7943. // the substring "bar"
  7944. return (_getAttr(elem, attr).indexOf(value)>=0);
  7945. }
  7946. },
  7947. "^=": function(attr, value){
  7948. // E[foo^="bar"]
  7949. // an E element whose "foo" attribute value begins exactly
  7950. // with the string "bar"
  7951. return function(elem){
  7952. return (_getAttr(elem, attr).indexOf(value)==0);
  7953. }
  7954. },
  7955. "$=": function(attr, value){
  7956. // E[foo$="bar"]
  7957. // an E element whose "foo" attribute value ends exactly
  7958. // with the string "bar"
  7959. var tval = " "+value;
  7960. return function(elem){
  7961. var ea = " "+_getAttr(elem, attr);
  7962. return (ea.lastIndexOf(value)==(ea.length-value.length));
  7963. }
  7964. },
  7965. "~=": function(attr, value){
  7966. // E[foo~="bar"]
  7967. // an E element whose "foo" attribute value is a list of
  7968. // space-separated values, one of which is exactly equal
  7969. // to "bar"
  7970. // return "[contains(concat(' ',@"+attr+",' '), ' "+ value +" ')]";
  7971. var tval = " "+value+" ";
  7972. return function(elem){
  7973. var ea = " "+_getAttr(elem, attr)+" ";
  7974. return (ea.indexOf(tval)>=0);
  7975. }
  7976. },
  7977. "|=": function(attr, value){
  7978. // E[hreflang|="en"]
  7979. // an E element whose "hreflang" attribute has a
  7980. // hyphen-separated list of values beginning (from the
  7981. // left) with "en"
  7982. var valueDash = " "+value+"-";
  7983. return function(elem){
  7984. var ea = " "+_getAttr(elem, attr);
  7985. return (
  7986. (ea == value) ||
  7987. (ea.indexOf(valueDash)==0)
  7988. );
  7989. }
  7990. },
  7991. "=": function(attr, value){
  7992. return function(elem){
  7993. return (_getAttr(elem, attr) == value);
  7994. }
  7995. }
  7996. };
  7997. // avoid testing for node type if we can. Defining this in the negative
  7998. // here to avoid negation in the fast path.
  7999. var _noNES = (typeof getDoc().firstChild.nextElementSibling == "undefined");
  8000. var _ns = !_noNES ? "nextElementSibling" : "nextSibling";
  8001. var _ps = !_noNES ? "previousElementSibling" : "previousSibling";
  8002. var _simpleNodeTest = (_noNES ? _isElement : yesman);
  8003. var _lookLeft = function(node){
  8004. // look left
  8005. while(node = node[_ps]){
  8006. if(_simpleNodeTest(node)){ return false; }
  8007. }
  8008. return true;
  8009. };
  8010. var _lookRight = function(node){
  8011. // look right
  8012. while(node = node[_ns]){
  8013. if(_simpleNodeTest(node)){ return false; }
  8014. }
  8015. return true;
  8016. };
  8017. var getNodeIndex = function(node){
  8018. var root = node.parentNode;
  8019. var i = 0,
  8020. tret = root.children || root.childNodes,
  8021. ci = (node["_i"]||-1),
  8022. cl = (root["_l"]||-1);
  8023. if(!tret){ return -1; }
  8024. var l = tret.length;
  8025. // we calculate the parent length as a cheap way to invalidate the
  8026. // cache. It's not 100% accurate, but it's much more honest than what
  8027. // other libraries do
  8028. if( cl == l && ci >= 0 && cl >= 0 ){
  8029. // if it's legit, tag and release
  8030. return ci;
  8031. }
  8032. // else re-key things
  8033. root["_l"] = l;
  8034. ci = -1;
  8035. for(var te = root["firstElementChild"]||root["firstChild"]; te; te = te[_ns]){
  8036. if(_simpleNodeTest(te)){
  8037. te["_i"] = ++i;
  8038. if(node === te){
  8039. // NOTE:
  8040. // shortcutting the return at this step in indexing works
  8041. // very well for benchmarking but we avoid it here since
  8042. // it leads to potential O(n^2) behavior in sequential
  8043. // getNodexIndex operations on a previously un-indexed
  8044. // parent. We may revisit this at a later time, but for
  8045. // now we just want to get the right answer more often
  8046. // than not.
  8047. ci = i;
  8048. }
  8049. }
  8050. }
  8051. return ci;
  8052. };
  8053. var isEven = function(elem){
  8054. return !((getNodeIndex(elem)) % 2);
  8055. };
  8056. var isOdd = function(elem){
  8057. return ((getNodeIndex(elem)) % 2);
  8058. };
  8059. var pseudos = {
  8060. "checked": function(name, condition){
  8061. return function(elem){
  8062. return !!("checked" in elem ? elem.checked : elem.selected);
  8063. }
  8064. },
  8065. "first-child": function(){ return _lookLeft; },
  8066. "last-child": function(){ return _lookRight; },
  8067. "only-child": function(name, condition){
  8068. return function(node){
  8069. if(!_lookLeft(node)){ return false; }
  8070. if(!_lookRight(node)){ return false; }
  8071. return true;
  8072. };
  8073. },
  8074. "empty": function(name, condition){
  8075. return function(elem){
  8076. // DomQuery and jQuery get this wrong, oddly enough.
  8077. // The CSS 3 selectors spec is pretty explicit about it, too.
  8078. var cn = elem.childNodes;
  8079. var cnl = elem.childNodes.length;
  8080. // if(!cnl){ return true; }
  8081. for(var x=cnl-1; x >= 0; x--){
  8082. var nt = cn[x].nodeType;
  8083. if((nt === 1)||(nt == 3)){ return false; }
  8084. }
  8085. return true;
  8086. }
  8087. },
  8088. "contains": function(name, condition){
  8089. var cz = condition.charAt(0);
  8090. if( cz == '"' || cz == "'" ){ //remove quote
  8091. condition = condition.slice(1, -1);
  8092. }
  8093. return function(elem){
  8094. return (elem.innerHTML.indexOf(condition) >= 0);
  8095. }
  8096. },
  8097. "not": function(name, condition){
  8098. var p = getQueryParts(condition)[0];
  8099. var ignores = { el: 1 };
  8100. if(p.tag != "*"){
  8101. ignores.tag = 1;
  8102. }
  8103. if(!p.classes.length){
  8104. ignores.classes = 1;
  8105. }
  8106. var ntf = getSimpleFilterFunc(p, ignores);
  8107. return function(elem){
  8108. return (!ntf(elem));
  8109. }
  8110. },
  8111. "nth-child": function(name, condition){
  8112. var pi = parseInt;
  8113. // avoid re-defining function objects if we can
  8114. if(condition == "odd"){
  8115. return isOdd;
  8116. }else if(condition == "even"){
  8117. return isEven;
  8118. }
  8119. // FIXME: can we shorten this?
  8120. if(condition.indexOf("n") != -1){
  8121. var tparts = condition.split("n", 2);
  8122. var pred = tparts[0] ? ((tparts[0] == '-') ? -1 : pi(tparts[0])) : 1;
  8123. var idx = tparts[1] ? pi(tparts[1]) : 0;
  8124. var lb = 0, ub = -1;
  8125. if(pred > 0){
  8126. if(idx < 0){
  8127. idx = (idx % pred) && (pred + (idx % pred));
  8128. }else if(idx>0){
  8129. if(idx >= pred){
  8130. lb = idx - idx % pred;
  8131. }
  8132. idx = idx % pred;
  8133. }
  8134. }else if(pred<0){
  8135. pred *= -1;
  8136. // idx has to be greater than 0 when pred is negative;
  8137. // shall we throw an error here?
  8138. if(idx > 0){
  8139. ub = idx;
  8140. idx = idx % pred;
  8141. }
  8142. }
  8143. if(pred > 0){
  8144. return function(elem){
  8145. var i = getNodeIndex(elem);
  8146. return (i>=lb) && (ub<0 || i<=ub) && ((i % pred) == idx);
  8147. }
  8148. }else{
  8149. condition = idx;
  8150. }
  8151. }
  8152. var ncount = pi(condition);
  8153. return function(elem){
  8154. return (getNodeIndex(elem) == ncount);
  8155. }
  8156. }
  8157. };
  8158. var defaultGetter = (d.isIE < 9 || d.isIE == 9 && d.isQuirks) ? function(cond){
  8159. var clc = cond.toLowerCase();
  8160. if(clc == "class"){ cond = "className"; }
  8161. return function(elem){
  8162. return (caseSensitive ? elem.getAttribute(cond) : elem[cond]||elem[clc]);
  8163. }
  8164. } : function(cond){
  8165. return function(elem){
  8166. return (elem && elem.getAttribute && elem.hasAttribute(cond));
  8167. }
  8168. };
  8169. var getSimpleFilterFunc = function(query, ignores){
  8170. // generates a node tester function based on the passed query part. The
  8171. // query part is one of the structures generated by the query parser
  8172. // when it creates the query AST. The "ignores" object specifies which
  8173. // (if any) tests to skip, allowing the system to avoid duplicating
  8174. // work where it may have already been taken into account by other
  8175. // factors such as how the nodes to test were fetched in the first
  8176. // place
  8177. if(!query){ return yesman; }
  8178. ignores = ignores||{};
  8179. var ff = null;
  8180. if(!("el" in ignores)){
  8181. ff = agree(ff, _isElement);
  8182. }
  8183. if(!("tag" in ignores)){
  8184. if(query.tag != "*"){
  8185. ff = agree(ff, function(elem){
  8186. return (elem && (elem.tagName == query.getTag()));
  8187. });
  8188. }
  8189. }
  8190. if(!("classes" in ignores)){
  8191. each(query.classes, function(cname, idx, arr){
  8192. // get the class name
  8193. /*
  8194. var isWildcard = cname.charAt(cname.length-1) == "*";
  8195. if(isWildcard){
  8196. cname = cname.substr(0, cname.length-1);
  8197. }
  8198. // I dislike the regex thing, even if memoized in a cache, but it's VERY short
  8199. var re = new RegExp("(?:^|\\s)" + cname + (isWildcard ? ".*" : "") + "(?:\\s|$)");
  8200. */
  8201. var re = new RegExp("(?:^|\\s)" + cname + "(?:\\s|$)");
  8202. ff = agree(ff, function(elem){
  8203. return re.test(elem.className);
  8204. });
  8205. ff.count = idx;
  8206. });
  8207. }
  8208. if(!("pseudos" in ignores)){
  8209. each(query.pseudos, function(pseudo){
  8210. var pn = pseudo.name;
  8211. if(pseudos[pn]){
  8212. ff = agree(ff, pseudos[pn](pn, pseudo.value));
  8213. }
  8214. });
  8215. }
  8216. if(!("attrs" in ignores)){
  8217. each(query.attrs, function(attr){
  8218. var matcher;
  8219. var a = attr.attr;
  8220. // type, attr, matchFor
  8221. if(attr.type && attrs[attr.type]){
  8222. matcher = attrs[attr.type](a, attr.matchFor);
  8223. }else if(a.length){
  8224. matcher = defaultGetter(a);
  8225. }
  8226. if(matcher){
  8227. ff = agree(ff, matcher);
  8228. }
  8229. });
  8230. }
  8231. if(!("id" in ignores)){
  8232. if(query.id){
  8233. ff = agree(ff, function(elem){
  8234. return (!!elem && (elem.id == query.id));
  8235. });
  8236. }
  8237. }
  8238. if(!ff){
  8239. if(!("default" in ignores)){
  8240. ff = yesman;
  8241. }
  8242. }
  8243. return ff;
  8244. };
  8245. var _nextSibling = function(filterFunc){
  8246. return function(node, ret, bag){
  8247. while(node = node[_ns]){
  8248. if(_noNES && (!_isElement(node))){ continue; }
  8249. if(
  8250. (!bag || _isUnique(node, bag)) &&
  8251. filterFunc(node)
  8252. ){
  8253. ret.push(node);
  8254. }
  8255. break;
  8256. }
  8257. return ret;
  8258. }
  8259. };
  8260. var _nextSiblings = function(filterFunc){
  8261. return function(root, ret, bag){
  8262. var te = root[_ns];
  8263. while(te){
  8264. if(_simpleNodeTest(te)){
  8265. if(bag && !_isUnique(te, bag)){
  8266. break;
  8267. }
  8268. if(filterFunc(te)){
  8269. ret.push(te);
  8270. }
  8271. }
  8272. te = te[_ns];
  8273. }
  8274. return ret;
  8275. }
  8276. };
  8277. // get an array of child *elements*, skipping text and comment nodes
  8278. var _childElements = function(filterFunc){
  8279. filterFunc = filterFunc||yesman;
  8280. return function(root, ret, bag){
  8281. // get an array of child elements, skipping text and comment nodes
  8282. var te, x = 0, tret = root.children || root.childNodes;
  8283. while(te = tret[x++]){
  8284. if(
  8285. _simpleNodeTest(te) &&
  8286. (!bag || _isUnique(te, bag)) &&
  8287. (filterFunc(te, x))
  8288. ){
  8289. ret.push(te);
  8290. }
  8291. }
  8292. return ret;
  8293. };
  8294. };
  8295. /*
  8296. // thanks, Dean!
  8297. var itemIsAfterRoot = d.isIE ? function(item, root){
  8298. return (item.sourceIndex > root.sourceIndex);
  8299. } : function(item, root){
  8300. return (item.compareDocumentPosition(root) == 2);
  8301. };
  8302. */
  8303. // test to see if node is below root
  8304. var _isDescendant = function(node, root){
  8305. var pn = node.parentNode;
  8306. while(pn){
  8307. if(pn == root){
  8308. break;
  8309. }
  8310. pn = pn.parentNode;
  8311. }
  8312. return !!pn;
  8313. };
  8314. var _getElementsFuncCache = {};
  8315. var getElementsFunc = function(query){
  8316. var retFunc = _getElementsFuncCache[query.query];
  8317. // if we've got a cached dispatcher, just use that
  8318. if(retFunc){ return retFunc; }
  8319. // else, generate a new on
  8320. // NOTE:
  8321. // this function returns a function that searches for nodes and
  8322. // filters them. The search may be specialized by infix operators
  8323. // (">", "~", or "+") else it will default to searching all
  8324. // descendants (the " " selector). Once a group of children is
  8325. // found, a test function is applied to weed out the ones we
  8326. // don't want. Many common cases can be fast-pathed. We spend a
  8327. // lot of cycles to create a dispatcher that doesn't do more work
  8328. // than necessary at any point since, unlike this function, the
  8329. // dispatchers will be called every time. The logic of generating
  8330. // efficient dispatchers looks like this in pseudo code:
  8331. //
  8332. // # if it's a purely descendant query (no ">", "+", or "~" modifiers)
  8333. // if infixOperator == " ":
  8334. // if only(id):
  8335. // return def(root):
  8336. // return d.byId(id, root);
  8337. //
  8338. // elif id:
  8339. // return def(root):
  8340. // return filter(d.byId(id, root));
  8341. //
  8342. // elif cssClass && getElementsByClassName:
  8343. // return def(root):
  8344. // return filter(root.getElementsByClassName(cssClass));
  8345. //
  8346. // elif only(tag):
  8347. // return def(root):
  8348. // return root.getElementsByTagName(tagName);
  8349. //
  8350. // else:
  8351. // # search by tag name, then filter
  8352. // return def(root):
  8353. // return filter(root.getElementsByTagName(tagName||"*"));
  8354. //
  8355. // elif infixOperator == ">":
  8356. // # search direct children
  8357. // return def(root):
  8358. // return filter(root.children);
  8359. //
  8360. // elif infixOperator == "+":
  8361. // # search next sibling
  8362. // return def(root):
  8363. // return filter(root.nextElementSibling);
  8364. //
  8365. // elif infixOperator == "~":
  8366. // # search rightward siblings
  8367. // return def(root):
  8368. // return filter(nextSiblings(root));
  8369. var io = query.infixOper;
  8370. var oper = (io ? io.oper : "");
  8371. // the default filter func which tests for all conditions in the query
  8372. // part. This is potentially inefficient, so some optimized paths may
  8373. // re-define it to test fewer things.
  8374. var filterFunc = getSimpleFilterFunc(query, { el: 1 });
  8375. var qt = query.tag;
  8376. var wildcardTag = ("*" == qt);
  8377. var ecs = getDoc()["getElementsByClassName"];
  8378. if(!oper){
  8379. // if there's no infix operator, then it's a descendant query. ID
  8380. // and "elements by class name" variants can be accelerated so we
  8381. // call them out explicitly:
  8382. if(query.id){
  8383. // testing shows that the overhead of yesman() is acceptable
  8384. // and can save us some bytes vs. re-defining the function
  8385. // everywhere.
  8386. filterFunc = (!query.loops && wildcardTag) ?
  8387. yesman :
  8388. getSimpleFilterFunc(query, { el: 1, id: 1 });
  8389. retFunc = function(root, arr){
  8390. var te = d.byId(query.id, (root.ownerDocument||root));
  8391. if(!te || !filterFunc(te)){ return; }
  8392. if(9 == root.nodeType){ // if root's a doc, we just return directly
  8393. return getArr(te, arr);
  8394. }else{ // otherwise check ancestry
  8395. if(_isDescendant(te, root)){
  8396. return getArr(te, arr);
  8397. }
  8398. }
  8399. }
  8400. }else if(
  8401. ecs &&
  8402. // isAlien check. Workaround for Prototype.js being totally evil/dumb.
  8403. /\{\s*\[native code\]\s*\}/.test(String(ecs)) &&
  8404. query.classes.length &&
  8405. !cssCaseBug
  8406. ){
  8407. // it's a class-based query and we've got a fast way to run it.
  8408. // ignore class and ID filters since we will have handled both
  8409. filterFunc = getSimpleFilterFunc(query, { el: 1, classes: 1, id: 1 });
  8410. var classesString = query.classes.join(" ");
  8411. retFunc = function(root, arr, bag){
  8412. var ret = getArr(0, arr), te, x=0;
  8413. var tret = root.getElementsByClassName(classesString);
  8414. while((te = tret[x++])){
  8415. if(filterFunc(te, root) && _isUnique(te, bag)){
  8416. ret.push(te);
  8417. }
  8418. }
  8419. return ret;
  8420. };
  8421. }else if(!wildcardTag && !query.loops){
  8422. // it's tag only. Fast-path it.
  8423. retFunc = function(root, arr, bag){
  8424. var ret = getArr(0, arr), te, x=0;
  8425. var tret = root.getElementsByTagName(query.getTag());
  8426. while((te = tret[x++])){
  8427. if(_isUnique(te, bag)){
  8428. ret.push(te);
  8429. }
  8430. }
  8431. return ret;
  8432. };
  8433. }else{
  8434. // the common case:
  8435. // a descendant selector without a fast path. By now it's got
  8436. // to have a tag selector, even if it's just "*" so we query
  8437. // by that and filter
  8438. filterFunc = getSimpleFilterFunc(query, { el: 1, tag: 1, id: 1 });
  8439. retFunc = function(root, arr, bag){
  8440. var ret = getArr(0, arr), te, x=0;
  8441. // we use getTag() to avoid case sensitivity issues
  8442. var tret = root.getElementsByTagName(query.getTag());
  8443. while((te = tret[x++])){
  8444. if(filterFunc(te, root) && _isUnique(te, bag)){
  8445. ret.push(te);
  8446. }
  8447. }
  8448. return ret;
  8449. };
  8450. }
  8451. }else{
  8452. // the query is scoped in some way. Instead of querying by tag we
  8453. // use some other collection to find candidate nodes
  8454. var skipFilters = { el: 1 };
  8455. if(wildcardTag){
  8456. skipFilters.tag = 1;
  8457. }
  8458. filterFunc = getSimpleFilterFunc(query, skipFilters);
  8459. if("+" == oper){
  8460. retFunc = _nextSibling(filterFunc);
  8461. }else if("~" == oper){
  8462. retFunc = _nextSiblings(filterFunc);
  8463. }else if(">" == oper){
  8464. retFunc = _childElements(filterFunc);
  8465. }
  8466. }
  8467. // cache it and return
  8468. return _getElementsFuncCache[query.query] = retFunc;
  8469. };
  8470. var filterDown = function(root, queryParts){
  8471. // NOTE:
  8472. // this is the guts of the DOM query system. It takes a list of
  8473. // parsed query parts and a root and finds children which match
  8474. // the selector represented by the parts
  8475. var candidates = getArr(root), qp, x, te, qpl = queryParts.length, bag, ret;
  8476. for(var i = 0; i < qpl; i++){
  8477. ret = [];
  8478. qp = queryParts[i];
  8479. x = candidates.length - 1;
  8480. if(x > 0){
  8481. // if we have more than one root at this level, provide a new
  8482. // hash to use for checking group membership but tell the
  8483. // system not to post-filter us since we will already have been
  8484. // gauranteed to be unique
  8485. bag = {};
  8486. ret.nozip = true;
  8487. }
  8488. var gef = getElementsFunc(qp);
  8489. for(var j = 0; (te = candidates[j]); j++){
  8490. // for every root, get the elements that match the descendant
  8491. // selector, adding them to the "ret" array and filtering them
  8492. // via membership in this level's bag. If there are more query
  8493. // parts, then this level's return will be used as the next
  8494. // level's candidates
  8495. gef(te, ret, bag);
  8496. }
  8497. if(!ret.length){ break; }
  8498. candidates = ret;
  8499. }
  8500. return ret;
  8501. };
  8502. ////////////////////////////////////////////////////////////////////////
  8503. // the query runner
  8504. ////////////////////////////////////////////////////////////////////////
  8505. // these are the primary caches for full-query results. The query
  8506. // dispatcher functions are generated then stored here for hash lookup in
  8507. // the future
  8508. var _queryFuncCacheDOM = {},
  8509. _queryFuncCacheQSA = {};
  8510. // this is the second level of spliting, from full-length queries (e.g.,
  8511. // "div.foo .bar") into simple query expressions (e.g., ["div.foo",
  8512. // ".bar"])
  8513. var getStepQueryFunc = function(query){
  8514. var qparts = getQueryParts(trim(query));
  8515. // if it's trivial, avoid iteration and zipping costs
  8516. if(qparts.length == 1){
  8517. // we optimize this case here to prevent dispatch further down the
  8518. // chain, potentially slowing things down. We could more elegantly
  8519. // handle this in filterDown(), but it's slower for simple things
  8520. // that need to be fast (e.g., "#someId").
  8521. var tef = getElementsFunc(qparts[0]);
  8522. return function(root){
  8523. var r = tef(root, new qlc());
  8524. if(r){ r.nozip = true; }
  8525. return r;
  8526. }
  8527. }
  8528. // otherwise, break it up and return a runner that iterates over the parts recursively
  8529. return function(root){
  8530. return filterDown(root, qparts);
  8531. }
  8532. };
  8533. // NOTES:
  8534. // * we can't trust QSA for anything but document-rooted queries, so
  8535. // caching is split into DOM query evaluators and QSA query evaluators
  8536. // * caching query results is dirty and leak-prone (or, at a minimum,
  8537. // prone to unbounded growth). Other toolkits may go this route, but
  8538. // they totally destroy their own ability to manage their memory
  8539. // footprint. If we implement it, it should only ever be with a fixed
  8540. // total element reference # limit and an LRU-style algorithm since JS
  8541. // has no weakref support. Caching compiled query evaluators is also
  8542. // potentially problematic, but even on large documents the size of the
  8543. // query evaluators is often < 100 function objects per evaluator (and
  8544. // LRU can be applied if it's ever shown to be an issue).
  8545. // * since IE's QSA support is currently only for HTML documents and even
  8546. // then only in IE 8's "standards mode", we have to detect our dispatch
  8547. // route at query time and keep 2 separate caches. Ugg.
  8548. // we need to determine if we think we can run a given query via
  8549. // querySelectorAll or if we'll need to fall back on DOM queries to get
  8550. // there. We need a lot of information about the environment and the query
  8551. // to make the determiniation (e.g. does it support QSA, does the query in
  8552. // question work in the native QSA impl, etc.).
  8553. var nua = navigator.userAgent;
  8554. // some versions of Safari provided QSA, but it was buggy and crash-prone.
  8555. // We need te detect the right "internal" webkit version to make this work.
  8556. var wk = "WebKit/";
  8557. var is525 = (
  8558. d.isWebKit &&
  8559. (nua.indexOf(wk) > 0) &&
  8560. (parseFloat(nua.split(wk)[1]) > 528)
  8561. );
  8562. // IE QSA queries may incorrectly include comment nodes, so we throw the
  8563. // zipping function into "remove" comments mode instead of the normal "skip
  8564. // it" which every other QSA-clued browser enjoys
  8565. var noZip = d.isIE ? "commentStrip" : "nozip";
  8566. var qsa = "querySelectorAll";
  8567. var qsaAvail = (
  8568. !!getDoc()[qsa] &&
  8569. // see #5832
  8570. (!d.isSafari || (d.isSafari > 3.1) || is525 )
  8571. );
  8572. //Don't bother with n+3 type of matches, IE complains if we modify those.
  8573. var infixSpaceRe = /n\+\d|([^ ])?([>~+])([^ =])?/g;
  8574. var infixSpaceFunc = function(match, pre, ch, post) {
  8575. return ch ? (pre ? pre + " " : "") + ch + (post ? " " + post : "") : /*n+3*/ match;
  8576. };
  8577. var getQueryFunc = function(query, forceDOM){
  8578. //Normalize query. The CSS3 selectors spec allows for omitting spaces around
  8579. //infix operators, >, ~ and +
  8580. //Do the work here since detection for spaces is used as a simple "not use QSA"
  8581. //test below.
  8582. query = query.replace(infixSpaceRe, infixSpaceFunc);
  8583. if(qsaAvail){
  8584. // if we've got a cached variant and we think we can do it, run it!
  8585. var qsaCached = _queryFuncCacheQSA[query];
  8586. if(qsaCached && !forceDOM){ return qsaCached; }
  8587. }
  8588. // else if we've got a DOM cached variant, assume that we already know
  8589. // all we need to and use it
  8590. var domCached = _queryFuncCacheDOM[query];
  8591. if(domCached){ return domCached; }
  8592. // TODO:
  8593. // today we're caching DOM and QSA branches separately so we
  8594. // recalc useQSA every time. If we had a way to tag root+query
  8595. // efficiently, we'd be in good shape to do a global cache.
  8596. var qcz = query.charAt(0);
  8597. var nospace = (-1 == query.indexOf(" "));
  8598. // byId searches are wicked fast compared to QSA, even when filtering
  8599. // is required
  8600. if( (query.indexOf("#") >= 0) && (nospace) ){
  8601. forceDOM = true;
  8602. }
  8603. var useQSA = (
  8604. qsaAvail && (!forceDOM) &&
  8605. // as per CSS 3, we can't currently start w/ combinator:
  8606. // http://www.w3.org/TR/css3-selectors/#w3cselgrammar
  8607. (specials.indexOf(qcz) == -1) &&
  8608. // IE's QSA impl sucks on pseudos
  8609. (!d.isIE || (query.indexOf(":") == -1)) &&
  8610. (!(cssCaseBug && (query.indexOf(".") >= 0))) &&
  8611. // FIXME:
  8612. // need to tighten up browser rules on ":contains" and "|=" to
  8613. // figure out which aren't good
  8614. // Latest webkit (around 531.21.8) does not seem to do well with :checked on option
  8615. // elements, even though according to spec, selected options should
  8616. // match :checked. So go nonQSA for it:
  8617. // http://bugs.dojotoolkit.org/ticket/5179
  8618. (query.indexOf(":contains") == -1) && (query.indexOf(":checked") == -1) &&
  8619. (query.indexOf("|=") == -1) // some browsers don't grok it
  8620. );
  8621. // TODO:
  8622. // if we've got a descendant query (e.g., "> .thinger" instead of
  8623. // just ".thinger") in a QSA-able doc, but are passed a child as a
  8624. // root, it should be possible to give the item a synthetic ID and
  8625. // trivially rewrite the query to the form "#synid > .thinger" to
  8626. // use the QSA branch
  8627. if(useQSA){
  8628. var tq = (specials.indexOf(query.charAt(query.length-1)) >= 0) ?
  8629. (query + " *") : query;
  8630. return _queryFuncCacheQSA[query] = function(root){
  8631. try{
  8632. // the QSA system contains an egregious spec bug which
  8633. // limits us, effectively, to only running QSA queries over
  8634. // entire documents. See:
  8635. // http://ejohn.org/blog/thoughts-on-queryselectorall/
  8636. // despite this, we can also handle QSA runs on simple
  8637. // selectors, but we don't want detection to be expensive
  8638. // so we're just checking for the presence of a space char
  8639. // right now. Not elegant, but it's cheaper than running
  8640. // the query parser when we might not need to
  8641. if(!((9 == root.nodeType) || nospace)){ throw ""; }
  8642. var r = root[qsa](tq);
  8643. // skip expensive duplication checks and just wrap in a NodeList
  8644. r[noZip] = true;
  8645. return r;
  8646. }catch(e){
  8647. // else run the DOM branch on this query, ensuring that we
  8648. // default that way in the future
  8649. return getQueryFunc(query, true)(root);
  8650. }
  8651. }
  8652. }else{
  8653. // DOM branch
  8654. var parts = query.split(/\s*,\s*/);
  8655. return _queryFuncCacheDOM[query] = ((parts.length < 2) ?
  8656. // if not a compound query (e.g., ".foo, .bar"), cache and return a dispatcher
  8657. getStepQueryFunc(query) :
  8658. // if it *is* a complex query, break it up into its
  8659. // constituent parts and return a dispatcher that will
  8660. // merge the parts when run
  8661. function(root){
  8662. var pindex = 0, // avoid array alloc for every invocation
  8663. ret = [],
  8664. tp;
  8665. while((tp = parts[pindex++])){
  8666. ret = ret.concat(getStepQueryFunc(tp)(root));
  8667. }
  8668. return ret;
  8669. }
  8670. );
  8671. }
  8672. };
  8673. var _zipIdx = 0;
  8674. // NOTE:
  8675. // this function is Moo inspired, but our own impl to deal correctly
  8676. // with XML in IE
  8677. var _nodeUID = d.isIE ? function(node){
  8678. if(caseSensitive){
  8679. // XML docs don't have uniqueID on their nodes
  8680. return (node.getAttribute("_uid") || node.setAttribute("_uid", ++_zipIdx) || _zipIdx);
  8681. }else{
  8682. return node.uniqueID;
  8683. }
  8684. } :
  8685. function(node){
  8686. return (node._uid || (node._uid = ++_zipIdx));
  8687. };
  8688. // determine if a node in is unique in a "bag". In this case we don't want
  8689. // to flatten a list of unique items, but rather just tell if the item in
  8690. // question is already in the bag. Normally we'd just use hash lookup to do
  8691. // this for us but IE's DOM is busted so we can't really count on that. On
  8692. // the upside, it gives us a built in unique ID function.
  8693. var _isUnique = function(node, bag){
  8694. if(!bag){ return 1; }
  8695. var id = _nodeUID(node);
  8696. if(!bag[id]){ return bag[id] = 1; }
  8697. return 0;
  8698. };
  8699. // attempt to efficiently determine if an item in a list is a dupe,
  8700. // returning a list of "uniques", hopefully in doucment order
  8701. var _zipIdxName = "_zipIdx";
  8702. var _zip = function(arr){
  8703. if(arr && arr.nozip){
  8704. return (qlc._wrap) ? qlc._wrap(arr) : arr;
  8705. }
  8706. // var ret = new d._NodeListCtor();
  8707. var ret = new qlc();
  8708. if(!arr || !arr.length){ return ret; }
  8709. if(arr[0]){
  8710. ret.push(arr[0]);
  8711. }
  8712. if(arr.length < 2){ return ret; }
  8713. _zipIdx++;
  8714. // we have to fork here for IE and XML docs because we can't set
  8715. // expandos on their nodes (apparently). *sigh*
  8716. if(d.isIE && caseSensitive){
  8717. var szidx = _zipIdx+"";
  8718. arr[0].setAttribute(_zipIdxName, szidx);
  8719. for(var x = 1, te; te = arr[x]; x++){
  8720. if(arr[x].getAttribute(_zipIdxName) != szidx){
  8721. ret.push(te);
  8722. }
  8723. te.setAttribute(_zipIdxName, szidx);
  8724. }
  8725. }else if(d.isIE && arr.commentStrip){
  8726. try{
  8727. for(var x = 1, te; te = arr[x]; x++){
  8728. if(_isElement(te)){
  8729. ret.push(te);
  8730. }
  8731. }
  8732. }catch(e){ /* squelch */ }
  8733. }else{
  8734. if(arr[0]){ arr[0][_zipIdxName] = _zipIdx; }
  8735. for(var x = 1, te; te = arr[x]; x++){
  8736. if(arr[x][_zipIdxName] != _zipIdx){
  8737. ret.push(te);
  8738. }
  8739. te[_zipIdxName] = _zipIdx;
  8740. }
  8741. }
  8742. return ret;
  8743. };
  8744. // the main executor
  8745. d.query = function(/*String*/ query, /*String|DOMNode?*/ root){
  8746. // summary:
  8747. // Returns nodes which match the given CSS3 selector, searching the
  8748. // entire document by default but optionally taking a node to scope
  8749. // the search by. Returns an instance of dojo.NodeList.
  8750. // description:
  8751. // dojo.query() is the swiss army knife of DOM node manipulation in
  8752. // Dojo. Much like Prototype's "$$" (bling-bling) function or JQuery's
  8753. // "$" function, dojo.query provides robust, high-performance
  8754. // CSS-based node selector support with the option of scoping searches
  8755. // to a particular sub-tree of a document.
  8756. //
  8757. // Supported Selectors:
  8758. // --------------------
  8759. //
  8760. // dojo.query() supports a rich set of CSS3 selectors, including:
  8761. //
  8762. // * class selectors (e.g., `.foo`)
  8763. // * node type selectors like `span`
  8764. // * ` ` descendant selectors
  8765. // * `>` child element selectors
  8766. // * `#foo` style ID selectors
  8767. // * `*` universal selector
  8768. // * `~`, the preceded-by sibling selector
  8769. // * `+`, the immediately preceded-by sibling selector
  8770. // * attribute queries:
  8771. // | * `[foo]` attribute presence selector
  8772. // | * `[foo='bar']` attribute value exact match
  8773. // | * `[foo~='bar']` attribute value list item match
  8774. // | * `[foo^='bar']` attribute start match
  8775. // | * `[foo$='bar']` attribute end match
  8776. // | * `[foo*='bar']` attribute substring match
  8777. // * `:first-child`, `:last-child`, and `:only-child` positional selectors
  8778. // * `:empty` content emtpy selector
  8779. // * `:checked` pseudo selector
  8780. // * `:nth-child(n)`, `:nth-child(2n+1)` style positional calculations
  8781. // * `:nth-child(even)`, `:nth-child(odd)` positional selectors
  8782. // * `:not(...)` negation pseudo selectors
  8783. //
  8784. // Any legal combination of these selectors will work with
  8785. // `dojo.query()`, including compound selectors ("," delimited).
  8786. // Very complex and useful searches can be constructed with this
  8787. // palette of selectors and when combined with functions for
  8788. // manipulation presented by dojo.NodeList, many types of DOM
  8789. // manipulation operations become very straightforward.
  8790. //
  8791. // Unsupported Selectors:
  8792. // ----------------------
  8793. //
  8794. // While dojo.query handles many CSS3 selectors, some fall outside of
  8795. // what's reasonable for a programmatic node querying engine to
  8796. // handle. Currently unsupported selectors include:
  8797. //
  8798. // * namespace-differentiated selectors of any form
  8799. // * all `::` pseduo-element selectors
  8800. // * certain pseduo-selectors which don't get a lot of day-to-day use:
  8801. // | * `:root`, `:lang()`, `:target`, `:focus`
  8802. // * all visual and state selectors:
  8803. // | * `:root`, `:active`, `:hover`, `:visisted`, `:link`,
  8804. // `:enabled`, `:disabled`
  8805. // * `:*-of-type` pseudo selectors
  8806. //
  8807. // dojo.query and XML Documents:
  8808. // -----------------------------
  8809. //
  8810. // `dojo.query` (as of dojo 1.2) supports searching XML documents
  8811. // in a case-sensitive manner. If an HTML document is served with
  8812. // a doctype that forces case-sensitivity (e.g., XHTML 1.1
  8813. // Strict), dojo.query() will detect this and "do the right
  8814. // thing". Case sensitivity is dependent upon the document being
  8815. // searched and not the query used. It is therefore possible to
  8816. // use case-sensitive queries on strict sub-documents (iframes,
  8817. // etc.) or XML documents while still assuming case-insensitivity
  8818. // for a host/root document.
  8819. //
  8820. // Non-selector Queries:
  8821. // ---------------------
  8822. //
  8823. // If something other than a String is passed for the query,
  8824. // `dojo.query` will return a new `dojo.NodeList` instance
  8825. // constructed from that parameter alone and all further
  8826. // processing will stop. This means that if you have a reference
  8827. // to a node or NodeList, you can quickly construct a new NodeList
  8828. // from the original by calling `dojo.query(node)` or
  8829. // `dojo.query(list)`.
  8830. //
  8831. // query:
  8832. // The CSS3 expression to match against. For details on the syntax of
  8833. // CSS3 selectors, see <http://www.w3.org/TR/css3-selectors/#selectors>
  8834. // root:
  8835. // A DOMNode (or node id) to scope the search from. Optional.
  8836. // returns: dojo.NodeList
  8837. // An instance of `dojo.NodeList`. Many methods are available on
  8838. // NodeLists for searching, iterating, manipulating, and handling
  8839. // events on the matched nodes in the returned list.
  8840. // example:
  8841. // search the entire document for elements with the class "foo":
  8842. // | dojo.query(".foo");
  8843. // these elements will match:
  8844. // | <span class="foo"></span>
  8845. // | <span class="foo bar"></span>
  8846. // | <p class="thud foo"></p>
  8847. // example:
  8848. // search the entire document for elements with the classes "foo" *and* "bar":
  8849. // | dojo.query(".foo.bar");
  8850. // these elements will match:
  8851. // | <span class="foo bar"></span>
  8852. // while these will not:
  8853. // | <span class="foo"></span>
  8854. // | <p class="thud foo"></p>
  8855. // example:
  8856. // find `<span>` elements which are descendants of paragraphs and
  8857. // which have a "highlighted" class:
  8858. // | dojo.query("p span.highlighted");
  8859. // the innermost span in this fragment matches:
  8860. // | <p class="foo">
  8861. // | <span>...
  8862. // | <span class="highlighted foo bar">...</span>
  8863. // | </span>
  8864. // | </p>
  8865. // example:
  8866. // set an "odd" class on all odd table rows inside of the table
  8867. // `#tabular_data`, using the `>` (direct child) selector to avoid
  8868. // affecting any nested tables:
  8869. // | dojo.query("#tabular_data > tbody > tr:nth-child(odd)").addClass("odd");
  8870. // example:
  8871. // remove all elements with the class "error" from the document
  8872. // and store them in a list:
  8873. // | var errors = dojo.query(".error").orphan();
  8874. // example:
  8875. // add an onclick handler to every submit button in the document
  8876. // which causes the form to be sent via Ajax instead:
  8877. // | dojo.query("input[type='submit']").onclick(function(e){
  8878. // | dojo.stopEvent(e); // prevent sending the form
  8879. // | var btn = e.target;
  8880. // | dojo.xhrPost({
  8881. // | form: btn.form,
  8882. // | load: function(data){
  8883. // | // replace the form with the response
  8884. // | var div = dojo.doc.createElement("div");
  8885. // | dojo.place(div, btn.form, "after");
  8886. // | div.innerHTML = data;
  8887. // | dojo.style(btn.form, "display", "none");
  8888. // | }
  8889. // | });
  8890. // | });
  8891. //Set list constructor to desired value. This can change
  8892. //between calls, so always re-assign here.
  8893. qlc = d._NodeListCtor;
  8894. if(!query){
  8895. return new qlc();
  8896. }
  8897. if(query.constructor == qlc){
  8898. return query;
  8899. }
  8900. if(typeof query != "string"){ // inline'd type check
  8901. return new qlc(query); // dojo.NodeList
  8902. }
  8903. if(typeof root == "string"){ // inline'd type check
  8904. root = d.byId(root);
  8905. if(!root){ return new qlc(); }
  8906. }
  8907. root = root||getDoc();
  8908. var od = root.ownerDocument||root.documentElement;
  8909. // throw the big case sensitivity switch
  8910. // NOTE:
  8911. // Opera in XHTML mode doesn't detect case-sensitivity correctly
  8912. // and it's not clear that there's any way to test for it
  8913. caseSensitive = (root.contentType && root.contentType=="application/xml") ||
  8914. (d.isOpera && (root.doctype || od.toString() == "[object XMLDocument]")) ||
  8915. (!!od) &&
  8916. (d.isIE ? od.xml : (root.xmlVersion||od.xmlVersion));
  8917. // NOTE:
  8918. // adding "true" as the 2nd argument to getQueryFunc is useful for
  8919. // testing the DOM branch without worrying about the
  8920. // behavior/performance of the QSA branch.
  8921. var r = getQueryFunc(query)(root);
  8922. // FIXME:
  8923. // need to investigate this branch WRT #8074 and #8075
  8924. if(r && r.nozip && !qlc._wrap){
  8925. return r;
  8926. }
  8927. return _zip(r); // dojo.NodeList
  8928. }
  8929. // FIXME: need to add infrastructure for post-filtering pseudos, ala :last
  8930. d.query.pseudos = pseudos;
  8931. // function for filtering a NodeList based on a selector, optimized for simple selectors
  8932. d._filterQueryResult = function(/*NodeList*/ nodeList, /*String*/ filter, /*String|DOMNode?*/ root){
  8933. var tmpNodeList = new d._NodeListCtor(),
  8934. parts = getQueryParts(filter),
  8935. filterFunc =
  8936. (parts.length == 1 && !/[^\w#\.]/.test(filter)) ?
  8937. getSimpleFilterFunc(parts[0]) :
  8938. function(node) {
  8939. return dojo.query(filter, root).indexOf(node) != -1;
  8940. };
  8941. for(var x = 0, te; te = nodeList[x]; x++){
  8942. if(filterFunc(te)){ tmpNodeList.push(te); }
  8943. }
  8944. return tmpNodeList;
  8945. }
  8946. };//end defineQuery
  8947. var defineAcme= function(){
  8948. // a self-sufficient query impl
  8949. acme = {
  8950. trim: function(/*String*/ str){
  8951. // summary:
  8952. // trims whitespaces from both sides of the string
  8953. str = str.replace(/^\s+/, '');
  8954. for(var i = str.length - 1; i >= 0; i--){
  8955. if(/\S/.test(str.charAt(i))){
  8956. str = str.substring(0, i + 1);
  8957. break;
  8958. }
  8959. }
  8960. return str; // String
  8961. },
  8962. forEach: function(/*String*/ arr, /*Function*/ callback, /*Object?*/ thisObject){
  8963. // summary:
  8964. // an iterator function that passes items, indexes,
  8965. // and the array to a callback
  8966. if(!arr || !arr.length){ return; }
  8967. for(var i=0,l=arr.length; i<l; ++i){
  8968. callback.call(thisObject||window, arr[i], i, arr);
  8969. }
  8970. },
  8971. byId: function(id, doc){
  8972. // summary:
  8973. // a function that return an element by ID, but also
  8974. // accepts nodes safely
  8975. if(typeof id == "string"){
  8976. return (doc||document).getElementById(id); // DomNode
  8977. }else{
  8978. return id; // DomNode
  8979. }
  8980. },
  8981. // the default document to search
  8982. doc: document,
  8983. // the constructor for node list objects returned from query()
  8984. NodeList: Array
  8985. };
  8986. // define acme.isIE, acme.isSafari, acme.isOpera, etc.
  8987. var n = navigator;
  8988. var dua = n.userAgent;
  8989. var dav = n.appVersion;
  8990. var tv = parseFloat(dav);
  8991. acme.isOpera = (dua.indexOf("Opera") >= 0) ? tv: undefined;
  8992. acme.isKhtml = (dav.indexOf("Konqueror") >= 0) ? tv : undefined;
  8993. acme.isWebKit = parseFloat(dua.split("WebKit/")[1]) || undefined;
  8994. acme.isChrome = parseFloat(dua.split("Chrome/")[1]) || undefined;
  8995. var index = Math.max(dav.indexOf("WebKit"), dav.indexOf("Safari"), 0);
  8996. if(index && !acme.isChrome){
  8997. acme.isSafari = parseFloat(dav.split("Version/")[1]);
  8998. if(!acme.isSafari || parseFloat(dav.substr(index + 7)) <= 419.3){
  8999. acme.isSafari = 2;
  9000. }
  9001. }
  9002. if(document.all && !acme.isOpera){
  9003. acme.isIE = parseFloat(dav.split("MSIE ")[1]) || undefined;
  9004. }
  9005. Array._wrap = function(arr){ return arr; };
  9006. return acme;
  9007. };
  9008. //prefers queryPortability, then acme, then dojo
  9009. if(this["dojo"]){
  9010. dojo.provide("dojo._base.query");
  9011. defineQuery(this["queryPortability"]||this["acme"]||dojo);
  9012. }else{
  9013. defineQuery(this["queryPortability"]||this["acme"]||defineAcme());
  9014. }
  9015. })();
  9016. /*
  9017. */
  9018. }
  9019. if(!dojo._hasResource["dojo._base.xhr"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  9020. dojo._hasResource["dojo._base.xhr"] = true;
  9021. dojo.provide("dojo._base.xhr");
  9022. (function(){
  9023. var _d = dojo, cfg = _d.config;
  9024. function setValue(/*Object*/obj, /*String*/name, /*String*/value){
  9025. //summary:
  9026. // For the named property in object, set the value. If a value
  9027. // already exists and it is a string, convert the value to be an
  9028. // array of values.
  9029. //Skip it if there is no value
  9030. if(value === null){
  9031. return;
  9032. }
  9033. var val = obj[name];
  9034. if(typeof val == "string"){ // inline'd type check
  9035. obj[name] = [val, value];
  9036. }else if(_d.isArray(val)){
  9037. val.push(value);
  9038. }else{
  9039. obj[name] = value;
  9040. }
  9041. }
  9042. dojo.fieldToObject = function(/*DOMNode||String*/ inputNode){
  9043. // summary:
  9044. // Serialize a form field to a JavaScript object.
  9045. //
  9046. // description:
  9047. // Returns the value encoded in a form field as
  9048. // as a string or an array of strings. Disabled form elements
  9049. // and unchecked radio and checkboxes are skipped. Multi-select
  9050. // elements are returned as an array of string values.
  9051. var ret = null;
  9052. var item = _d.byId(inputNode);
  9053. if(item){
  9054. var _in = item.name;
  9055. var type = (item.type||"").toLowerCase();
  9056. if(_in && type && !item.disabled){
  9057. if(type == "radio" || type == "checkbox"){
  9058. if(item.checked){ ret = item.value; }
  9059. }else if(item.multiple){
  9060. ret = [];
  9061. _d.query("option", item).forEach(function(opt){
  9062. if(opt.selected){
  9063. ret.push(opt.value);
  9064. }
  9065. });
  9066. }else{
  9067. ret = item.value;
  9068. }
  9069. }
  9070. }
  9071. return ret; // Object
  9072. };
  9073. dojo.formToObject = function(/*DOMNode||String*/ formNode){
  9074. // summary:
  9075. // Serialize a form node to a JavaScript object.
  9076. // description:
  9077. // Returns the values encoded in an HTML form as
  9078. // string properties in an object which it then returns. Disabled form
  9079. // elements, buttons, and other non-value form elements are skipped.
  9080. // Multi-select elements are returned as an array of string values.
  9081. //
  9082. // example:
  9083. // This form:
  9084. // | <form id="test_form">
  9085. // | <input type="text" name="blah" value="blah">
  9086. // | <input type="text" name="no_value" value="blah" disabled>
  9087. // | <input type="button" name="no_value2" value="blah">
  9088. // | <select type="select" multiple name="multi" size="5">
  9089. // | <option value="blah">blah</option>
  9090. // | <option value="thud" selected>thud</option>
  9091. // | <option value="thonk" selected>thonk</option>
  9092. // | </select>
  9093. // | </form>
  9094. //
  9095. // yields this object structure as the result of a call to
  9096. // formToObject():
  9097. //
  9098. // | {
  9099. // | blah: "blah",
  9100. // | multi: [
  9101. // | "thud",
  9102. // | "thonk"
  9103. // | ]
  9104. // | };
  9105. var ret = {};
  9106. var exclude = "file|submit|image|reset|button|";
  9107. _d.forEach(dojo.byId(formNode).elements, function(item){
  9108. var _in = item.name;
  9109. var type = (item.type||"").toLowerCase();
  9110. if(_in && type && exclude.indexOf(type) == -1 && !item.disabled){
  9111. setValue(ret, _in, _d.fieldToObject(item));
  9112. if(type == "image"){
  9113. ret[_in+".x"] = ret[_in+".y"] = ret[_in].x = ret[_in].y = 0;
  9114. }
  9115. }
  9116. });
  9117. return ret; // Object
  9118. };
  9119. dojo.objectToQuery = function(/*Object*/ map){
  9120. // summary:
  9121. // takes a name/value mapping object and returns a string representing
  9122. // a URL-encoded version of that object.
  9123. // example:
  9124. // this object:
  9125. //
  9126. // | {
  9127. // | blah: "blah",
  9128. // | multi: [
  9129. // | "thud",
  9130. // | "thonk"
  9131. // | ]
  9132. // | };
  9133. //
  9134. // yields the following query string:
  9135. //
  9136. // | "blah=blah&multi=thud&multi=thonk"
  9137. // FIXME: need to implement encodeAscii!!
  9138. var enc = encodeURIComponent;
  9139. var pairs = [];
  9140. var backstop = {};
  9141. for(var name in map){
  9142. var value = map[name];
  9143. if(value != backstop[name]){
  9144. var assign = enc(name) + "=";
  9145. if(_d.isArray(value)){
  9146. for(var i=0; i < value.length; i++){
  9147. pairs.push(assign + enc(value[i]));
  9148. }
  9149. }else{
  9150. pairs.push(assign + enc(value));
  9151. }
  9152. }
  9153. }
  9154. return pairs.join("&"); // String
  9155. };
  9156. dojo.formToQuery = function(/*DOMNode||String*/ formNode){
  9157. // summary:
  9158. // Returns a URL-encoded string representing the form passed as either a
  9159. // node or string ID identifying the form to serialize
  9160. return _d.objectToQuery(_d.formToObject(formNode)); // String
  9161. };
  9162. dojo.formToJson = function(/*DOMNode||String*/ formNode, /*Boolean?*/prettyPrint){
  9163. // summary:
  9164. // Create a serialized JSON string from a form node or string
  9165. // ID identifying the form to serialize
  9166. return _d.toJson(_d.formToObject(formNode), prettyPrint); // String
  9167. };
  9168. dojo.queryToObject = function(/*String*/ str){
  9169. // summary:
  9170. // Create an object representing a de-serialized query section of a
  9171. // URL. Query keys with multiple values are returned in an array.
  9172. //
  9173. // example:
  9174. // This string:
  9175. //
  9176. // | "foo=bar&foo=baz&thinger=%20spaces%20=blah&zonk=blarg&"
  9177. //
  9178. // results in this object structure:
  9179. //
  9180. // | {
  9181. // | foo: [ "bar", "baz" ],
  9182. // | thinger: " spaces =blah",
  9183. // | zonk: "blarg"
  9184. // | }
  9185. //
  9186. // Note that spaces and other urlencoded entities are correctly
  9187. // handled.
  9188. // FIXME: should we grab the URL string if we're not passed one?
  9189. var ret = {};
  9190. var qp = str.split("&");
  9191. var dec = decodeURIComponent;
  9192. _d.forEach(qp, function(item){
  9193. if(item.length){
  9194. var parts = item.split("=");
  9195. var name = dec(parts.shift());
  9196. var val = dec(parts.join("="));
  9197. if(typeof ret[name] == "string"){ // inline'd type check
  9198. ret[name] = [ret[name]];
  9199. }
  9200. if(_d.isArray(ret[name])){
  9201. ret[name].push(val);
  9202. }else{
  9203. ret[name] = val;
  9204. }
  9205. }
  9206. });
  9207. return ret; // Object
  9208. };
  9209. // need to block async callbacks from snatching this thread as the result
  9210. // of an async callback might call another sync XHR, this hangs khtml forever
  9211. // must checked by watchInFlight()
  9212. dojo._blockAsync = false;
  9213. // MOW: remove dojo._contentHandlers alias in 2.0
  9214. var handlers = _d._contentHandlers = dojo.contentHandlers = {
  9215. // summary:
  9216. // A map of availble XHR transport handle types. Name matches the
  9217. // `handleAs` attribute passed to XHR calls.
  9218. //
  9219. // description:
  9220. // A map of availble XHR transport handle types. Name matches the
  9221. // `handleAs` attribute passed to XHR calls. Each contentHandler is
  9222. // called, passing the xhr object for manipulation. The return value
  9223. // from the contentHandler will be passed to the `load` or `handle`
  9224. // functions defined in the original xhr call.
  9225. //
  9226. // example:
  9227. // Creating a custom content-handler:
  9228. // | dojo.contentHandlers.makeCaps = function(xhr){
  9229. // | return xhr.responseText.toUpperCase();
  9230. // | }
  9231. // | // and later:
  9232. // | dojo.xhrGet({
  9233. // | url:"foo.txt",
  9234. // | handleAs:"makeCaps",
  9235. // | load: function(data){ /* data is a toUpper version of foo.txt */ }
  9236. // | });
  9237. text: function(xhr){
  9238. // summary: A contentHandler which simply returns the plaintext response data
  9239. return xhr.responseText;
  9240. },
  9241. json: function(xhr){
  9242. // summary: A contentHandler which returns a JavaScript object created from the response data
  9243. return _d.fromJson(xhr.responseText || null);
  9244. },
  9245. "json-comment-filtered": function(xhr){
  9246. // summary: A contentHandler which expects comment-filtered JSON.
  9247. // description:
  9248. // A contentHandler which expects comment-filtered JSON.
  9249. // the json-comment-filtered option was implemented to prevent
  9250. // "JavaScript Hijacking", but it is less secure than standard JSON. Use
  9251. // standard JSON instead. JSON prefixing can be used to subvert hijacking.
  9252. //
  9253. // Will throw a notice suggesting to use application/json mimetype, as
  9254. // json-commenting can introduce security issues. To decrease the chances of hijacking,
  9255. // use the standard `json` contentHandler, and prefix your "JSON" with: {}&&
  9256. //
  9257. // use djConfig.useCommentedJson = true to turn off the notice
  9258. if(!dojo.config.useCommentedJson){
  9259. console.warn("Consider using the standard mimetype:application/json."
  9260. + " json-commenting can introduce security issues. To"
  9261. + " decrease the chances of hijacking, use the standard the 'json' handler and"
  9262. + " prefix your json with: {}&&\n"
  9263. + "Use djConfig.useCommentedJson=true to turn off this message.");
  9264. }
  9265. var value = xhr.responseText;
  9266. var cStartIdx = value.indexOf("\/*");
  9267. var cEndIdx = value.lastIndexOf("*\/");
  9268. if(cStartIdx == -1 || cEndIdx == -1){
  9269. throw new Error("JSON was not comment filtered");
  9270. }
  9271. return _d.fromJson(value.substring(cStartIdx+2, cEndIdx));
  9272. },
  9273. javascript: function(xhr){
  9274. // summary: A contentHandler which evaluates the response data, expecting it to be valid JavaScript
  9275. // FIXME: try Moz and IE specific eval variants?
  9276. return _d.eval(xhr.responseText);
  9277. },
  9278. xml: function(xhr){
  9279. // summary: A contentHandler returning an XML Document parsed from the response data
  9280. var result = xhr.responseXML;
  9281. if(_d.isIE && (!result || !result.documentElement)){
  9282. //WARNING: this branch used by the xml handling in dojo.io.iframe,
  9283. //so be sure to test dojo.io.iframe if making changes below.
  9284. var ms = function(n){ return "MSXML" + n + ".DOMDocument"; };
  9285. var dp = ["Microsoft.XMLDOM", ms(6), ms(4), ms(3), ms(2)];
  9286. _d.some(dp, function(p){
  9287. try{
  9288. var dom = new ActiveXObject(p);
  9289. dom.async = false;
  9290. dom.loadXML(xhr.responseText);
  9291. result = dom;
  9292. }catch(e){ return false; }
  9293. return true;
  9294. });
  9295. }
  9296. return result; // DOMDocument
  9297. },
  9298. "json-comment-optional": function(xhr){
  9299. // summary: A contentHandler which checks the presence of comment-filtered JSON and
  9300. // alternates between the `json` and `json-comment-filtered` contentHandlers.
  9301. if(xhr.responseText && /^[^{\[]*\/\*/.test(xhr.responseText)){
  9302. return handlers["json-comment-filtered"](xhr);
  9303. }else{
  9304. return handlers["json"](xhr);
  9305. }
  9306. }
  9307. };
  9308. /*=====
  9309. dojo.__IoArgs = function(){
  9310. // url: String
  9311. // URL to server endpoint.
  9312. // content: Object?
  9313. // Contains properties with string values. These
  9314. // properties will be serialized as name1=value2 and
  9315. // passed in the request.
  9316. // timeout: Integer?
  9317. // Milliseconds to wait for the response. If this time
  9318. // passes, the then error callbacks are called.
  9319. // form: DOMNode?
  9320. // DOM node for a form. Used to extract the form values
  9321. // and send to the server.
  9322. // preventCache: Boolean?
  9323. // Default is false. If true, then a
  9324. // "dojo.preventCache" parameter is sent in the request
  9325. // with a value that changes with each request
  9326. // (timestamp). Useful only with GET-type requests.
  9327. // handleAs: String?
  9328. // Acceptable values depend on the type of IO
  9329. // transport (see specific IO calls for more information).
  9330. // rawBody: String?
  9331. // Sets the raw body for an HTTP request. If this is used, then the content
  9332. // property is ignored. This is mostly useful for HTTP methods that have
  9333. // a body to their requests, like PUT or POST. This property can be used instead
  9334. // of postData and putData for dojo.rawXhrPost and dojo.rawXhrPut respectively.
  9335. // ioPublish: Boolean?
  9336. // Set this explicitly to false to prevent publishing of topics related to
  9337. // IO operations. Otherwise, if djConfig.ioPublish is set to true, topics
  9338. // will be published via dojo.publish for different phases of an IO operation.
  9339. // See dojo.__IoPublish for a list of topics that are published.
  9340. // load: Function?
  9341. // This function will be
  9342. // called on a successful HTTP response code.
  9343. // error: Function?
  9344. // This function will
  9345. // be called when the request fails due to a network or server error, the url
  9346. // is invalid, etc. It will also be called if the load or handle callback throws an
  9347. // exception, unless djConfig.debugAtAllCosts is true. This allows deployed applications
  9348. // to continue to run even when a logic error happens in the callback, while making
  9349. // it easier to troubleshoot while in debug mode.
  9350. // handle: Function?
  9351. // This function will
  9352. // be called at the end of every request, whether or not an error occurs.
  9353. this.url = url;
  9354. this.content = content;
  9355. this.timeout = timeout;
  9356. this.form = form;
  9357. this.preventCache = preventCache;
  9358. this.handleAs = handleAs;
  9359. this.ioPublish = ioPublish;
  9360. this.load = function(response, ioArgs){
  9361. // ioArgs: dojo.__IoCallbackArgs
  9362. // Provides additional information about the request.
  9363. // response: Object
  9364. // The response in the format as defined with handleAs.
  9365. }
  9366. this.error = function(response, ioArgs){
  9367. // ioArgs: dojo.__IoCallbackArgs
  9368. // Provides additional information about the request.
  9369. // response: Object
  9370. // The response in the format as defined with handleAs.
  9371. }
  9372. this.handle = function(loadOrError, response, ioArgs){
  9373. // loadOrError: String
  9374. // Provides a string that tells you whether this function
  9375. // was called because of success (load) or failure (error).
  9376. // response: Object
  9377. // The response in the format as defined with handleAs.
  9378. // ioArgs: dojo.__IoCallbackArgs
  9379. // Provides additional information about the request.
  9380. }
  9381. }
  9382. =====*/
  9383. /*=====
  9384. dojo.__IoCallbackArgs = function(args, xhr, url, query, handleAs, id, canDelete, json){
  9385. // args: Object
  9386. // the original object argument to the IO call.
  9387. // xhr: XMLHttpRequest
  9388. // For XMLHttpRequest calls only, the
  9389. // XMLHttpRequest object that was used for the
  9390. // request.
  9391. // url: String
  9392. // The final URL used for the call. Many times it
  9393. // will be different than the original args.url
  9394. // value.
  9395. // query: String
  9396. // For non-GET requests, the
  9397. // name1=value1&name2=value2 parameters sent up in
  9398. // the request.
  9399. // handleAs: String
  9400. // The final indicator on how the response will be
  9401. // handled.
  9402. // id: String
  9403. // For dojo.io.script calls only, the internal
  9404. // script ID used for the request.
  9405. // canDelete: Boolean
  9406. // For dojo.io.script calls only, indicates
  9407. // whether the script tag that represents the
  9408. // request can be deleted after callbacks have
  9409. // been called. Used internally to know when
  9410. // cleanup can happen on JSONP-type requests.
  9411. // json: Object
  9412. // For dojo.io.script calls only: holds the JSON
  9413. // response for JSONP-type requests. Used
  9414. // internally to hold on to the JSON responses.
  9415. // You should not need to access it directly --
  9416. // the same object should be passed to the success
  9417. // callbacks directly.
  9418. this.args = args;
  9419. this.xhr = xhr;
  9420. this.url = url;
  9421. this.query = query;
  9422. this.handleAs = handleAs;
  9423. this.id = id;
  9424. this.canDelete = canDelete;
  9425. this.json = json;
  9426. }
  9427. =====*/
  9428. /*=====
  9429. dojo.__IoPublish = function(){
  9430. // summary:
  9431. // This is a list of IO topics that can be published
  9432. // if djConfig.ioPublish is set to true. IO topics can be
  9433. // published for any Input/Output, network operation. So,
  9434. // dojo.xhr, dojo.io.script and dojo.io.iframe can all
  9435. // trigger these topics to be published.
  9436. // start: String
  9437. // "/dojo/io/start" is sent when there are no outstanding IO
  9438. // requests, and a new IO request is started. No arguments
  9439. // are passed with this topic.
  9440. // send: String
  9441. // "/dojo/io/send" is sent whenever a new IO request is started.
  9442. // It passes the dojo.Deferred for the request with the topic.
  9443. // load: String
  9444. // "/dojo/io/load" is sent whenever an IO request has loaded
  9445. // successfully. It passes the response and the dojo.Deferred
  9446. // for the request with the topic.
  9447. // error: String
  9448. // "/dojo/io/error" is sent whenever an IO request has errored.
  9449. // It passes the error and the dojo.Deferred
  9450. // for the request with the topic.
  9451. // done: String
  9452. // "/dojo/io/done" is sent whenever an IO request has completed,
  9453. // either by loading or by erroring. It passes the error and
  9454. // the dojo.Deferred for the request with the topic.
  9455. // stop: String
  9456. // "/dojo/io/stop" is sent when all outstanding IO requests have
  9457. // finished. No arguments are passed with this topic.
  9458. this.start = "/dojo/io/start";
  9459. this.send = "/dojo/io/send";
  9460. this.load = "/dojo/io/load";
  9461. this.error = "/dojo/io/error";
  9462. this.done = "/dojo/io/done";
  9463. this.stop = "/dojo/io/stop";
  9464. }
  9465. =====*/
  9466. dojo._ioSetArgs = function(/*dojo.__IoArgs*/args,
  9467. /*Function*/canceller,
  9468. /*Function*/okHandler,
  9469. /*Function*/errHandler){
  9470. // summary:
  9471. // sets up the Deferred and ioArgs property on the Deferred so it
  9472. // can be used in an io call.
  9473. // args:
  9474. // The args object passed into the public io call. Recognized properties on
  9475. // the args object are:
  9476. // canceller:
  9477. // The canceller function used for the Deferred object. The function
  9478. // will receive one argument, the Deferred object that is related to the
  9479. // canceller.
  9480. // okHandler:
  9481. // The first OK callback to be registered with Deferred. It has the opportunity
  9482. // to transform the OK response. It will receive one argument -- the Deferred
  9483. // object returned from this function.
  9484. // errHandler:
  9485. // The first error callback to be registered with Deferred. It has the opportunity
  9486. // to do cleanup on an error. It will receive two arguments: error (the
  9487. // Error object) and dfd, the Deferred object returned from this function.
  9488. var ioArgs = {args: args, url: args.url};
  9489. //Get values from form if requestd.
  9490. var formObject = null;
  9491. if(args.form){
  9492. var form = _d.byId(args.form);
  9493. //IE requires going through getAttributeNode instead of just getAttribute in some form cases,
  9494. //so use it for all. See #2844
  9495. var actnNode = form.getAttributeNode("action");
  9496. ioArgs.url = ioArgs.url || (actnNode ? actnNode.value : null);
  9497. formObject = _d.formToObject(form);
  9498. }
  9499. // set up the query params
  9500. var miArgs = [{}];
  9501. if(formObject){
  9502. // potentially over-ride url-provided params w/ form values
  9503. miArgs.push(formObject);
  9504. }
  9505. if(args.content){
  9506. // stuff in content over-rides what's set by form
  9507. miArgs.push(args.content);
  9508. }
  9509. if(args.preventCache){
  9510. miArgs.push({"dojo.preventCache": new Date().valueOf()});
  9511. }
  9512. ioArgs.query = _d.objectToQuery(_d.mixin.apply(null, miArgs));
  9513. // .. and the real work of getting the deferred in order, etc.
  9514. ioArgs.handleAs = args.handleAs || "text";
  9515. var d = new _d.Deferred(canceller);
  9516. d.addCallbacks(okHandler, function(error){
  9517. return errHandler(error, d);
  9518. });
  9519. //Support specifying load, error and handle callback functions from the args.
  9520. //For those callbacks, the "this" object will be the args object.
  9521. //The callbacks will get the deferred result value as the
  9522. //first argument and the ioArgs object as the second argument.
  9523. var ld = args.load;
  9524. if(ld && _d.isFunction(ld)){
  9525. d.addCallback(function(value){
  9526. return ld.call(args, value, ioArgs);
  9527. });
  9528. }
  9529. var err = args.error;
  9530. if(err && _d.isFunction(err)){
  9531. d.addErrback(function(value){
  9532. return err.call(args, value, ioArgs);
  9533. });
  9534. }
  9535. var handle = args.handle;
  9536. if(handle && _d.isFunction(handle)){
  9537. d.addBoth(function(value){
  9538. return handle.call(args, value, ioArgs);
  9539. });
  9540. }
  9541. //Plug in topic publishing, if dojo.publish is loaded.
  9542. if(cfg.ioPublish && _d.publish && ioArgs.args.ioPublish !== false){
  9543. d.addCallbacks(
  9544. function(res){
  9545. _d.publish("/dojo/io/load", [d, res]);
  9546. return res;
  9547. },
  9548. function(res){
  9549. _d.publish("/dojo/io/error", [d, res]);
  9550. return res;
  9551. }
  9552. );
  9553. d.addBoth(function(res){
  9554. _d.publish("/dojo/io/done", [d, res]);
  9555. return res;
  9556. });
  9557. }
  9558. d.ioArgs = ioArgs;
  9559. // FIXME: need to wire up the xhr object's abort method to something
  9560. // analagous in the Deferred
  9561. return d;
  9562. };
  9563. var _deferredCancel = function(/*Deferred*/dfd){
  9564. // summary: canceller function for dojo._ioSetArgs call.
  9565. dfd.canceled = true;
  9566. var xhr = dfd.ioArgs.xhr;
  9567. var _at = typeof xhr.abort;
  9568. if(_at == "function" || _at == "object" || _at == "unknown"){
  9569. xhr.abort();
  9570. }
  9571. var err = dfd.ioArgs.error;
  9572. if(!err){
  9573. err = new Error("xhr cancelled");
  9574. err.dojoType="cancel";
  9575. }
  9576. return err;
  9577. };
  9578. var _deferredOk = function(/*Deferred*/dfd){
  9579. // summary: okHandler function for dojo._ioSetArgs call.
  9580. var ret = handlers[dfd.ioArgs.handleAs](dfd.ioArgs.xhr);
  9581. return ret === undefined ? null : ret;
  9582. };
  9583. var _deferError = function(/*Error*/error, /*Deferred*/dfd){
  9584. // summary: errHandler function for dojo._ioSetArgs call.
  9585. if(!dfd.ioArgs.args.failOk){
  9586. console.error(error);
  9587. }
  9588. return error;
  9589. };
  9590. // avoid setting a timer per request. It degrades performance on IE
  9591. // something fierece if we don't use unified loops.
  9592. var _inFlightIntvl = null;
  9593. var _inFlight = [];
  9594. //Use a separate count for knowing if we are starting/stopping io calls.
  9595. //Cannot use _inFlight.length since it can change at a different time than
  9596. //when we want to do this kind of test. We only want to decrement the count
  9597. //after a callback/errback has finished, since the callback/errback should be
  9598. //considered as part of finishing a request.
  9599. var _pubCount = 0;
  9600. var _checkPubCount = function(dfd){
  9601. if(_pubCount <= 0){
  9602. _pubCount = 0;
  9603. if(cfg.ioPublish && _d.publish && (!dfd || dfd && dfd.ioArgs.args.ioPublish !== false)){
  9604. _d.publish("/dojo/io/stop");
  9605. }
  9606. }
  9607. };
  9608. var _watchInFlight = function(){
  9609. //summary:
  9610. // internal method that checks each inflight XMLHttpRequest to see
  9611. // if it has completed or if the timeout situation applies.
  9612. var now = (new Date()).getTime();
  9613. // make sure sync calls stay thread safe, if this callback is called
  9614. // during a sync call and this results in another sync call before the
  9615. // first sync call ends the browser hangs
  9616. if(!_d._blockAsync){
  9617. // we need manual loop because we often modify _inFlight (and therefore 'i') while iterating
  9618. // note: the second clause is an assigment on purpose, lint may complain
  9619. for(var i = 0, tif; i < _inFlight.length && (tif = _inFlight[i]); i++){
  9620. var dfd = tif.dfd;
  9621. var func = function(){
  9622. if(!dfd || dfd.canceled || !tif.validCheck(dfd)){
  9623. _inFlight.splice(i--, 1);
  9624. _pubCount -= 1;
  9625. }else if(tif.ioCheck(dfd)){
  9626. _inFlight.splice(i--, 1);
  9627. tif.resHandle(dfd);
  9628. _pubCount -= 1;
  9629. }else if(dfd.startTime){
  9630. //did we timeout?
  9631. if(dfd.startTime + (dfd.ioArgs.args.timeout || 0) < now){
  9632. _inFlight.splice(i--, 1);
  9633. var err = new Error("timeout exceeded");
  9634. err.dojoType = "timeout";
  9635. dfd.errback(err);
  9636. //Cancel the request so the io module can do appropriate cleanup.
  9637. dfd.cancel();
  9638. _pubCount -= 1;
  9639. }
  9640. }
  9641. };
  9642. if(dojo.config.debugAtAllCosts){
  9643. func.call(this);
  9644. }else{
  9645. try{
  9646. func.call(this);
  9647. }catch(e){
  9648. dfd.errback(e);
  9649. }
  9650. }
  9651. }
  9652. }
  9653. _checkPubCount(dfd);
  9654. if(!_inFlight.length){
  9655. clearInterval(_inFlightIntvl);
  9656. _inFlightIntvl = null;
  9657. return;
  9658. }
  9659. };
  9660. dojo._ioCancelAll = function(){
  9661. //summary: Cancels all pending IO requests, regardless of IO type
  9662. //(xhr, script, iframe).
  9663. try{
  9664. _d.forEach(_inFlight, function(i){
  9665. try{
  9666. i.dfd.cancel();
  9667. }catch(e){/*squelch*/}
  9668. });
  9669. }catch(e){/*squelch*/}
  9670. };
  9671. //Automatically call cancel all io calls on unload
  9672. //in IE for trac issue #2357.
  9673. if(_d.isIE){
  9674. _d.addOnWindowUnload(_d._ioCancelAll);
  9675. }
  9676. _d._ioNotifyStart = function(/*Deferred*/dfd){
  9677. // summary:
  9678. // If dojo.publish is available, publish topics
  9679. // about the start of a request queue and/or the
  9680. // the beginning of request.
  9681. // description:
  9682. // Used by IO transports. An IO transport should
  9683. // call this method before making the network connection.
  9684. if(cfg.ioPublish && _d.publish && dfd.ioArgs.args.ioPublish !== false){
  9685. if(!_pubCount){
  9686. _d.publish("/dojo/io/start");
  9687. }
  9688. _pubCount += 1;
  9689. _d.publish("/dojo/io/send", [dfd]);
  9690. }
  9691. };
  9692. _d._ioWatch = function(dfd, validCheck, ioCheck, resHandle){
  9693. // summary:
  9694. // Watches the io request represented by dfd to see if it completes.
  9695. // dfd: Deferred
  9696. // The Deferred object to watch.
  9697. // validCheck: Function
  9698. // Function used to check if the IO request is still valid. Gets the dfd
  9699. // object as its only argument.
  9700. // ioCheck: Function
  9701. // Function used to check if basic IO call worked. Gets the dfd
  9702. // object as its only argument.
  9703. // resHandle: Function
  9704. // Function used to process response. Gets the dfd
  9705. // object as its only argument.
  9706. var args = dfd.ioArgs.args;
  9707. if(args.timeout){
  9708. dfd.startTime = (new Date()).getTime();
  9709. }
  9710. _inFlight.push({dfd: dfd, validCheck: validCheck, ioCheck: ioCheck, resHandle: resHandle});
  9711. if(!_inFlightIntvl){
  9712. _inFlightIntvl = setInterval(_watchInFlight, 50);
  9713. }
  9714. // handle sync requests
  9715. //A weakness: async calls in flight
  9716. //could have their handlers called as part of the
  9717. //_watchInFlight call, before the sync's callbacks
  9718. // are called.
  9719. if(args.sync){
  9720. _watchInFlight();
  9721. }
  9722. };
  9723. var _defaultContentType = "application/x-www-form-urlencoded";
  9724. var _validCheck = function(/*Deferred*/dfd){
  9725. return dfd.ioArgs.xhr.readyState; //boolean
  9726. };
  9727. var _ioCheck = function(/*Deferred*/dfd){
  9728. return 4 == dfd.ioArgs.xhr.readyState; //boolean
  9729. };
  9730. var _resHandle = function(/*Deferred*/dfd){
  9731. var xhr = dfd.ioArgs.xhr;
  9732. if(_d._isDocumentOk(xhr)){
  9733. dfd.callback(dfd);
  9734. }else{
  9735. var err = new Error("Unable to load " + dfd.ioArgs.url + " status:" + xhr.status);
  9736. err.status = xhr.status;
  9737. err.responseText = xhr.responseText;
  9738. dfd.errback(err);
  9739. }
  9740. };
  9741. dojo._ioAddQueryToUrl = function(/*dojo.__IoCallbackArgs*/ioArgs){
  9742. //summary: Adds query params discovered by the io deferred construction to the URL.
  9743. //Only use this for operations which are fundamentally GET-type operations.
  9744. if(ioArgs.query.length){
  9745. ioArgs.url += (ioArgs.url.indexOf("?") == -1 ? "?" : "&") + ioArgs.query;
  9746. ioArgs.query = null;
  9747. }
  9748. };
  9749. /*=====
  9750. dojo.declare("dojo.__XhrArgs", dojo.__IoArgs, {
  9751. constructor: function(){
  9752. // summary:
  9753. // In addition to the properties listed for the dojo._IoArgs type,
  9754. // the following properties are allowed for dojo.xhr* methods.
  9755. // handleAs: String?
  9756. // Acceptable values are: text (default), json, json-comment-optional,
  9757. // json-comment-filtered, javascript, xml. See `dojo.contentHandlers`
  9758. // sync: Boolean?
  9759. // false is default. Indicates whether the request should
  9760. // be a synchronous (blocking) request.
  9761. // headers: Object?
  9762. // Additional HTTP headers to send in the request.
  9763. // failOk: Boolean?
  9764. // false is default. Indicates whether a request should be
  9765. // allowed to fail (and therefore no console error message in
  9766. // the event of a failure)
  9767. // contentType: String|Boolean
  9768. // "application/x-www-form-urlencoded" is default. Set to false to
  9769. // prevent a Content-Type header from being sent, or to a string
  9770. // to send a different Content-Type.
  9771. this.handleAs = handleAs;
  9772. this.sync = sync;
  9773. this.headers = headers;
  9774. this.failOk = failOk;
  9775. }
  9776. });
  9777. =====*/
  9778. dojo.xhr = function(/*String*/ method, /*dojo.__XhrArgs*/ args, /*Boolean?*/ hasBody){
  9779. // summary:
  9780. // Sends an HTTP request with the given method.
  9781. // description:
  9782. // Sends an HTTP request with the given method.
  9783. // See also dojo.xhrGet(), xhrPost(), xhrPut() and dojo.xhrDelete() for shortcuts
  9784. // for those HTTP methods. There are also methods for "raw" PUT and POST methods
  9785. // via dojo.rawXhrPut() and dojo.rawXhrPost() respectively.
  9786. // method:
  9787. // HTTP method to be used, such as GET, POST, PUT, DELETE. Should be uppercase.
  9788. // hasBody:
  9789. // If the request has an HTTP body, then pass true for hasBody.
  9790. //Make the Deferred object for this xhr request.
  9791. var dfd = _d._ioSetArgs(args, _deferredCancel, _deferredOk, _deferError);
  9792. var ioArgs = dfd.ioArgs;
  9793. //Pass the args to _xhrObj, to allow alternate XHR calls based specific calls, like
  9794. //the one used for iframe proxies.
  9795. var xhr = ioArgs.xhr = _d._xhrObj(ioArgs.args);
  9796. //If XHR factory fails, cancel the deferred.
  9797. if(!xhr){
  9798. dfd.cancel();
  9799. return dfd;
  9800. }
  9801. //Allow for specifying the HTTP body completely.
  9802. if("postData" in args){
  9803. ioArgs.query = args.postData;
  9804. }else if("putData" in args){
  9805. ioArgs.query = args.putData;
  9806. }else if("rawBody" in args){
  9807. ioArgs.query = args.rawBody;
  9808. }else if((arguments.length > 2 && !hasBody) || "POST|PUT".indexOf(method.toUpperCase()) == -1){
  9809. //Check for hasBody being passed. If no hasBody,
  9810. //then only append query string if not a POST or PUT request.
  9811. _d._ioAddQueryToUrl(ioArgs);
  9812. }
  9813. // IE 6 is a steaming pile. It won't let you call apply() on the native function (xhr.open).
  9814. // workaround for IE6's apply() "issues"
  9815. xhr.open(method, ioArgs.url, args.sync !== true, args.user || undefined, args.password || undefined);
  9816. if(args.headers){
  9817. for(var hdr in args.headers){
  9818. if(hdr.toLowerCase() === "content-type"){
  9819. if(!args.contentType){
  9820. args.contentType = args.headers[hdr];
  9821. }
  9822. }else if(args.headers[hdr]){
  9823. //Only add header if it has a value. This allows for instnace, skipping
  9824. //insertion of X-Requested-With by specifying empty value.
  9825. xhr.setRequestHeader(hdr, args.headers[hdr]);
  9826. }
  9827. }
  9828. }
  9829. // FIXME: is this appropriate for all content types?
  9830. if(args.contentType !== false){
  9831. xhr.setRequestHeader("Content-Type", args.contentType || _defaultContentType);
  9832. }
  9833. if(!args.headers || !("X-Requested-With" in args.headers)){
  9834. xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
  9835. }
  9836. // FIXME: set other headers here!
  9837. _d._ioNotifyStart(dfd);
  9838. if(dojo.config.debugAtAllCosts){
  9839. xhr.send(ioArgs.query);
  9840. }else{
  9841. try{
  9842. xhr.send(ioArgs.query);
  9843. }catch(e){
  9844. ioArgs.error = e;
  9845. dfd.cancel();
  9846. }
  9847. }
  9848. _d._ioWatch(dfd, _validCheck, _ioCheck, _resHandle);
  9849. xhr = null;
  9850. return dfd; // dojo.Deferred
  9851. };
  9852. dojo.xhrGet = function(/*dojo.__XhrArgs*/ args){
  9853. // summary:
  9854. // Sends an HTTP GET request to the server.
  9855. return _d.xhr("GET", args); // dojo.Deferred
  9856. };
  9857. dojo.rawXhrPost = dojo.xhrPost = function(/*dojo.__XhrArgs*/ args){
  9858. // summary:
  9859. // Sends an HTTP POST request to the server. In addtion to the properties
  9860. // listed for the dojo.__XhrArgs type, the following property is allowed:
  9861. // postData:
  9862. // String. Send raw data in the body of the POST request.
  9863. return _d.xhr("POST", args, true); // dojo.Deferred
  9864. };
  9865. dojo.rawXhrPut = dojo.xhrPut = function(/*dojo.__XhrArgs*/ args){
  9866. // summary:
  9867. // Sends an HTTP PUT request to the server. In addtion to the properties
  9868. // listed for the dojo.__XhrArgs type, the following property is allowed:
  9869. // putData:
  9870. // String. Send raw data in the body of the PUT request.
  9871. return _d.xhr("PUT", args, true); // dojo.Deferred
  9872. };
  9873. dojo.xhrDelete = function(/*dojo.__XhrArgs*/ args){
  9874. // summary:
  9875. // Sends an HTTP DELETE request to the server.
  9876. return _d.xhr("DELETE", args); //dojo.Deferred
  9877. };
  9878. /*
  9879. dojo.wrapForm = function(formNode){
  9880. //summary:
  9881. // A replacement for FormBind, but not implemented yet.
  9882. // FIXME: need to think harder about what extensions to this we might
  9883. // want. What should we allow folks to do w/ this? What events to
  9884. // set/send?
  9885. throw new Error("dojo.wrapForm not yet implemented");
  9886. }
  9887. */
  9888. })();
  9889. }
  9890. if(!dojo._hasResource["dojo._base.fx"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  9891. dojo._hasResource["dojo._base.fx"] = true;
  9892. dojo.provide("dojo._base.fx");
  9893. /*
  9894. Animation loosely package based on Dan Pupius' work, contributed under CLA:
  9895. http://pupius.co.uk/js/Toolkit.Drawing.js
  9896. */
  9897. (function(){
  9898. var d = dojo;
  9899. var _mixin = d._mixin;
  9900. dojo._Line = function(/*int*/ start, /*int*/ end){
  9901. // summary:
  9902. // dojo._Line is the object used to generate values from a start value
  9903. // to an end value
  9904. // start: int
  9905. // Beginning value for range
  9906. // end: int
  9907. // Ending value for range
  9908. this.start = start;
  9909. this.end = end;
  9910. };
  9911. dojo._Line.prototype.getValue = function(/*float*/ n){
  9912. // summary: Returns the point on the line
  9913. // n: a floating point number greater than 0 and less than 1
  9914. return ((this.end - this.start) * n) + this.start; // Decimal
  9915. };
  9916. dojo.Animation = function(args){
  9917. // summary:
  9918. // A generic animation class that fires callbacks into its handlers
  9919. // object at various states.
  9920. // description:
  9921. // A generic animation class that fires callbacks into its handlers
  9922. // object at various states. Nearly all dojo animation functions
  9923. // return an instance of this method, usually without calling the
  9924. // .play() method beforehand. Therefore, you will likely need to
  9925. // call .play() on instances of `dojo.Animation` when one is
  9926. // returned.
  9927. // args: Object
  9928. // The 'magic argument', mixing all the properties into this
  9929. // animation instance.
  9930. _mixin(this, args);
  9931. if(d.isArray(this.curve)){
  9932. this.curve = new d._Line(this.curve[0], this.curve[1]);
  9933. }
  9934. };
  9935. // Alias to drop come 2.0:
  9936. d._Animation = d.Animation;
  9937. d.extend(dojo.Animation, {
  9938. // duration: Integer
  9939. // The time in milliseonds the animation will take to run
  9940. duration: 350,
  9941. /*=====
  9942. // curve: dojo._Line|Array
  9943. // A two element array of start and end values, or a `dojo._Line` instance to be
  9944. // used in the Animation.
  9945. curve: null,
  9946. // easing: Function?
  9947. // A Function to adjust the acceleration (or deceleration) of the progress
  9948. // across a dojo._Line
  9949. easing: null,
  9950. =====*/
  9951. // repeat: Integer?
  9952. // The number of times to loop the animation
  9953. repeat: 0,
  9954. // rate: Integer?
  9955. // the time in milliseconds to wait before advancing to next frame
  9956. // (used as a fps timer: 1000/rate = fps)
  9957. rate: 20 /* 50 fps */,
  9958. /*=====
  9959. // delay: Integer?
  9960. // The time in milliseconds to wait before starting animation after it
  9961. // has been .play()'ed
  9962. delay: null,
  9963. // beforeBegin: Event?
  9964. // Synthetic event fired before a dojo.Animation begins playing (synchronous)
  9965. beforeBegin: null,
  9966. // onBegin: Event?
  9967. // Synthetic event fired as a dojo.Animation begins playing (useful?)
  9968. onBegin: null,
  9969. // onAnimate: Event?
  9970. // Synthetic event fired at each interval of a `dojo.Animation`
  9971. onAnimate: null,
  9972. // onEnd: Event?
  9973. // Synthetic event fired after the final frame of a `dojo.Animation`
  9974. onEnd: null,
  9975. // onPlay: Event?
  9976. // Synthetic event fired any time a `dojo.Animation` is play()'ed
  9977. onPlay: null,
  9978. // onPause: Event?
  9979. // Synthetic event fired when a `dojo.Animation` is paused
  9980. onPause: null,
  9981. // onStop: Event
  9982. // Synthetic event fires when a `dojo.Animation` is stopped
  9983. onStop: null,
  9984. =====*/
  9985. _percent: 0,
  9986. _startRepeatCount: 0,
  9987. _getStep: function(){
  9988. var _p = this._percent,
  9989. _e = this.easing
  9990. ;
  9991. return _e ? _e(_p) : _p;
  9992. },
  9993. _fire: function(/*Event*/ evt, /*Array?*/ args){
  9994. // summary:
  9995. // Convenience function. Fire event "evt" and pass it the
  9996. // arguments specified in "args".
  9997. // description:
  9998. // Convenience function. Fire event "evt" and pass it the
  9999. // arguments specified in "args".
  10000. // Fires the callback in the scope of the `dojo.Animation`
  10001. // instance.
  10002. // evt:
  10003. // The event to fire.
  10004. // args:
  10005. // The arguments to pass to the event.
  10006. var a = args||[];
  10007. if(this[evt]){
  10008. if(d.config.debugAtAllCosts){
  10009. this[evt].apply(this, a);
  10010. }else{
  10011. try{
  10012. this[evt].apply(this, a);
  10013. }catch(e){
  10014. // squelch and log because we shouldn't allow exceptions in
  10015. // synthetic event handlers to cause the internal timer to run
  10016. // amuck, potentially pegging the CPU. I'm not a fan of this
  10017. // squelch, but hopefully logging will make it clear what's
  10018. // going on
  10019. console.error("exception in animation handler for:", evt);
  10020. console.error(e);
  10021. }
  10022. }
  10023. }
  10024. return this; // dojo.Animation
  10025. },
  10026. play: function(/*int?*/ delay, /*Boolean?*/ gotoStart){
  10027. // summary:
  10028. // Start the animation.
  10029. // delay:
  10030. // How many milliseconds to delay before starting.
  10031. // gotoStart:
  10032. // If true, starts the animation from the beginning; otherwise,
  10033. // starts it from its current position.
  10034. // returns: dojo.Animation
  10035. // The instance to allow chaining.
  10036. var _t = this;
  10037. if(_t._delayTimer){ _t._clearTimer(); }
  10038. if(gotoStart){
  10039. _t._stopTimer();
  10040. _t._active = _t._paused = false;
  10041. _t._percent = 0;
  10042. }else if(_t._active && !_t._paused){
  10043. return _t;
  10044. }
  10045. _t._fire("beforeBegin", [_t.node]);
  10046. var de = delay || _t.delay,
  10047. _p = dojo.hitch(_t, "_play", gotoStart);
  10048. if(de > 0){
  10049. _t._delayTimer = setTimeout(_p, de);
  10050. return _t;
  10051. }
  10052. _p();
  10053. return _t;
  10054. },
  10055. _play: function(gotoStart){
  10056. var _t = this;
  10057. if(_t._delayTimer){ _t._clearTimer(); }
  10058. _t._startTime = new Date().valueOf();
  10059. if(_t._paused){
  10060. _t._startTime -= _t.duration * _t._percent;
  10061. }
  10062. _t._active = true;
  10063. _t._paused = false;
  10064. var value = _t.curve.getValue(_t._getStep());
  10065. if(!_t._percent){
  10066. if(!_t._startRepeatCount){
  10067. _t._startRepeatCount = _t.repeat;
  10068. }
  10069. _t._fire("onBegin", [value]);
  10070. }
  10071. _t._fire("onPlay", [value]);
  10072. _t._cycle();
  10073. return _t; // dojo.Animation
  10074. },
  10075. pause: function(){
  10076. // summary: Pauses a running animation.
  10077. var _t = this;
  10078. if(_t._delayTimer){ _t._clearTimer(); }
  10079. _t._stopTimer();
  10080. if(!_t._active){ return _t; /*dojo.Animation*/ }
  10081. _t._paused = true;
  10082. _t._fire("onPause", [_t.curve.getValue(_t._getStep())]);
  10083. return _t; // dojo.Animation
  10084. },
  10085. gotoPercent: function(/*Decimal*/ percent, /*Boolean?*/ andPlay){
  10086. // summary:
  10087. // Sets the progress of the animation.
  10088. // percent:
  10089. // A percentage in decimal notation (between and including 0.0 and 1.0).
  10090. // andPlay:
  10091. // If true, play the animation after setting the progress.
  10092. var _t = this;
  10093. _t._stopTimer();
  10094. _t._active = _t._paused = true;
  10095. _t._percent = percent;
  10096. if(andPlay){ _t.play(); }
  10097. return _t; // dojo.Animation
  10098. },
  10099. stop: function(/*boolean?*/ gotoEnd){
  10100. // summary: Stops a running animation.
  10101. // gotoEnd: If true, the animation will end.
  10102. var _t = this;
  10103. if(_t._delayTimer){ _t._clearTimer(); }
  10104. if(!_t._timer){ return _t; /* dojo.Animation */ }
  10105. _t._stopTimer();
  10106. if(gotoEnd){
  10107. _t._percent = 1;
  10108. }
  10109. _t._fire("onStop", [_t.curve.getValue(_t._getStep())]);
  10110. _t._active = _t._paused = false;
  10111. return _t; // dojo.Animation
  10112. },
  10113. status: function(){
  10114. // summary:
  10115. // Returns a string token representation of the status of
  10116. // the animation, one of: "paused", "playing", "stopped"
  10117. if(this._active){
  10118. return this._paused ? "paused" : "playing"; // String
  10119. }
  10120. return "stopped"; // String
  10121. },
  10122. _cycle: function(){
  10123. var _t = this;
  10124. if(_t._active){
  10125. var curr = new Date().valueOf();
  10126. var step = (curr - _t._startTime) / (_t.duration);
  10127. if(step >= 1){
  10128. step = 1;
  10129. }
  10130. _t._percent = step;
  10131. // Perform easing
  10132. if(_t.easing){
  10133. step = _t.easing(step);
  10134. }
  10135. _t._fire("onAnimate", [_t.curve.getValue(step)]);
  10136. if(_t._percent < 1){
  10137. _t._startTimer();
  10138. }else{
  10139. _t._active = false;
  10140. if(_t.repeat > 0){
  10141. _t.repeat--;
  10142. _t.play(null, true);
  10143. }else if(_t.repeat == -1){
  10144. _t.play(null, true);
  10145. }else{
  10146. if(_t._startRepeatCount){
  10147. _t.repeat = _t._startRepeatCount;
  10148. _t._startRepeatCount = 0;
  10149. }
  10150. }
  10151. _t._percent = 0;
  10152. _t._fire("onEnd", [_t.node]);
  10153. !_t.repeat && _t._stopTimer();
  10154. }
  10155. }
  10156. return _t; // dojo.Animation
  10157. },
  10158. _clearTimer: function(){
  10159. // summary: Clear the play delay timer
  10160. clearTimeout(this._delayTimer);
  10161. delete this._delayTimer;
  10162. }
  10163. });
  10164. // the local timer, stubbed into all Animation instances
  10165. var ctr = 0,
  10166. timer = null,
  10167. runner = {
  10168. run: function(){}
  10169. };
  10170. d.extend(d.Animation, {
  10171. _startTimer: function(){
  10172. if(!this._timer){
  10173. this._timer = d.connect(runner, "run", this, "_cycle");
  10174. ctr++;
  10175. }
  10176. if(!timer){
  10177. timer = setInterval(d.hitch(runner, "run"), this.rate);
  10178. }
  10179. },
  10180. _stopTimer: function(){
  10181. if(this._timer){
  10182. d.disconnect(this._timer);
  10183. this._timer = null;
  10184. ctr--;
  10185. }
  10186. if(ctr <= 0){
  10187. clearInterval(timer);
  10188. timer = null;
  10189. ctr = 0;
  10190. }
  10191. }
  10192. });
  10193. var _makeFadeable =
  10194. d.isIE ? function(node){
  10195. // only set the zoom if the "tickle" value would be the same as the
  10196. // default
  10197. var ns = node.style;
  10198. // don't set the width to auto if it didn't already cascade that way.
  10199. // We don't want to f anyones designs
  10200. if(!ns.width.length && d.style(node, "width") == "auto"){
  10201. ns.width = "auto";
  10202. }
  10203. } :
  10204. function(){};
  10205. dojo._fade = function(/*Object*/ args){
  10206. // summary:
  10207. // Returns an animation that will fade the node defined by
  10208. // args.node from the start to end values passed (args.start
  10209. // args.end) (end is mandatory, start is optional)
  10210. args.node = d.byId(args.node);
  10211. var fArgs = _mixin({ properties: {} }, args),
  10212. props = (fArgs.properties.opacity = {});
  10213. props.start = !("start" in fArgs) ?
  10214. function(){
  10215. return +d.style(fArgs.node, "opacity")||0;
  10216. } : fArgs.start;
  10217. props.end = fArgs.end;
  10218. var anim = d.animateProperty(fArgs);
  10219. d.connect(anim, "beforeBegin", d.partial(_makeFadeable, fArgs.node));
  10220. return anim; // dojo.Animation
  10221. };
  10222. /*=====
  10223. dojo.__FadeArgs = function(node, duration, easing){
  10224. // node: DOMNode|String
  10225. // The node referenced in the animation
  10226. // duration: Integer?
  10227. // Duration of the animation in milliseconds.
  10228. // easing: Function?
  10229. // An easing function.
  10230. this.node = node;
  10231. this.duration = duration;
  10232. this.easing = easing;
  10233. }
  10234. =====*/
  10235. dojo.fadeIn = function(/*dojo.__FadeArgs*/ args){
  10236. // summary:
  10237. // Returns an animation that will fade node defined in 'args' from
  10238. // its current opacity to fully opaque.
  10239. return d._fade(_mixin({ end: 1 }, args)); // dojo.Animation
  10240. };
  10241. dojo.fadeOut = function(/*dojo.__FadeArgs*/ args){
  10242. // summary:
  10243. // Returns an animation that will fade node defined in 'args'
  10244. // from its current opacity to fully transparent.
  10245. return d._fade(_mixin({ end: 0 }, args)); // dojo.Animation
  10246. };
  10247. dojo._defaultEasing = function(/*Decimal?*/ n){
  10248. // summary: The default easing function for dojo.Animation(s)
  10249. return 0.5 + ((Math.sin((n + 1.5) * Math.PI)) / 2);
  10250. };
  10251. var PropLine = function(properties){
  10252. // PropLine is an internal class which is used to model the values of
  10253. // an a group of CSS properties across an animation lifecycle. In
  10254. // particular, the "getValue" function handles getting interpolated
  10255. // values between start and end for a particular CSS value.
  10256. this._properties = properties;
  10257. for(var p in properties){
  10258. var prop = properties[p];
  10259. if(prop.start instanceof d.Color){
  10260. // create a reusable temp color object to keep intermediate results
  10261. prop.tempColor = new d.Color();
  10262. }
  10263. }
  10264. };
  10265. PropLine.prototype.getValue = function(r){
  10266. var ret = {};
  10267. for(var p in this._properties){
  10268. var prop = this._properties[p],
  10269. start = prop.start;
  10270. if(start instanceof d.Color){
  10271. ret[p] = d.blendColors(start, prop.end, r, prop.tempColor).toCss();
  10272. }else if(!d.isArray(start)){
  10273. ret[p] = ((prop.end - start) * r) + start + (p != "opacity" ? prop.units || "px" : 0);
  10274. }
  10275. }
  10276. return ret;
  10277. };
  10278. /*=====
  10279. dojo.declare("dojo.__AnimArgs", [dojo.__FadeArgs], {
  10280. // Properties: Object?
  10281. // A hash map of style properties to Objects describing the transition,
  10282. // such as the properties of dojo._Line with an additional 'units' property
  10283. properties: {}
  10284. //TODOC: add event callbacks
  10285. });
  10286. =====*/
  10287. dojo.animateProperty = function(/*dojo.__AnimArgs*/ args){
  10288. // summary:
  10289. // Returns an animation that will transition the properties of
  10290. // node defined in `args` depending how they are defined in
  10291. // `args.properties`
  10292. //
  10293. // description:
  10294. // `dojo.animateProperty` is the foundation of most `dojo.fx`
  10295. // animations. It takes an object of "properties" corresponding to
  10296. // style properties, and animates them in parallel over a set
  10297. // duration.
  10298. //
  10299. // example:
  10300. // A simple animation that changes the width of the specified node.
  10301. // | dojo.animateProperty({
  10302. // | node: "nodeId",
  10303. // | properties: { width: 400 },
  10304. // | }).play();
  10305. // Dojo figures out the start value for the width and converts the
  10306. // integer specified for the width to the more expressive but
  10307. // verbose form `{ width: { end: '400', units: 'px' } }` which you
  10308. // can also specify directly. Defaults to 'px' if ommitted.
  10309. //
  10310. // example:
  10311. // Animate width, height, and padding over 2 seconds... the
  10312. // pedantic way:
  10313. // | dojo.animateProperty({ node: node, duration:2000,
  10314. // | properties: {
  10315. // | width: { start: '200', end: '400', units:"px" },
  10316. // | height: { start:'200', end: '400', units:"px" },
  10317. // | paddingTop: { start:'5', end:'50', units:"px" }
  10318. // | }
  10319. // | }).play();
  10320. // Note 'paddingTop' is used over 'padding-top'. Multi-name CSS properties
  10321. // are written using "mixed case", as the hyphen is illegal as an object key.
  10322. //
  10323. // example:
  10324. // Plug in a different easing function and register a callback for
  10325. // when the animation ends. Easing functions accept values between
  10326. // zero and one and return a value on that basis. In this case, an
  10327. // exponential-in curve.
  10328. // | dojo.animateProperty({
  10329. // | node: "nodeId",
  10330. // | // dojo figures out the start value
  10331. // | properties: { width: { end: 400 } },
  10332. // | easing: function(n){
  10333. // | return (n==0) ? 0 : Math.pow(2, 10 * (n - 1));
  10334. // | },
  10335. // | onEnd: function(node){
  10336. // | // called when the animation finishes. The animation
  10337. // | // target is passed to this function
  10338. // | }
  10339. // | }).play(500); // delay playing half a second
  10340. //
  10341. // example:
  10342. // Like all `dojo.Animation`s, animateProperty returns a handle to the
  10343. // Animation instance, which fires the events common to Dojo FX. Use `dojo.connect`
  10344. // to access these events outside of the Animation definiton:
  10345. // | var anim = dojo.animateProperty({
  10346. // | node:"someId",
  10347. // | properties:{
  10348. // | width:400, height:500
  10349. // | }
  10350. // | });
  10351. // | dojo.connect(anim,"onEnd", function(){
  10352. // | console.log("animation ended");
  10353. // | });
  10354. // | // play the animation now:
  10355. // | anim.play();
  10356. //
  10357. // example:
  10358. // Each property can be a function whose return value is substituted along.
  10359. // Additionally, each measurement (eg: start, end) can be a function. The node
  10360. // reference is passed direcly to callbacks.
  10361. // | dojo.animateProperty({
  10362. // | node:"mine",
  10363. // | properties:{
  10364. // | height:function(node){
  10365. // | // shrink this node by 50%
  10366. // | return dojo.position(node).h / 2
  10367. // | },
  10368. // | width:{
  10369. // | start:function(node){ return 100; },
  10370. // | end:function(node){ return 200; }
  10371. // | }
  10372. // | }
  10373. // | }).play();
  10374. //
  10375. var n = args.node = d.byId(args.node);
  10376. if(!args.easing){ args.easing = d._defaultEasing; }
  10377. var anim = new d.Animation(args);
  10378. d.connect(anim, "beforeBegin", anim, function(){
  10379. var pm = {};
  10380. for(var p in this.properties){
  10381. // Make shallow copy of properties into pm because we overwrite
  10382. // some values below. In particular if start/end are functions
  10383. // we don't want to overwrite them or the functions won't be
  10384. // called if the animation is reused.
  10385. if(p == "width" || p == "height"){
  10386. this.node.display = "block";
  10387. }
  10388. var prop = this.properties[p];
  10389. if(d.isFunction(prop)){
  10390. prop = prop(n);
  10391. }
  10392. prop = pm[p] = _mixin({}, (d.isObject(prop) ? prop: { end: prop }));
  10393. if(d.isFunction(prop.start)){
  10394. prop.start = prop.start(n);
  10395. }
  10396. if(d.isFunction(prop.end)){
  10397. prop.end = prop.end(n);
  10398. }
  10399. var isColor = (p.toLowerCase().indexOf("color") >= 0);
  10400. function getStyle(node, p){
  10401. // dojo.style(node, "height") can return "auto" or "" on IE; this is more reliable:
  10402. var v = { height: node.offsetHeight, width: node.offsetWidth }[p];
  10403. if(v !== undefined){ return v; }
  10404. v = d.style(node, p);
  10405. return (p == "opacity") ? +v : (isColor ? v : parseFloat(v));
  10406. }
  10407. if(!("end" in prop)){
  10408. prop.end = getStyle(n, p);
  10409. }else if(!("start" in prop)){
  10410. prop.start = getStyle(n, p);
  10411. }
  10412. if(isColor){
  10413. prop.start = new d.Color(prop.start);
  10414. prop.end = new d.Color(prop.end);
  10415. }else{
  10416. prop.start = (p == "opacity") ? +prop.start : parseFloat(prop.start);
  10417. }
  10418. }
  10419. this.curve = new PropLine(pm);
  10420. });
  10421. d.connect(anim, "onAnimate", d.hitch(d, "style", anim.node));
  10422. return anim; // dojo.Animation
  10423. };
  10424. dojo.anim = function( /*DOMNode|String*/ node,
  10425. /*Object*/ properties,
  10426. /*Integer?*/ duration,
  10427. /*Function?*/ easing,
  10428. /*Function?*/ onEnd,
  10429. /*Integer?*/ delay){
  10430. // summary:
  10431. // A simpler interface to `dojo.animateProperty()`, also returns
  10432. // an instance of `dojo.Animation` but begins the animation
  10433. // immediately, unlike nearly every other Dojo animation API.
  10434. // description:
  10435. // `dojo.anim` is a simpler (but somewhat less powerful) version
  10436. // of `dojo.animateProperty`. It uses defaults for many basic properties
  10437. // and allows for positional parameters to be used in place of the
  10438. // packed "property bag" which is used for other Dojo animation
  10439. // methods.
  10440. //
  10441. // The `dojo.Animation` object returned from `dojo.anim` will be
  10442. // already playing when it is returned from this function, so
  10443. // calling play() on it again is (usually) a no-op.
  10444. // node:
  10445. // a DOM node or the id of a node to animate CSS properties on
  10446. // duration:
  10447. // The number of milliseconds over which the animation
  10448. // should run. Defaults to the global animation default duration
  10449. // (350ms).
  10450. // easing:
  10451. // An easing function over which to calculate acceleration
  10452. // and deceleration of the animation through its duration.
  10453. // A default easing algorithm is provided, but you may
  10454. // plug in any you wish. A large selection of easing algorithms
  10455. // are available in `dojo.fx.easing`.
  10456. // onEnd:
  10457. // A function to be called when the animation finishes
  10458. // running.
  10459. // delay:
  10460. // The number of milliseconds to delay beginning the
  10461. // animation by. The default is 0.
  10462. // example:
  10463. // Fade out a node
  10464. // | dojo.anim("id", { opacity: 0 });
  10465. // example:
  10466. // Fade out a node over a full second
  10467. // | dojo.anim("id", { opacity: 0 }, 1000);
  10468. return d.animateProperty({ // dojo.Animation
  10469. node: node,
  10470. duration: duration || d.Animation.prototype.duration,
  10471. properties: properties,
  10472. easing: easing,
  10473. onEnd: onEnd
  10474. }).play(delay || 0);
  10475. };
  10476. })();
  10477. }
  10478. if(!dojo._hasResource["dojo._base.browser"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  10479. dojo._hasResource["dojo._base.browser"] = true;
  10480. dojo.provide("dojo._base.browser");
  10481. //Need this to be the last code segment in base, so do not place any
  10482. //dojo/requireIf calls in this file/ Otherwise, due to how the build system
  10483. //puts all requireIf dependencies after the current file, the require calls
  10484. //could be called before all of base is defined/
  10485. dojo.forEach(dojo.config.require, function(i){
  10486. dojo["require"](i);
  10487. });
  10488. }
  10489. if(!dojo._hasResource["dojo._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  10490. dojo._hasResource["dojo._base"] = true;
  10491. dojo.provide("dojo._base");
  10492. }
  10493. //INSERT dojo.i18n._preloadLocalizations HERE
  10494. //Check if document already complete, and if so, just trigger page load
  10495. //listeners. NOTE: does not work with Firefox before 3.6. To support
  10496. //those browsers, set djConfig.afterOnLoad = true when you know Dojo is added
  10497. //after page load. Using a timeout so the rest of this
  10498. //script gets evaluated properly. This work needs to happen after the
  10499. //dojo.config.require work done in dojo._base.
  10500. if(dojo.isBrowser && (document.readyState === "complete" || dojo.config.afterOnLoad)){
  10501. window.setTimeout(dojo._loadInit, 100);
  10502. }
  10503. })();