12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737 |
- /*
- Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.
- Available via Academic Free License >= 2.1 OR the modified BSD license.
- see: http://dojotoolkit.org/license for details
- */
- /*
- This is an optimized version of Dojo, built for deployment and not for
- development. To get sources and documentation, please visit:
- http://dojotoolkit.org
- */
- (function(
- userConfig,
- defaultConfig
- ){
- // summary:
- // This is the "source loader" and is the entry point for Dojo during development. You may also load Dojo with
- // any AMD-compliant loader via the package main module dojo/main.
- // description:
- // This is the "source loader" for Dojo. It provides an AMD-compliant loader that can be configured
- // to operate in either synchronous or asynchronous modes. After the loader is defined, dojo is loaded
- // IAW the package main module dojo/main. In the event you wish to use a foreign loader, you may load dojo as a package
- // via the package main module dojo/main and this loader is not required; see dojo/package.json for details.
- //
- // In order to keep compatibility with the v1.x line, this loader includes additional machinery that enables
- // the dojo.provide, dojo.require et al API. This machinery is loaded by default, but may be dynamically removed
- // via the has.js API and statically removed via the build system.
- //
- // This loader includes sniffing machinery to determine the environment; the following environments are supported:
- //
- // - browser
- // - node.js
- // - rhino
- //
- // This is the so-called "source loader". As such, it includes many optional features that may be discadred by
- // building a customized verion with the build system.
- // Design and Implementation Notes
- //
- // This is a dojo-specific adaption of bdLoad, donated to the dojo foundation by Altoviso LLC.
- //
- // This function defines an AMD-compliant (http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition)
- // loader that can be configured to operate in either synchronous or asynchronous modes.
- //
- // Since this machinery implements a loader, it does not have the luxury of using a load system and/or
- // leveraging a utility library. This results in an unpleasantly long file; here is a road map of the contents:
- //
- // 1. Small library for use implementing the loader.
- // 2. Define the has.js API; this is used throughout the loader to bracket features.
- // 3. Define the node.js and rhino sniffs and sniff.
- // 4. Define the loader's data.
- // 5. Define the configuration machinery.
- // 6. Define the script element sniffing machinery and sniff for configuration data.
- // 7. Configure the loader IAW the provided user, default, and sniffing data.
- // 8. Define the global require function.
- // 9. Define the module resolution machinery.
- // 10. Define the module and plugin module definition machinery
- // 11. Define the script injection machinery.
- // 12. Define the window load detection.
- // 13. Define the logging API.
- // 14. Define the tracing API.
- // 16. Define the AMD define function.
- // 17. Define the dojo v1.x provide/require machinery--so called "legacy" modes.
- // 18. Publish global variables.
- //
- // Language and Acronyms and Idioms
- //
- // moduleId: a CJS module identifier, (used for public APIs)
- // mid: moduleId (used internally)
- // packageId: a package identifier (used for public APIs)
- // pid: packageId (used internally); the implied system or default package has pid===""
- // pack: package is used internally to reference a package object (since javascript has reserved words including "package")
- // prid: plugin resource identifier
- // The integer constant 1 is used in place of true and 0 in place of false.
- // define a minimal library to help build the loader
- var noop = function(){
- },
- isEmpty = function(it){
- for(var p in it){
- return 0;
- }
- return 1;
- },
- toString = {}.toString,
- isFunction = function(it){
- return toString.call(it) == "[object Function]";
- },
- isString = function(it){
- return toString.call(it) == "[object String]";
- },
- isArray = function(it){
- return toString.call(it) == "[object Array]";
- },
- forEach = function(vector, callback){
- if(vector){
- for(var i = 0; i < vector.length;){
- callback(vector[i++]);
- }
- }
- },
- mix = function(dest, src){
- for(var p in src){
- dest[p] = src[p];
- }
- return dest;
- },
- makeError = function(error, info){
- return mix(new Error(error), {src:"dojoLoader", info:info});
- },
- uidSeed = 1,
- uid = function(){
- // Returns a unique indentifier (within the lifetime of the document) of the form /_d+/.
- return "_" + uidSeed++;
- },
- // FIXME: how to doc window.require() api
- // this will be the global require function; define it immediately so we can start hanging things off of it
- req = function(
- config, //(object, optional) hash of configuration properties
- dependencies, //(array of commonjs.moduleId, optional) list of modules to be loaded before applying callback
- callback //(function, optional) lamda expression to apply to module values implied by dependencies
- ){
- return contextRequire(config, dependencies, callback, 0, req);
- },
- // the loader uses the has.js API to control feature inclusion/exclusion; define then use throughout
- global = this,
- doc = global.document,
- element = doc && doc.createElement("DiV"),
- has = req.has = function(name){
- return isFunction(hasCache[name]) ? (hasCache[name] = hasCache[name](global, doc, element)) : hasCache[name];
- },
- hasCache = has.cache = defaultConfig.hasCache;
- has.add = function(name, test, now, force){
- (hasCache[name]===undefined || force) && (hasCache[name] = test);
- return now && has(name);
- };
- 0 && has.add("host-node", userConfig.has && "host-node" in userConfig.has ?
- userConfig.has["host-node"] :
- (typeof process == "object" && process.versions && process.versions.node && process.versions.v8));
- if( 0 ){
- // fixup the default config for node.js environment
- require("./_base/configNode.js").config(defaultConfig);
- // remember node's require (with respect to baseUrl==dojo's root)
- defaultConfig.loaderPatch.nodeRequire = require;
- }
- 0 && has.add("host-rhino", userConfig.has && "host-rhino" in userConfig.has ?
- userConfig.has["host-rhino"] :
- (typeof load == "function" && (typeof Packages == "function" || typeof Packages == "object")));
- if( 0 ){
- // owing to rhino's lame feature that hides the source of the script, give the user a way to specify the baseUrl...
- for(var baseUrl = userConfig.baseUrl || ".", arg, rhinoArgs = this.arguments, i = 0; i < rhinoArgs.length;){
- arg = (rhinoArgs[i++] + "").split("=");
- if(arg[0] == "baseUrl"){
- baseUrl = arg[1];
- break;
- }
- }
- load(baseUrl + "/_base/configRhino.js");
- rhinoDojoConfig(defaultConfig, baseUrl, rhinoArgs);
- }
- // userConfig has tests override defaultConfig has tests; do this after the environment detection because
- // the environment detection usually sets some has feature values in the hasCache.
- for(var p in userConfig.has){
- has.add(p, userConfig.has[p], 0, 1);
- }
- //
- // define the loader data
- //
- // the loader will use these like symbols if the loader has the traceApi; otherwise
- // define magic numbers so that modules can be provided as part of defaultConfig
- var requested = 1,
- arrived = 2,
- nonmodule = 3,
- executing = 4,
- executed = 5;
- if( 0 ){
- // these make debugging nice; but using strings for symbols is a gross rookie error; don't do it for production code
- requested = "requested";
- arrived = "arrived";
- nonmodule = "not-a-module";
- executing = "executing";
- executed = "executed";
- }
- var legacyMode = 0,
- sync = "sync",
- xd = "xd",
- syncExecStack = [],
- dojoRequirePlugin = 0,
- checkDojoRequirePlugin = noop,
- transformToAmd = noop,
- getXhr;
- if( 1 ){
- req.isXdUrl = noop;
- req.initSyncLoader = function(dojoRequirePlugin_, checkDojoRequirePlugin_, transformToAmd_){
- // the first dojo/_base/loader loaded gets to define these variables; they are designed to work
- // in the presense of zero to many mapped dojo/_base/loaders
- if(!dojoRequirePlugin){
- dojoRequirePlugin = dojoRequirePlugin_;
- checkDojoRequirePlugin = checkDojoRequirePlugin_;
- transformToAmd = transformToAmd_;
- }
- return {
- sync:sync,
- requested:requested,
- arrived:arrived,
- nonmodule:nonmodule,
- executing:executing,
- executed:executed,
- syncExecStack:syncExecStack,
- modules:modules,
- execQ:execQ,
- getModule:getModule,
- injectModule:injectModule,
- setArrived:setArrived,
- signal:signal,
- finishExec:finishExec,
- execModule:execModule,
- dojoRequirePlugin:dojoRequirePlugin,
- getLegacyMode:function(){return legacyMode;},
- guardCheckComplete:guardCheckComplete
- };
- };
- if( 1 ){
- // in legacy sync mode, the loader needs a minimal XHR library
- var locationProtocol = location.protocol,
- locationHost = location.host;
- req.isXdUrl = function(url){
- if(/^\./.test(url)){
- // begins with a dot is always relative to page URL; therefore not xdomain
- return false;
- }
- if(/^\/\//.test(url)){
- // for v1.6- backcompat, url starting with // indicates xdomain
- return true;
- }
- // get protocol and host
- // \/+ takes care of the typical file protocol that looks like file:///drive/path/to/file
- // locationHost is falsy if file protocol => if locationProtocol matches and is "file:", || will return false
- var match = url.match(/^([^\/\:]+\:)\/+([^\/]+)/);
- return match && (match[1] != locationProtocol || (locationHost && match[2] != locationHost));
- };
- // note: to get the file:// protocol to work in FF, you must set security.fileuri.strict_origin_policy to false in about:config
- 1 || has.add("dojo-xhr-factory", 1);
- has.add("dojo-force-activex-xhr", 1 && !doc.addEventListener && window.location.protocol == "file:");
- has.add("native-xhr", typeof XMLHttpRequest != "undefined");
- if(has("native-xhr") && !has("dojo-force-activex-xhr")){
- getXhr = function(){
- return new XMLHttpRequest();
- };
- }else{
- // if in the browser an old IE; find an xhr
- for(var XMLHTTP_PROGIDS = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'], progid, i = 0; i < 3;){
- try{
- progid = XMLHTTP_PROGIDS[i++];
- if(new ActiveXObject(progid)){
- // this progid works; therefore, use it from now on
- break;
- }
- }catch(e){
- // squelch; we're just trying to find a good ActiveX progid
- // if they all fail, then progid ends up as the last attempt and that will signal the error
- // the first time the client actually tries to exec an xhr
- }
- }
- getXhr = function(){
- return new ActiveXObject(progid);
- };
- }
- req.getXhr = getXhr;
- has.add("dojo-gettext-api", 1);
- req.getText = function(url, async, onLoad){
- var xhr = getXhr();
- xhr.open('GET', fixupUrl(url), false);
- xhr.send(null);
- if(xhr.status == 200 || (!location.host && !xhr.status)){
- if(onLoad){
- onLoad(xhr.responseText, async);
- }
- }else{
- throw makeError("xhrFailed", xhr.status);
- }
- return xhr.responseText;
- };
- }
- }else{
- req.async = 1;
- }
- //
- // loader eval
- //
- var eval_ =
- // use the function constructor so our eval is scoped close to (but not in) in the global space with minimal pollution
- new Function('return eval(arguments[0]);');
- req.eval =
- function(text, hint){
- return eval_(text + "\r\n////@ sourceURL=" + hint);
- };
- //
- // loader micro events API
- //
- var listenerQueues = {},
- error = "error",
- signal = req.signal = function(type, args){
- var queue = listenerQueues[type];
- // notice we run a copy of the queue; this allows listeners to add/remove
- // other listeners without affecting this particular signal
- forEach(queue && queue.slice(0), function(listener){
- listener.apply(null, isArray(args) ? args : [args]);
- });
- },
- on = req.on = function(type, listener){
- // notice a queue is not created until a client actually connects
- var queue = listenerQueues[type] || (listenerQueues[type] = []);
- queue.push(listener);
- return {
- remove:function(){
- for(var i = 0; i<queue.length; i++){
- if(queue[i]===listener){
- queue.splice(i, 1);
- return;
- }
- }
- }
- };
- };
- // configuration machinery; with an optimized/built defaultConfig, all configuration machinery can be discarded
- // lexical variables hold key loader data structures to help with minification; these may be completely,
- // one-time initialized by defaultConfig for optimized/built versions
- var
- aliases
- // a vector of pairs of [regexs or string, replacement] => (alias, actual)
- = [],
- paths
- // CommonJS paths
- = {},
- pathsMapProg
- // list of (from-path, to-path, regex, length) derived from paths;
- // a "program" to apply paths; see computeMapProg
- = [],
- packs
- // a map from packageId to package configuration object; see fixupPackageInfo
- = {},
- map = req.map
- // AMD map config variable; dojo/_base/kernel needs req.map to figure out the scope map
- = {},
- mapProgs
- // vector of quads as described by computeMapProg; map-key is AMD map key, map-value is AMD map value
- = [],
- modules
- // A hash:(mid) --> (module-object) the module namespace
- //
- // pid: the package identifier to which the module belongs (e.g., "dojo"); "" indicates the system or default package
- // mid: the fully-resolved (i.e., mappings have been applied) module identifier without the package identifier (e.g., "dojo/io/script")
- // url: the URL from which the module was retrieved
- // pack: the package object of the package to which the module belongs
- // executed: 0 => not executed; executing => in the process of tranversing deps and running factory; executed => factory has been executed
- // deps: the dependency vector for this module (vector of modules objects)
- // def: the factory for this module
- // result: the result of the running the factory for this module
- // injected: (0 | requested | arrived) the status of the module; nonmodule means the resource did not call define
- // load: plugin load function; applicable only for plugins
- //
- // Modules go through several phases in creation:
- //
- // 1. Requested: some other module's definition or a require application contained the requested module in
- // its dependency vector or executing code explicitly demands a module via req.require.
- //
- // 2. Injected: a script element has been appended to the insert-point element demanding the resource implied by the URL
- //
- // 3. Loaded: the resource injected in [2] has been evalated.
- //
- // 4. Defined: the resource contained a define statement that advised the loader about the module. Notice that some
- // resources may just contain a bundle of code and never formally define a module via define
- //
- // 5. Evaluated: the module was defined via define and the loader has evaluated the factory and computed a result.
- = {},
- cacheBust
- // query string to append to module URLs to bust browser cache
- = "",
- cache
- // hash:(mid | url)-->(function | string)
- //
- // A cache of resources. The resources arrive via a config.cache object, which is a hash from either mid --> function or
- // url --> string. The url key is distinguished from the mid key by always containing the prefix "url:". url keys as provided
- // by config.cache always have a string value that represents the contents of the resource at the given url. mid keys as provided
- // by configl.cache always have a function value that causes the same code to execute as if the module was script injected.
- //
- // Both kinds of key-value pairs are entered into cache via the function consumePendingCache, which may relocate keys as given
- // by any mappings *iff* the config.cache was received as part of a module resource request.
- //
- // Further, for mid keys, the implied url is computed and the value is entered into that key as well. This allows mapped modules
- // to retrieve cached items that may have arrived consequent to another namespace.
- //
- = {},
- urlKeyPrefix
- // the prefix to prepend to a URL key in the cache.
- = "url:",
- pendingCacheInsert
- // hash:(mid)-->(function)
- //
- // Gives a set of cache modules pending entry into cache. When cached modules are published to the loader, they are
- // entered into pendingCacheInsert; modules are then pressed into cache upon (1) AMD define or (2) upon receiving another
- // independent set of cached modules. (1) is the usual case, and this case allows normalizing mids given in the pending
- // cache for the local configuration, possibly relocating modules.
- = {},
- dojoSniffConfig
- // map of configuration variables
- // give the data-dojo-config as sniffed from the document (if any)
- = {};
- if( 1 ){
- var consumePendingCacheInsert = function(referenceModule){
- var p, item, match, now, m;
- for(p in pendingCacheInsert){
- item = pendingCacheInsert[p];
- match = p.match(/^url\:(.+)/);
- if(match){
- cache[urlKeyPrefix + toUrl(match[1], referenceModule)] = item;
- }else if(p=="*now"){
- now = item;
- }else if(p!="*noref"){
- m = getModuleInfo(p, referenceModule);
- cache[m.mid] = cache[urlKeyPrefix + m.url] = item;
- }
- }
- if(now){
- now(createRequire(referenceModule));
- }
- pendingCacheInsert = {};
- },
- escapeString = function(s){
- return s.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, function(c){ return "\\" + c; });
- },
- computeMapProg = function(map, dest){
- // This routine takes a map as represented by a JavaScript object and initializes dest, a vector of
- // quads of (map-key, map-value, refex-for-map-key, length-of-map-key), sorted decreasing by length-
- // of-map-key. The regex looks for the map-key followed by either "/" or end-of-string at the beginning
- // of a the search source. Notice the map-value is irrelevent to the algorithm
- dest.splice(0, dest.length);
- for(var p in map){
- dest.push([
- p,
- map[p],
- new RegExp("^" + escapeString(p) + "(\/|$)"),
- p.length]);
- }
- dest.sort(function(lhs, rhs){ return rhs[3] - lhs[3]; });
- return dest;
- },
- fixupPackageInfo = function(packageInfo){
- // calculate the precise (name, location, main, mappings) for a package
- var name = packageInfo.name;
- if(!name){
- // packageInfo must be a string that gives the name
- name = packageInfo;
- packageInfo = {name:name};
- }
- packageInfo = mix({main:"main"}, packageInfo);
- packageInfo.location = packageInfo.location ? packageInfo.location : name;
- // packageMap is depricated in favor of AMD map
- if(packageInfo.packageMap){
- map[name] = packageInfo.packageMap;
- }
- if(!packageInfo.main.indexOf("./")){
- packageInfo.main = packageInfo.main.substring(2);
- }
- // now that we've got a fully-resolved package object, push it into the configuration
- packs[name] = packageInfo;
- },
- delayedModuleConfig
- // module config cannot be consummed until the loader is completely initialized; therefore, all
- // module config detected during booting is memorized and applied at the end of loader initialization
- // TODO: this is a bit of a kludge; all config should be moved to end of loader initialization, but
- // we'll delay this chore and do it with a final loader 1.x cleanup after the 2.x loader prototyping is complete
- = [],
- config = function(config, booting, referenceModule){
- for(var p in config){
- if(p=="waitSeconds"){
- req.waitms = (config[p] || 0) * 1000;
- }
- if(p=="cacheBust"){
- cacheBust = config[p] ? (isString(config[p]) ? config[p] : (new Date()).getTime() + "") : "";
- }
- if(p=="baseUrl" || p=="combo"){
- req[p] = config[p];
- }
- if( 1 && p=="async"){
- // falsy or "sync" => legacy sync loader
- // "xd" => sync but loading xdomain tree and therefore loading asynchronously (not configurable, set automatically by the loader)
- // "legacyAsync" => permanently in "xd" by choice
- // "debugAtAllCosts" => trying to load everything via script injection (not implemented)
- // otherwise, must be truthy => AMD
- // legacyMode: sync | legacyAsync | xd | false
- var mode = config[p];
- req.legacyMode = legacyMode = (isString(mode) && /sync|legacyAsync/.test(mode) ? mode : (!mode ? sync : false));
- req.async = !legacyMode;
- }
- if(config[p]!==hasCache){
- // accumulate raw config info for client apps which can use this to pass their own config
- req.rawConfig[p] = config[p];
- p!="has" && has.add("config-"+p, config[p], 0, booting);
- }
- }
- // make sure baseUrl exists
- if(!req.baseUrl){
- req.baseUrl = "./";
- }
- // make sure baseUrl ends with a slash
- if(!/\/$/.test(req.baseUrl)){
- req.baseUrl += "/";
- }
- // now do the special work for has, packages, packagePaths, paths, aliases, and cache
- for(p in config.has){
- has.add(p, config.has[p], 0, booting);
- }
- // for each package found in any packages config item, augment the packs map owned by the loader
- forEach(config.packages, fixupPackageInfo);
- // for each packagePath found in any packagePaths config item, augment the packageConfig
- // packagePaths is depricated; remove in 2.0
- for(baseUrl in config.packagePaths){
- forEach(config.packagePaths[baseUrl], function(packageInfo){
- var location = baseUrl + "/" + packageInfo;
- if(isString(packageInfo)){
- packageInfo = {name:packageInfo};
- }
- packageInfo.location = location;
- fixupPackageInfo(packageInfo);
- });
- }
- // notice that computeMapProg treats the dest as a reference; therefore, if/when that variable
- // is published (see dojo-publish-privates), the published variable will always hold a valid value.
- // this must come after all package processing since package processing may mutate map
- computeMapProg(mix(map, config.map), mapProgs);
- forEach(mapProgs, function(item){
- item[1] = computeMapProg(item[1], []);
- if(item[0]=="*"){
- mapProgs.star = item[1];
- }
- });
- // push in any paths and recompute the internal pathmap
- computeMapProg(mix(paths, config.paths), pathsMapProg);
- // aliases
- forEach(config.aliases, function(pair){
- if(isString(pair[0])){
- pair[0] = new RegExp("^" + escapeString(pair[0]) + "$");
- }
- aliases.push(pair);
- });
- if(booting){
- delayedModuleConfig.push({config:config.config});
- }else{
- for(p in config.config){
- var module = getModule(p, referenceModule);
- module.config = mix(module.config || {}, config.config[p]);
- }
- }
- // push in any new cache values
- if(config.cache){
- consumePendingCacheInsert();
- pendingCacheInsert = config.cache;
- if(config.cache["*noref"]){
- consumePendingCacheInsert();
- }
- }
- signal("config", [config, req.rawConfig]);
- };
- //
- // execute the various sniffs; userConfig can override and value
- //
- if(has("dojo-cdn") || 1 ){
- // the sniff regex looks for a src attribute ending in dojo.js, optionally preceeded with a path.
- // match[3] returns the path to dojo.js (if any) without the trailing slash. This is used for the
- // dojo location on CDN deployments and baseUrl when either/both of these are not provided
- // explicitly in the config data; this is the 1.6- behavior.
- var scripts = doc.getElementsByTagName("script"),
- i = 0,
- script, dojoDir, src, match;
- while(i < scripts.length){
- script = scripts[i++];
- if((src = script.getAttribute("src")) && (match = src.match(/(((.*)\/)|^)dojo\.js(\W|$)/i))){
- // sniff dojoDir and baseUrl
- dojoDir = match[3] || "";
- defaultConfig.baseUrl = defaultConfig.baseUrl || dojoDir;
- // sniff configuration on attribute in script element
- src = (script.getAttribute("data-dojo-config") || script.getAttribute("djConfig"));
- if(src){
- dojoSniffConfig = req.eval("({ " + src + " })", "data-dojo-config");
- }
- // sniff requirejs attribute
- if( 0 ){
- var dataMain = script.getAttribute("data-main");
- if(dataMain){
- dojoSniffConfig.deps = dojoSniffConfig.deps || [dataMain];
- }
- }
- break;
- }
- }
- }
- if( 0 ){
- // pass down doh.testConfig from parent as if it were a data-dojo-config
- try{
- if(window.parent != window && window.parent.require){
- var doh = window.parent.require("doh");
- doh && mix(dojoSniffConfig, doh.testConfig);
- }
- }catch(e){}
- }
- // configure the loader; let the user override defaults
- req.rawConfig = {};
- config(defaultConfig, 1);
- // do this before setting userConfig/sniffConfig to allow userConfig/sniff overrides
- if(has("dojo-cdn")){
- packs.dojo.location = dojoDir;
- if(dojoDir){
- dojoDir += "/";
- }
- packs.dijit.location = dojoDir + "../dijit/";
- packs.dojox.location = dojoDir + "../dojox/";
- }
- config(userConfig, 1);
- config(dojoSniffConfig, 1);
- }else{
- // no config API, assume defaultConfig has everything the loader needs...for the entire lifetime of the application
- paths = defaultConfig.paths;
- pathsMapProg = defaultConfig.pathsMapProg;
- packs = defaultConfig.packs;
- aliases = defaultConfig.aliases;
- mapProgs = defaultConfig.mapProgs;
- modules = defaultConfig.modules;
- cache = defaultConfig.cache;
- cacheBust = defaultConfig.cacheBust;
- // remember the default config for other processes (e.g., dojo/config)
- req.rawConfig = defaultConfig;
- }
- if( 0 ){
- req.combo = req.combo || {add:noop};
- var comboPending = 0,
- combosPending = [],
- comboPendingTimer = null;
- }
- // build the loader machinery iaw configuration, including has feature tests
- var injectDependencies = function(module){
- // checkComplete!=0 holds the idle signal; we're not idle if we're injecting dependencies
- guardCheckComplete(function(){
- forEach(module.deps, injectModule);
- if( 0 && comboPending && !comboPendingTimer){
- comboPendingTimer = setTimeout(function() {
- comboPending = 0;
- comboPendingTimer = null;
- req.combo.done(function(mids, url) {
- var onLoadCallback= function(){
- // defQ is a vector of module definitions 1-to-1, onto mids
- runDefQ(0, mids);
- checkComplete();
- };
- combosPending.push(mids);
- injectingModule = mids;
- req.injectUrl(url, onLoadCallback, mids);
- injectingModule = 0;
- }, req);
- }, 0);
- }
- });
- },
- contextRequire = function(a1, a2, a3, referenceModule, contextRequire){
- var module, syntheticMid;
- if(isString(a1)){
- // signature is (moduleId)
- module = getModule(a1, referenceModule, true);
- if(module && module.executed){
- return module.result;
- }
- throw makeError("undefinedModule", a1);
- }
- if(!isArray(a1)){
- // a1 is a configuration
- config(a1, 0, referenceModule);
- // juggle args; (a2, a3) may be (dependencies, callback)
- a1 = a2;
- a2 = a3;
- }
- if(isArray(a1)){
- // signature is (requestList [,callback])
- if(!a1.length){
- a2 && a2();
- }else{
- syntheticMid = "require*" + uid();
- // resolve the request list with respect to the reference module
- for(var mid, deps = [], i = 0; i < a1.length;){
- mid = a1[i++];
- deps.push(getModule(mid, referenceModule));
- }
- // construct a synthetic module to control execution of the requestList, and, optionally, callback
- module = mix(makeModuleInfo("", syntheticMid, 0, ""), {
- injected: arrived,
- deps: deps,
- def: a2 || noop,
- require: referenceModule ? referenceModule.require : req,
- gc: 1 //garbage collect
- });
- modules[module.mid] = module;
- // checkComplete!=0 holds the idle signal; we're not idle if we're injecting dependencies
- injectDependencies(module);
- // try to immediately execute
- // if already traversing a factory tree, then strict causes circular dependency to abort the execution; maybe
- // it's possible to execute this require later after the current traversal completes and avoid the circular dependency.
- // ...but *always* insist on immediate in synch mode
- var strict = checkCompleteGuard && legacyMode!=sync;
- guardCheckComplete(function(){
- execModule(module, strict);
- });
- if(!module.executed){
- // some deps weren't on board or circular dependency detected and strict; therefore, push into the execQ
- execQ.push(module);
- }
- checkComplete();
- }
- }
- return contextRequire;
- },
- createRequire = function(module){
- if(!module){
- return req;
- }
- var result = module.require;
- if(!result){
- result = function(a1, a2, a3){
- return contextRequire(a1, a2, a3, module, result);
- };
- module.require = mix(result, req);
- result.module = module;
- result.toUrl = function(name){
- return toUrl(name, module);
- };
- result.toAbsMid = function(mid){
- return toAbsMid(mid, module);
- };
- if( 0 ){
- result.undef = function(mid){
- req.undef(mid, module);
- };
- }
- if( 1 ){
- result.syncLoadNls = function(mid){
- var nlsModuleInfo = getModuleInfo(mid, module),
- nlsModule = modules[nlsModuleInfo.mid];
- if(!nlsModule || !nlsModule.executed){
- cached = cache[nlsModuleInfo.mid] || cache[urlKeyPrefix + nlsModuleInfo.url];
- if(cached){
- evalModuleText(cached);
- nlsModule = modules[nlsModuleInfo.mid];
- }
- }
- return nlsModule && nlsModule.executed && nlsModule.result;
- };
- }
- }
- return result;
- },
- execQ =
- // The list of modules that need to be evaluated.
- [],
- defQ =
- // The queue of define arguments sent to loader.
- [],
- waiting =
- // The set of modules upon which the loader is waiting for definition to arrive
- {},
- setRequested = function(module){
- module.injected = requested;
- waiting[module.mid] = 1;
- if(module.url){
- waiting[module.url] = module.pack || 1;
- }
- startTimer();
- },
- setArrived = function(module){
- module.injected = arrived;
- delete waiting[module.mid];
- if(module.url){
- delete waiting[module.url];
- }
- if(isEmpty(waiting)){
- clearTimer();
- 1 && legacyMode==xd && (legacyMode = sync);
- }
- },
- execComplete = req.idle =
- // says the loader has completed (or not) its work
- function(){
- return !defQ.length && isEmpty(waiting) && !execQ.length && !checkCompleteGuard;
- },
- runMapProg = function(targetMid, map){
- // search for targetMid in map; return the map item if found; falsy otherwise
- if(map){
- for(var i = 0; i < map.length; i++){
- if(map[i][2].test(targetMid)){
- return map[i];
- }
- }
- }
- return 0;
- },
- compactPath = function(path){
- var result = [],
- segment, lastSegment;
- path = path.replace(/\\/g, '/').split('/');
- while(path.length){
- segment = path.shift();
- if(segment==".." && result.length && lastSegment!=".."){
- result.pop();
- lastSegment = result[result.length - 1];
- }else if(segment!="."){
- result.push(lastSegment= segment);
- } // else ignore "."
- }
- return result.join("/");
- },
- makeModuleInfo = function(pid, mid, pack, url){
- if( 1 ){
- var xd= req.isXdUrl(url);
- return {pid:pid, mid:mid, pack:pack, url:url, executed:0, def:0, isXd:xd, isAmd:!!(xd || (packs[pid] && packs[pid].isAmd))};
- }else{
- return {pid:pid, mid:mid, pack:pack, url:url, executed:0, def:0};
- }
- },
- getModuleInfo_ = function(mid, referenceModule, packs, modules, baseUrl, mapProgs, pathsMapProg, alwaysCreate){
- // arguments are passed instead of using lexical variables so that this function my be used independent of the loader (e.g., the builder)
- // alwaysCreate is useful in this case so that getModuleInfo never returns references to real modules owned by the loader
- var pid, pack, midInPackage, mapProg, mapItem, url, result, isRelative, requestedMid;
- requestedMid = mid;
- isRelative = /^\./.test(mid);
- if(/(^\/)|(\:)|(\.js$)/.test(mid) || (isRelative && !referenceModule)){
- // absolute path or protocol of .js filetype, or relative path but no reference module and therefore relative to page
- // whatever it is, it's not a module but just a URL of some sort
- // note: pid===0 indicates the routine is returning an unmodified mid
- return makeModuleInfo(0, mid, 0, mid);
- }else{
- // relative module ids are relative to the referenceModule; get rid of any dots
- mid = compactPath(isRelative ? (referenceModule.mid + "/../" + mid) : mid);
- if(/^\./.test(mid)){
- throw makeError("irrationalPath", mid);
- }
- // at this point, mid is an absolute mid
- // map the mid
- if(referenceModule){
- mapItem = runMapProg(referenceModule.mid, mapProgs);
- }
- mapItem = mapItem || mapProgs.star;
- mapItem = mapItem && runMapProg(mid, mapItem[1]);
- if(mapItem){
- mid = mapItem[1] + mid.substring(mapItem[3]);
- }
- match = mid.match(/^([^\/]+)(\/(.+))?$/);
- pid = match ? match[1] : "";
- if((pack = packs[pid])){
- mid = pid + "/" + (midInPackage = (match[3] || pack.main));
- }else{
- pid = "";
- }
- // search aliases
- var candidateLength = 0,
- candidate = 0;
- forEach(aliases, function(pair){
- var match = mid.match(pair[0]);
- if(match && match.length>candidateLength){
- candidate = isFunction(pair[1]) ? mid.replace(pair[0], pair[1]) : pair[1];
- }
- });
- if(candidate){
- return getModuleInfo_(candidate, 0, packs, modules, baseUrl, mapProgs, pathsMapProg, alwaysCreate);
- }
- result = modules[mid];
- if(result){
- return alwaysCreate ? makeModuleInfo(result.pid, result.mid, result.pack, result.url) : modules[mid];
- }
- }
- // get here iff the sought-after module does not yet exist; therefore, we need to compute the URL given the
- // fully resolved (i.e., all relative indicators and package mapping resolved) module id
- // note: pid!==0 indicates the routine is returning a url that has .js appended unmodified mid
- mapItem = runMapProg(mid, pathsMapProg);
- if(mapItem){
- url = mapItem[1] + mid.substring(mapItem[3]);
- }else if(pid){
- url = pack.location + "/" + midInPackage;
- }else if(has("config-tlmSiblingOfDojo")){
- url = "../" + mid;
- }else{
- url = mid;
- }
- // if result is not absolute, add baseUrl
- if(!(/(^\/)|(\:)/.test(url))){
- url = baseUrl + url;
- }
- url += ".js";
- return makeModuleInfo(pid, mid, pack, compactPath(url));
- },
- getModuleInfo = function(mid, referenceModule){
- return getModuleInfo_(mid, referenceModule, packs, modules, req.baseUrl, mapProgs, pathsMapProg);
- },
- resolvePluginResourceId = function(plugin, prid, referenceModule){
- return plugin.normalize ? plugin.normalize(prid, function(mid){return toAbsMid(mid, referenceModule);}) : toAbsMid(prid, referenceModule);
- },
- dynamicPluginUidGenerator = 0,
- getModule = function(mid, referenceModule, immediate){
- // compute and optionally construct (if necessary) the module implied by the mid with respect to referenceModule
- var match, plugin, prid, result;
- match = mid.match(/^(.+?)\!(.*)$/);
- if(match){
- // name was <plugin-module>!<plugin-resource-id>
- plugin = getModule(match[1], referenceModule, immediate);
- if( 1 && legacyMode == sync && !plugin.executed){
- injectModule(plugin);
- if(plugin.injected===arrived && !plugin.executed){
- guardCheckComplete(function(){
- execModule(plugin);
- });
- }
- if(plugin.executed){
- promoteModuleToPlugin(plugin);
- }else{
- // we are in xdomain mode for some reason
- execQ.unshift(plugin);
- }
- }
- if(plugin.executed === executed && !plugin.load){
- // executed the module not knowing it was a plugin
- promoteModuleToPlugin(plugin);
- }
- // if the plugin has not been loaded, then can't resolve the prid and must assume this plugin is dynamic until we find out otherwise
- if(plugin.load){
- prid = resolvePluginResourceId(plugin, match[2], referenceModule);
- mid = (plugin.mid + "!" + (plugin.dynamic ? ++dynamicPluginUidGenerator + "!" : "") + prid);
- }else{
- prid = match[2];
- mid = plugin.mid + "!" + (++dynamicPluginUidGenerator) + "!waitingForPlugin";
- }
- result = {plugin:plugin, mid:mid, req:createRequire(referenceModule), prid:prid};
- }else{
- result = getModuleInfo(mid, referenceModule);
- }
- return modules[result.mid] || (!immediate && (modules[result.mid] = result));
- },
- toAbsMid = req.toAbsMid = function(mid, referenceModule){
- return getModuleInfo(mid, referenceModule).mid;
- },
- toUrl = req.toUrl = function(name, referenceModule){
- var moduleInfo = getModuleInfo(name+"/x", referenceModule),
- url= moduleInfo.url;
- return fixupUrl(moduleInfo.pid===0 ?
- // if pid===0, then name had a protocol or absolute path; either way, toUrl is the identify function in such cases
- name :
- // "/x.js" since getModuleInfo automatically appends ".js" and we appended "/x" to make name look likde a module id
- url.substring(0, url.length-5)
- );
- },
- nonModuleProps = {
- injected: arrived,
- executed: executed,
- def: nonmodule,
- result: nonmodule
- },
- makeCjs = function(mid){
- return modules[mid] = mix({mid:mid}, nonModuleProps);
- },
- cjsRequireModule = makeCjs("require"),
- cjsExportsModule = makeCjs("exports"),
- cjsModuleModule = makeCjs("module"),
- runFactory = function(module, args){
- req.trace("loader-run-factory", [module.mid]);
- var factory = module.def,
- result;
- 1 && syncExecStack.unshift(module);
- if(has("config-dojo-loader-catches")){
- try{
- result= isFunction(factory) ? factory.apply(null, args) : factory;
- }catch(e){
- signal(error, module.result = makeError("factoryThrew", [module, e]));
- }
- }else{
- result= isFunction(factory) ? factory.apply(null, args) : factory;
- }
- module.result = result===undefined && module.cjs ? module.cjs.exports : result;
- 1 && syncExecStack.shift(module);
- },
- abortExec = {},
- defOrder = 0,
- promoteModuleToPlugin = function(pluginModule){
- var plugin = pluginModule.result;
- pluginModule.dynamic = plugin.dynamic;
- pluginModule.normalize = plugin.normalize;
- pluginModule.load = plugin.load;
- return pluginModule;
- },
- resolvePluginLoadQ = function(plugin){
- // plugins is a newly executed module that has a loadQ waiting to run
- // step 1: traverse the loadQ and fixup the mid and prid; remember the map from original mid to new mid
- // recall the original mid was created before the plugin was on board and therefore it was impossible to
- // compute the final mid; accordingly, prid may or may not change, but the mid will definitely change
- var map = {};
- forEach(plugin.loadQ, function(pseudoPluginResource){
- // manufacture and insert the real module in modules
- var prid = resolvePluginResourceId(plugin, pseudoPluginResource.prid, pseudoPluginResource.req.module),
- mid = plugin.dynamic ? pseudoPluginResource.mid.replace(/waitingForPlugin$/, prid) : (plugin.mid + "!" + prid),
- pluginResource = mix(mix({}, pseudoPluginResource), {mid:mid, prid:prid, injected:0});
- if(!modules[mid]){
- // create a new (the real) plugin resource and inject it normally now that the plugin is on board
- injectPlugin(modules[mid] = pluginResource);
- } // else this was a duplicate request for the same (plugin, rid) for a nondynamic plugin
- // pluginResource is really just a placeholder with the wrong mid (because we couldn't calculate it until the plugin was on board)
- // mark is as arrived and delete it from modules; the real module was requested above
- map[pseudoPluginResource.mid] = modules[mid];
- setArrived(pseudoPluginResource);
- delete modules[pseudoPluginResource.mid];
- });
- plugin.loadQ = 0;
- // step2: replace all references to any placeholder modules with real modules
- var substituteModules = function(module){
- for(var replacement, deps = module.deps || [], i = 0; i<deps.length; i++){
- replacement = map[deps[i].mid];
- if(replacement){
- deps[i] = replacement;
- }
- }
- };
- for(var p in modules){
- substituteModules(modules[p]);
- }
- forEach(execQ, substituteModules);
- },
- finishExec = function(module){
- req.trace("loader-finish-exec", [module.mid]);
- module.executed = executed;
- module.defOrder = defOrder++;
- 1 && forEach(module.provides, function(cb){ cb(); });
- if(module.loadQ){
- // the module was a plugin
- promoteModuleToPlugin(module);
- resolvePluginLoadQ(module);
- }
- // remove all occurences of this module from the execQ
- for(i = 0; i < execQ.length;){
- if(execQ[i] === module){
- execQ.splice(i, 1);
- }else{
- i++;
- }
- }
- // delete references to synthetic modules
- if (/^require\*/.test(module.mid)) {
- delete modules[module.mid];
- }
- },
- circleTrace = [],
- execModule = function(module, strict){
- // run the dependency vector, then run the factory for module
- if(module.executed === executing){
- req.trace("loader-circular-dependency", [circleTrace.concat(module.mid).join("->")]);
- return (!module.def || strict) ? abortExec : (module.cjs && module.cjs.exports);
- }
- // at this point the module is either not executed or fully executed
- if(!module.executed){
- if(!module.def){
- return abortExec;
- }
- var mid = module.mid,
- deps = module.deps || [],
- arg, argResult,
- args = [],
- i = 0;
- if( 0 ){
- circleTrace.push(mid);
- req.trace("loader-exec-module", ["exec", circleTrace.length, mid]);
- }
- // for circular dependencies, assume the first module encountered was executed OK
- // modules that circularly depend on a module that has not run its factory will get
- // the premade cjs.exports===module.result. They can take a reference to this object and/or
- // add properties to it. When the module finally runs its factory, the factory can
- // read/write/replace this object. Notice that so long as the object isn't replaced, any
- // reference taken earlier while walking the deps list is still valid.
- module.executed = executing;
- while(i < deps.length){
- arg = deps[i++];
- argResult = ((arg === cjsRequireModule) ? createRequire(module) :
- ((arg === cjsExportsModule) ? module.cjs.exports :
- ((arg === cjsModuleModule) ? module.cjs :
- execModule(arg, strict))));
- if(argResult === abortExec){
- module.executed = 0;
- req.trace("loader-exec-module", ["abort", mid]);
- 0 && circleTrace.pop();
- return abortExec;
- }
- args.push(argResult);
- }
- runFactory(module, args);
- finishExec(module);
- 0 && circleTrace.pop();
- }
- // at this point the module is guaranteed fully executed
- return module.result;
- },
- checkCompleteGuard = 0,
- guardCheckComplete = function(proc){
- try{
- checkCompleteGuard++;
- proc();
- }finally{
- checkCompleteGuard--;
- }
- if(execComplete()){
- signal("idle", []);
- }
- },
- checkComplete = function(){
- // keep going through the execQ as long as at least one factory is executed
- // plugins, recursion, cached modules all make for many execution path possibilities
- if(checkCompleteGuard){
- return;
- }
- guardCheckComplete(function(){
- checkDojoRequirePlugin();
- for(var currentDefOrder, module, i = 0; i < execQ.length;){
- currentDefOrder = defOrder;
- module = execQ[i];
- execModule(module);
- if(currentDefOrder!=defOrder){
- // defOrder was bumped one or more times indicating something was executed (note, this indicates
- // the execQ was modified, maybe a lot (for example a later module causes an earlier module to execute)
- checkDojoRequirePlugin();
- i = 0;
- }else{
- // nothing happened; check the next module in the exec queue
- i++;
- }
- }
- });
- };
- if( 0 ){
- req.undef = function(moduleId, referenceModule){
- // In order to reload a module, it must be undefined (this routine) and then re-requested.
- // This is useful for testing frameworks (at least).
- var module = getModule(moduleId, referenceModule);
- setArrived(module);
- delete modules[module.mid];
- };
- }
- if( 1 ){
- if(has("dojo-loader-eval-hint-url")===undefined){
- has.add("dojo-loader-eval-hint-url", 1);
- }
- var fixupUrl= function(url){
- url += ""; // make sure url is a Javascript string (some paths may be a Java string)
- return url + (cacheBust ? ((/\?/.test(url) ? "&" : "?") + cacheBust) : "");
- },
- injectPlugin = function(
- module
- ){
- // injects the plugin module given by module; may have to inject the plugin itself
- var plugin = module.plugin;
- if(plugin.executed === executed && !plugin.load){
- // executed the module not knowing it was a plugin
- promoteModuleToPlugin(plugin);
- }
- var onLoad = function(def){
- module.result = def;
- setArrived(module);
- finishExec(module);
- checkComplete();
- };
- if(plugin.load){
- plugin.load(module.prid, module.req, onLoad);
- }else if(plugin.loadQ){
- plugin.loadQ.push(module);
- }else{
- // the unshift instead of push is important: we don't want plugins to execute as
- // dependencies of some other module because this may cause circles when the plugin
- // loadQ is run; also, generally, we want plugins to run early since they may load
- // several other modules and therefore can potentially unblock many modules
- plugin.loadQ = [module];
- execQ.unshift(plugin);
- injectModule(plugin);
- }
- },
- // for IE, injecting a module may result in a recursive execution if the module is in the cache
- cached = 0,
- injectingModule = 0,
- injectingCachedModule = 0,
- evalModuleText = function(text, module){
- // see def() for the injectingCachedModule bracket; it simply causes a short, safe curcuit
- if(has("config-stripStrict")){
- text = text.replace(/"use strict"/g, '');
- }
- injectingCachedModule = 1;
- if(has("config-dojo-loader-catches")){
- try{
- if(text===cached){
- cached.call(null);
- }else{
- req.eval(text, has("dojo-loader-eval-hint-url") ? module.url : module.mid);
- }
- }catch(e){
- signal(error, makeError("evalModuleThrew", module));
- }
- }else{
- if(text===cached){
- cached.call(null);
- }else{
- req.eval(text, has("dojo-loader-eval-hint-url") ? module.url : module.mid);
- }
- }
- injectingCachedModule = 0;
- },
- injectModule = function(module){
- // Inject the module. In the browser environment, this means appending a script element into
- // the document; in other environments, it means loading a file.
- //
- // If in synchronous mode, then get the module synchronously if it's not xdomainLoading.
- var mid = module.mid,
- url = module.url;
- if(module.executed || module.injected || waiting[mid] || (module.url && ((module.pack && waiting[module.url]===module.pack) || waiting[module.url]==1))){
- return;
- }
- setRequested(module);
- if( 0 ){
- var viaCombo = 0;
- if(module.plugin && module.plugin.isCombo){
- // a combo plugin; therefore, must be handled by combo service
- // the prid should have already been converted to a URL (if required by the plugin) during
- // the normalze process; in any event, there is no way for the loader to know how to
- // to the conversion; therefore the third argument is zero
- req.combo.add(module.plugin.mid, module.prid, 0, req);
- viaCombo = 1;
- }else if(!module.plugin){
- viaCombo = req.combo.add(0, module.mid, module.url, req);
- }
- if(viaCombo){
- comboPending= 1;
- return;
- }
- }
- if(module.plugin){
- injectPlugin(module);
- return;
- } // else a normal module (not a plugin)
- var onLoadCallback = function(){
- runDefQ(module);
- if(module.injected !== arrived){
- // the script that contained the module arrived and has been executed yet
- // nothing was added to the defQ (so it wasn't an AMD module) and the module
- // wasn't marked as arrived by dojo.provide (so it wasn't a v1.6- module);
- // therefore, it must not have been a module; adjust state accordingly
- setArrived(module);
- mix(module, nonModuleProps);
- req.trace("loader-define-nonmodule", [module.url]);
- }
- if( 1 && legacyMode){
- // must call checkComplete even in for sync loader because we may be in xdomainLoading mode;
- // but, if xd loading, then don't call checkComplete until out of the current sync traversal
- // in order to preserve order of execution of the dojo.required modules
- !syncExecStack.length && checkComplete();
- }else{
- checkComplete();
- }
- };
- cached = cache[mid] || cache[urlKeyPrefix + module.url];
- if(cached){
- req.trace("loader-inject", ["cache", module.mid, url]);
- evalModuleText(cached, module);
- onLoadCallback();
- return;
- }
- if( 1 && legacyMode){
- if(module.isXd){
- // switch to async mode temporarily; if current legacyMode!=sync, then is must be one of {legacyAsync, xd, false}
- legacyMode==sync && (legacyMode = xd);
- // fall through and load via script injection
- }else if(module.isAmd && legacyMode!=sync){
- // fall through and load via script injection
- }else{
- // mode may be sync, xd/legacyAsync, or async; module may be AMD or legacy; but module is always located on the same domain
- var xhrCallback = function(text){
- if(legacyMode==sync){
- // the top of syncExecStack gives the current synchronously executing module; the loader needs
- // to know this if it has to switch to async loading in the middle of evaluating a legacy module
- // this happens when a modules dojo.require's a module that must be loaded async because it's xdomain
- // (using unshift/shift because there is no back() methods for Javascript arrays)
- syncExecStack.unshift(module);
- evalModuleText(text, module);
- syncExecStack.shift();
- // maybe the module was an AMD module
- runDefQ(module);
- // legacy modules never get to defineModule() => cjs and injected never set; also evaluation implies executing
- if(!module.cjs){
- setArrived(module);
- finishExec(module);
- }
- if(module.finish){
- // while synchronously evaluating this module, dojo.require was applied referencing a module
- // that had to be loaded async; therefore, the loader stopped answering all dojo.require
- // requests so they could be answered completely in the correct sequence; module.finish gives
- // the list of dojo.requires that must be re-applied once all target modules are available;
- // make a synthetic module to execute the dojo.require's in the correct order
- // compute a guarnateed-unique mid for the synthetic finish module; remember the finish vector; remove it from the reference module
- // TODO: can we just leave the module.finish...what's it hurting?
- var finishMid = mid + "*finish",
- finish = module.finish;
- delete module.finish;
- def(finishMid, ["dojo", ("dojo/require!" + finish.join(",")).replace(/\./g, "/")], function(dojo){
- forEach(finish, function(mid){ dojo.require(mid); });
- });
- // unshift, not push, which causes the current traversal to be reattempted from the top
- execQ.unshift(getModule(finishMid));
- }
- onLoadCallback();
- }else{
- text = transformToAmd(module, text);
- if(text){
- evalModuleText(text, module);
- onLoadCallback();
- }else{
- // if transformToAmd returned falsy, then the module was already AMD and it can be script-injected
- // do so to improve debugability(even though it means another download...which probably won't happen with a good browser cache)
- injectingModule = module;
- req.injectUrl(fixupUrl(url), onLoadCallback, module);
- injectingModule = 0;
- }
- }
- };
- req.trace("loader-inject", ["xhr", module.mid, url, legacyMode!=sync]);
- if(has("config-dojo-loader-catches")){
- try{
- req.getText(url, legacyMode!=sync, xhrCallback);
- }catch(e){
- signal(error, makeError("xhrInjectFailed", [module, e]));
- }
- }else{
- req.getText(url, legacyMode!=sync, xhrCallback);
- }
- return;
- }
- } // else async mode or fell through in xdomain loading mode; either way, load by script injection
- req.trace("loader-inject", ["script", module.mid, url]);
- injectingModule = module;
- req.injectUrl(fixupUrl(url), onLoadCallback, module);
- injectingModule = 0;
- },
- defineModule = function(module, deps, def){
- req.trace("loader-define-module", [module.mid, deps]);
- if( 0 && module.plugin && module.plugin.isCombo){
- // the module is a plugin resource loaded by the combo service
- // note: check for module.plugin should be enough since normal plugin resources should
- // not follow this path; module.plugin.isCombo is future-proofing belt and suspenders
- module.result = isFunction(def) ? def() : def;
- setArrived(module);
- finishExec(module);
- return module;
- };
- var mid = module.mid;
- if(module.injected === arrived){
- signal(error, makeError("multipleDefine", module));
- return module;
- }
- mix(module, {
- deps: deps,
- def: def,
- cjs: {
- id: module.mid,
- uri: module.url,
- exports: (module.result = {}),
- setExports: function(exports){
- module.cjs.exports = exports;
- },
- config:function(){
- return module.config;
- }
- }
- });
- // resolve deps with respect to this module
- for(var i = 0; i < deps.length; i++){
- deps[i] = getModule(deps[i], module);
- }
- if( 1 && legacyMode && !waiting[mid]){
- // the module showed up without being asked for; it was probably in a <script> element
- injectDependencies(module);
- execQ.push(module);
- checkComplete();
- }
- setArrived(module);
- if(!isFunction(def) && !deps.length){
- module.result = def;
- finishExec(module);
- }
- return module;
- },
- runDefQ = function(referenceModule, mids){
- // defQ is an array of [id, dependencies, factory]
- // mids (if any) is a vector of mids given by a combo service
- var definedModules = [],
- module, args;
- while(defQ.length){
- args = defQ.shift();
- mids && (args[0]= mids.shift());
- // explicit define indicates possible multiple modules in a single file; delay injecting dependencies until defQ fully
- // processed since modules earlier in the queue depend on already-arrived modules that are later in the queue
- // TODO: what if no args[0] and no referenceModule
- module = (args[0] && getModule(args[0])) || referenceModule;
- definedModules.push([module, args[1], args[2]]);
- }
- consumePendingCacheInsert(referenceModule);
- forEach(definedModules, function(args){
- injectDependencies(defineModule.apply(null, args));
- });
- };
- }
- var timerId = 0,
- clearTimer = noop,
- startTimer = noop;
- if( 1 ){
- // Timer machinery that monitors how long the loader is waiting and signals an error when the timer runs out.
- clearTimer = function(){
- timerId && clearTimeout(timerId);
- timerId = 0;
- },
- startTimer = function(){
- clearTimer();
- if(req.waitms){
- timerId = window.setTimeout(function(){
- clearTimer();
- signal(error, makeError("timeout", waiting));
- }, req.waitms);
- }
- };
- }
- if( 1 ){
- // the typically unnecessary !! in front of doc.attachEvent is due to an opera bug; see #15096
- has.add("ie-event-behavior", !!doc.attachEvent && (typeof opera === "undefined" || opera.toString() != "[object Opera]"));
- }
- if( 1 && ( 1 || 1 )){
- var domOn = function(node, eventName, ieEventName, handler){
- // Add an event listener to a DOM node using the API appropriate for the current browser;
- // return a function that will disconnect the listener.
- if(!has("ie-event-behavior")){
- node.addEventListener(eventName, handler, false);
- return function(){
- node.removeEventListener(eventName, handler, false);
- };
- }else{
- node.attachEvent(ieEventName, handler);
- return function(){
- node.detachEvent(ieEventName, handler);
- };
- }
- },
- windowOnLoadListener = domOn(window, "load", "onload", function(){
- req.pageLoaded = 1;
- doc.readyState!="complete" && (doc.readyState = "complete");
- windowOnLoadListener();
- });
- if( 1 ){
- // if the loader is on the page, there must be at least one script element
- // getting its parent and then doing insertBefore solves the "Operation Aborted"
- // error in IE from appending to a node that isn't properly closed; see
- // dojo/tests/_base/loader/requirejs/simple-badbase.html for an example
- var sibling = doc.getElementsByTagName("script")[0],
- insertPoint= sibling.parentNode;
- req.injectUrl = function(url, callback, owner){
- // insert a script element to the insert-point element with src=url;
- // apply callback upon detecting the script has loaded.
- var node = owner.node = doc.createElement("script"),
- onLoad = function(e){
- e = e || window.event;
- var node = e.target || e.srcElement;
- if(e.type === "load" || /complete|loaded/.test(node.readyState)){
- loadDisconnector();
- errorDisconnector();
- callback && callback();
- }
- },
- loadDisconnector = domOn(node, "load", "onreadystatechange", onLoad),
- errorDisconnector = domOn(node, "error", "onerror", function(e){
- loadDisconnector();
- errorDisconnector();
- signal(error, makeError("scriptError", [url, e]));
- });
- node.type = "text/javascript";
- node.charset = "utf-8";
- node.src = url;
- insertPoint.insertBefore(node, sibling);
- return node;
- };
- }
- }
- if( 1 ){
- req.log = function(){
- try{
- for(var i = 0; i < arguments.length; i++){
- console.log(arguments[i]);
- }
- }catch(e){}
- };
- }else{
- req.log = noop;
- }
- if( 0 ){
- var trace = req.trace = function(
- group, // the trace group to which this application belongs
- args // the contents of the trace
- ){
- ///
- // Tracing interface by group.
- //
- // Sends the contents of args to the console iff (req.trace.on && req.trace[group])
- if(trace.on && trace.group[group]){
- signal("trace", [group, args]);
- for(var arg, dump = [], text= "trace:" + group + (args.length ? (":" + args[0]) : ""), i= 1; i<args.length;){
- arg = args[i++];
- if(isString(arg)){
- text += ", " + arg;
- }else{
- dump.push(arg);
- }
- }
- req.log(text);
- dump.length && dump.push(".");
- req.log.apply(req, dump);
- }
- };
- mix(trace, {
- on:1,
- group:{},
- set:function(group, value){
- if(isString(group)){
- trace.group[group]= value;
- }else{
- mix(trace.group, group);
- }
- }
- });
- trace.set(mix(mix(mix({}, defaultConfig.trace), userConfig.trace), dojoSniffConfig.trace));
- on("config", function(config){
- config.trace && trace.set(config.trace);
- });
- }else{
- req.trace = noop;
- }
- var def = function(
- mid, //(commonjs.moduleId, optional) list of modules to be loaded before running factory
- dependencies, //(array of commonjs.moduleId, optional)
- factory //(any)
- ){
- ///
- // Advises the loader of a module factory. //Implements http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition.
- ///
- //note
- // CommonJS factory scan courtesy of http://requirejs.org
- var arity = arguments.length,
- defaultDeps = ["require", "exports", "module"],
- // the predominate signature...
- args = [0, mid, dependencies];
- if(arity==1){
- args = [0, (isFunction(mid) ? defaultDeps : []), mid];
- }else if(arity==2 && isString(mid)){
- args = [mid, (isFunction(dependencies) ? defaultDeps : []), dependencies];
- }else if(arity==3){
- args = [mid, dependencies, factory];
- }
- if( 0 && args[1]===defaultDeps){
- args[2].toString()
- .replace(/(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg, "")
- .replace(/require\(["']([\w\!\-_\.\/]+)["']\)/g, function(match, dep){
- args[1].push(dep);
- });
- }
- req.trace("loader-define", args.slice(0, 2));
- var targetModule = args[0] && getModule(args[0]),
- module;
- if(targetModule && !waiting[targetModule.mid]){
- // given a mid that hasn't been requested; therefore, defined through means other than injecting
- // consequent to a require() or define() application; examples include defining modules on-the-fly
- // due to some code path or including a module in a script element. In any case,
- // there is no callback waiting to finish processing and nothing to trigger the defQ and the
- // dependencies are never requested; therefore, do it here.
- injectDependencies(defineModule(targetModule, args[1], args[2]));
- }else if(!has("ie-event-behavior") || ! 1 || injectingCachedModule){
- // not IE path: anonymous module and therefore must have been injected; therefore, onLoad will fire immediately
- // after script finishes being evaluated and the defQ can be run from that callback to detect the module id
- defQ.push(args);
- }else{
- // IE path: possibly anonymous module and therefore injected; therefore, cannot depend on 1-to-1,
- // in-order exec of onLoad with script eval (since it's IE) and must manually detect here
- targetModule = targetModule || injectingModule;
- if(!targetModule){
- for(mid in waiting){
- module = modules[mid];
- if(module && module.node && module.node.readyState === 'interactive'){
- targetModule = module;
- break;
- }
- }
- if( 0 && !targetModule){
- for(var i = 0; i<combosPending.length; i++){
- targetModule = combosPending[i];
- if(targetModule.node && targetModule.node.readyState === 'interactive'){
- break;
- }
- targetModule= 0;
- }
- }
- }
- if( 0 && isArray(targetModule)){
- injectDependencies(defineModule(getModule(targetModule.shift()), args[1], args[2]));
- if(!targetModule.length){
- combosPending.splice(i, 1);
- }
- }else if(targetModule){
- consumePendingCacheInsert(targetModule);
- injectDependencies(defineModule(targetModule, args[1], args[2]));
- }else{
- signal(error, makeError("ieDefineFailed", args[0]));
- }
- checkComplete();
- }
- };
- def.amd = {
- vendor:"dojotoolkit.org"
- };
- if( 0 ){
- req.def = def;
- }
- // allow config to override default implemention of named functions; this is useful for
- // non-browser environments, e.g., overriding injectUrl, getText, log, etc. in node.js, Rhino, etc.
- // also useful for testing and monkey patching loader
- mix(mix(req, defaultConfig.loaderPatch), userConfig.loaderPatch);
- // now that req is fully initialized and won't change, we can hook it up to the error signal
- on(error, function(arg){
- try{
- console.error(arg);
- if(arg instanceof Error){
- for(var p in arg){
- console.log(p + ":", arg[p]);
- }
- console.log(".");
- }
- }catch(e){}
- });
- // always publish these
- mix(req, {
- uid:uid,
- cache:cache,
- packs:packs
- });
- if( 0 ){
- mix(req, {
- // these may be interesting to look at when debugging
- paths:paths,
- aliases:aliases,
- modules:modules,
- legacyMode:legacyMode,
- execQ:execQ,
- defQ:defQ,
- waiting:waiting,
- // these are used for testing
- // TODO: move testing infrastructure to a different has feature
- packs:packs,
- mapProgs:mapProgs,
- pathsMapProg:pathsMapProg,
- listenerQueues:listenerQueues,
- // these are used by the builder (at least)
- computeMapProg:computeMapProg,
- runMapProg:runMapProg,
- compactPath:compactPath,
- getModuleInfo:getModuleInfo_
- });
- }
- // the loader can be defined exactly once; look for global define which is the symbol AMD loaders are
- // *required* to define (as opposed to require, which is optional)
- if(global.define){
- if( 1 ){
- signal(error, makeError("defineAlreadyDefined", 0));
- }
- return;
- }else{
- global.define = def;
- global.require = req;
- if( 0 ){
- require= req;
- }
- }
- if( 0 && req.combo && req.combo.plugins){
- var plugins = req.combo.plugins,
- pluginName;
- for(pluginName in plugins){
- mix(mix(getModule(pluginName), plugins[pluginName]), {isCombo:1, executed:"executed", load:1});
- }
- }
- if( 1 ){
- forEach(delayedModuleConfig, function(c){ config(c); });
- var bootDeps = dojoSniffConfig.deps || userConfig.deps || defaultConfig.deps,
- bootCallback = dojoSniffConfig.callback || userConfig.callback || defaultConfig.callback;
- req.boot = (bootDeps || bootCallback) ? [bootDeps || [], bootCallback] : 0;
- }
- if(! 1 ){
- !req.async && req(["dojo"]);
- req.boot && req.apply(null, req.boot);
- }
- })
- (this.dojoConfig || this.djConfig || this.require || {}, {
- async:0,
- hasCache:{
- 'config-selectorEngine':"acme",
- 'config-tlmSiblingOfDojo':1,
- 'dojo-built':1,
- 'dojo-loader':1,
- dom:1,
- 'host-browser':1
- },
- packages:[
- {
- location:"../dijit",
- name:"dijit"
- },
- {
- location:"../dojox",
- name:"dojox"
- },
- {
- location:".",
- name:"dojo"
- }
- ]
- });require({cache:{
- 'dojo/_base/fx':function(){
- define(["./kernel", "./config", /*===== "./declare", =====*/ "./lang", "../Evented", "./Color", "./connect", "./sniff", "../dom", "../dom-style"],
- function(dojo, config, /*===== declare, =====*/ lang, Evented, Color, connect, has, dom, style){
- // module:
- // dojo/_base/fx
- // notes:
- // Animation loosely package based on Dan Pupius' work, contributed under CLA; see
- // http://pupius.co.uk/js/Toolkit.Drawing.js
- var _mixin = lang.mixin;
- // Module export
- var basefx = {
- // summary:
- // This module defines the base dojo/_base/fx implementation.
- };
- var _Line = basefx._Line = function(/*int*/ start, /*int*/ end){
- // summary:
- // Object used to generate values from a start value to an end value
- // start: int
- // Beginning value for range
- // end: int
- // Ending value for range
- this.start = start;
- this.end = end;
- };
- _Line.prototype.getValue = function(/*float*/ n){
- // summary:
- // Returns the point on the line
- // n:
- // a floating point number greater than 0 and less than 1
- return ((this.end - this.start) * n) + this.start; // Decimal
- };
- var Animation = basefx.Animation = function(args){
- // summary:
- // A generic animation class that fires callbacks into its handlers
- // object at various states.
- // description:
- // A generic animation class that fires callbacks into its handlers
- // object at various states. Nearly all dojo animation functions
- // return an instance of this method, usually without calling the
- // .play() method beforehand. Therefore, you will likely need to
- // call .play() on instances of `Animation` when one is
- // returned.
- // args: Object
- // The 'magic argument', mixing all the properties into this
- // animation instance.
- _mixin(this, args);
- if(lang.isArray(this.curve)){
- this.curve = new _Line(this.curve[0], this.curve[1]);
- }
- };
- Animation.prototype = new Evented();
- lang.extend(Animation, {
- // duration: Integer
- // The time in milliseconds the animation will take to run
- duration: 350,
- /*=====
- // curve: _Line|Array
- // A two element array of start and end values, or a `_Line` instance to be
- // used in the Animation.
- curve: null,
- // easing: Function?
- // A Function to adjust the acceleration (or deceleration) of the progress
- // across a _Line
- easing: null,
- =====*/
- // repeat: Integer?
- // The number of times to loop the animation
- repeat: 0,
- // rate: Integer?
- // the time in milliseconds to wait before advancing to next frame
- // (used as a fps timer: 1000/rate = fps)
- rate: 20 /* 50 fps */,
- /*=====
- // delay: Integer?
- // The time in milliseconds to wait before starting animation after it
- // has been .play()'ed
- delay: null,
- // beforeBegin: Event?
- // Synthetic event fired before a Animation begins playing (synchronous)
- beforeBegin: null,
- // onBegin: Event?
- // Synthetic event fired as a Animation begins playing (useful?)
- onBegin: null,
- // onAnimate: Event?
- // Synthetic event fired at each interval of the Animation
- onAnimate: null,
- // onEnd: Event?
- // Synthetic event fired after the final frame of the Animation
- onEnd: null,
- // onPlay: Event?
- // Synthetic event fired any time the Animation is play()'ed
- onPlay: null,
- // onPause: Event?
- // Synthetic event fired when the Animation is paused
- onPause: null,
- // onStop: Event
- // Synthetic event fires when the Animation is stopped
- onStop: null,
- =====*/
- _percent: 0,
- _startRepeatCount: 0,
- _getStep: function(){
- var _p = this._percent,
- _e = this.easing
- ;
- return _e ? _e(_p) : _p;
- },
- _fire: function(/*Event*/ evt, /*Array?*/ args){
- // summary:
- // Convenience function. Fire event "evt" and pass it the
- // arguments specified in "args".
- // description:
- // Convenience function. Fire event "evt" and pass it the
- // arguments specified in "args".
- // Fires the callback in the scope of this Animation
- // instance.
- // evt:
- // The event to fire.
- // args:
- // The arguments to pass to the event.
- var a = args||[];
- if(this[evt]){
- if(config.debugAtAllCosts){
- this[evt].apply(this, a);
- }else{
- try{
- this[evt].apply(this, a);
- }catch(e){
- // squelch and log because we shouldn't allow exceptions in
- // synthetic event handlers to cause the internal timer to run
- // amuck, potentially pegging the CPU. I'm not a fan of this
- // squelch, but hopefully logging will make it clear what's
- // going on
- console.error("exception in animation handler for:", evt);
- console.error(e);
- }
- }
- }
- return this; // Animation
- },
- play: function(/*int?*/ delay, /*Boolean?*/ gotoStart){
- // summary:
- // Start the animation.
- // delay:
- // How many milliseconds to delay before starting.
- // gotoStart:
- // If true, starts the animation from the beginning; otherwise,
- // starts it from its current position.
- // returns: Animation
- // The instance to allow chaining.
- var _t = this;
- if(_t._delayTimer){ _t._clearTimer(); }
- if(gotoStart){
- _t._stopTimer();
- _t._active = _t._paused = false;
- _t._percent = 0;
- }else if(_t._active && !_t._paused){
- return _t;
- }
- _t._fire("beforeBegin", [_t.node]);
- var de = delay || _t.delay,
- _p = lang.hitch(_t, "_play", gotoStart);
- if(de > 0){
- _t._delayTimer = setTimeout(_p, de);
- return _t;
- }
- _p();
- return _t; // Animation
- },
- _play: function(gotoStart){
- var _t = this;
- if(_t._delayTimer){ _t._clearTimer(); }
- _t._startTime = new Date().valueOf();
- if(_t._paused){
- _t._startTime -= _t.duration * _t._percent;
- }
- _t._active = true;
- _t._paused = false;
- var value = _t.curve.getValue(_t._getStep());
- if(!_t._percent){
- if(!_t._startRepeatCount){
- _t._startRepeatCount = _t.repeat;
- }
- _t._fire("onBegin", [value]);
- }
- _t._fire("onPlay", [value]);
- _t._cycle();
- return _t; // Animation
- },
- pause: function(){
- // summary:
- // Pauses a running animation.
- var _t = this;
- if(_t._delayTimer){ _t._clearTimer(); }
- _t._stopTimer();
- if(!_t._active){ return _t; /*Animation*/ }
- _t._paused = true;
- _t._fire("onPause", [_t.curve.getValue(_t._getStep())]);
- return _t; // Animation
- },
- gotoPercent: function(/*Decimal*/ percent, /*Boolean?*/ andPlay){
- // summary:
- // Sets the progress of the animation.
- // percent:
- // A percentage in decimal notation (between and including 0.0 and 1.0).
- // andPlay:
- // If true, play the animation after setting the progress.
- var _t = this;
- _t._stopTimer();
- _t._active = _t._paused = true;
- _t._percent = percent;
- if(andPlay){ _t.play(); }
- return _t; // Animation
- },
- stop: function(/*boolean?*/ gotoEnd){
- // summary:
- // Stops a running animation.
- // gotoEnd:
- // If true, the animation will end.
- var _t = this;
- if(_t._delayTimer){ _t._clearTimer(); }
- if(!_t._timer){ return _t; /* Animation */ }
- _t._stopTimer();
- if(gotoEnd){
- _t._percent = 1;
- }
- _t._fire("onStop", [_t.curve.getValue(_t._getStep())]);
- _t._active = _t._paused = false;
- return _t; // Animation
- },
- status: function(){
- // summary:
- // Returns a string token representation of the status of
- // the animation, one of: "paused", "playing", "stopped"
- if(this._active){
- return this._paused ? "paused" : "playing"; // String
- }
- return "stopped"; // String
- },
- _cycle: function(){
- var _t = this;
- if(_t._active){
- var curr = new Date().valueOf();
- // Allow durations of 0 (instant) by setting step to 1 - see #13798
- var step = _t.duration === 0 ? 1 : (curr - _t._startTime) / (_t.duration);
- if(step >= 1){
- step = 1;
- }
- _t._percent = step;
- // Perform easing
- if(_t.easing){
- step = _t.easing(step);
- }
- _t._fire("onAnimate", [_t.curve.getValue(step)]);
- if(_t._percent < 1){
- _t._startTimer();
- }else{
- _t._active = false;
- if(_t.repeat > 0){
- _t.repeat--;
- _t.play(null, true);
- }else if(_t.repeat == -1){
- _t.play(null, true);
- }else{
- if(_t._startRepeatCount){
- _t.repeat = _t._startRepeatCount;
- _t._startRepeatCount = 0;
- }
- }
- _t._percent = 0;
- _t._fire("onEnd", [_t.node]);
- !_t.repeat && _t._stopTimer();
- }
- }
- return _t; // Animation
- },
- _clearTimer: function(){
- // summary:
- // Clear the play delay timer
- clearTimeout(this._delayTimer);
- delete this._delayTimer;
- }
- });
- // the local timer, stubbed into all Animation instances
- var ctr = 0,
- timer = null,
- runner = {
- run: function(){}
- };
- lang.extend(Animation, {
- _startTimer: function(){
- if(!this._timer){
- this._timer = connect.connect(runner, "run", this, "_cycle");
- ctr++;
- }
- if(!timer){
- timer = setInterval(lang.hitch(runner, "run"), this.rate);
- }
- },
- _stopTimer: function(){
- if(this._timer){
- connect.disconnect(this._timer);
- this._timer = null;
- ctr--;
- }
- if(ctr <= 0){
- clearInterval(timer);
- timer = null;
- ctr = 0;
- }
- }
- });
- var _makeFadeable =
- has("ie") ? function(node){
- // only set the zoom if the "tickle" value would be the same as the
- // default
- var ns = node.style;
- // don't set the width to auto if it didn't already cascade that way.
- // We don't want to f anyones designs
- if(!ns.width.length && style.get(node, "width") == "auto"){
- ns.width = "auto";
- }
- } :
- function(){};
- basefx._fade = function(/*Object*/ args){
- // summary:
- // Returns an animation that will fade the node defined by
- // args.node from the start to end values passed (args.start
- // args.end) (end is mandatory, start is optional)
- args.node = dom.byId(args.node);
- var fArgs = _mixin({ properties: {} }, args),
- props = (fArgs.properties.opacity = {});
- props.start = !("start" in fArgs) ?
- function(){
- return +style.get(fArgs.node, "opacity")||0;
- } : fArgs.start;
- props.end = fArgs.end;
- var anim = basefx.animateProperty(fArgs);
- connect.connect(anim, "beforeBegin", lang.partial(_makeFadeable, fArgs.node));
- return anim; // Animation
- };
- /*=====
- var __FadeArgs = declare(null, {
- // node: DOMNode|String
- // The node referenced in the animation
- // duration: Integer?
- // Duration of the animation in milliseconds.
- // easing: Function?
- // An easing function.
- });
- =====*/
- basefx.fadeIn = function(/*__FadeArgs*/ args){
- // summary:
- // Returns an animation that will fade node defined in 'args' from
- // its current opacity to fully opaque.
- return basefx._fade(_mixin({ end: 1 }, args)); // Animation
- };
- basefx.fadeOut = function(/*__FadeArgs*/ args){
- // summary:
- // Returns an animation that will fade node defined in 'args'
- // from its current opacity to fully transparent.
- return basefx._fade(_mixin({ end: 0 }, args)); // Animation
- };
- basefx._defaultEasing = function(/*Decimal?*/ n){
- // summary:
- // The default easing function for Animation(s)
- return 0.5 + ((Math.sin((n + 1.5) * Math.PI)) / 2); // Decimal
- };
- var PropLine = function(properties){
- // PropLine is an internal class which is used to model the values of
- // an a group of CSS properties across an animation lifecycle. In
- // particular, the "getValue" function handles getting interpolated
- // values between start and end for a particular CSS value.
- this._properties = properties;
- for(var p in properties){
- var prop = properties[p];
- if(prop.start instanceof Color){
- // create a reusable temp color object to keep intermediate results
- prop.tempColor = new Color();
- }
- }
- };
- PropLine.prototype.getValue = function(r){
- var ret = {};
- for(var p in this._properties){
- var prop = this._properties[p],
- start = prop.start;
- if(start instanceof Color){
- ret[p] = Color.blendColors(start, prop.end, r, prop.tempColor).toCss();
- }else if(!lang.isArray(start)){
- ret[p] = ((prop.end - start) * r) + start + (p != "opacity" ? prop.units || "px" : 0);
- }
- }
- return ret;
- };
- /*=====
- var __AnimArgs = declare(__FadeArgs, {
- // properties: Object?
- // A hash map of style properties to Objects describing the transition,
- // such as the properties of _Line with an additional 'units' property
- properties: {}
- //TODOC: add event callbacks
- });
- =====*/
- basefx.animateProperty = function(/*__AnimArgs*/ args){
- // summary:
- // Returns an animation that will transition the properties of
- // node defined in `args` depending how they are defined in
- // `args.properties`
- //
- // description:
- // Foundation of most `dojo/_base/fx`
- // animations. It takes an object of "properties" corresponding to
- // style properties, and animates them in parallel over a set
- // duration.
- //
- // example:
- // A simple animation that changes the width of the specified node.
- // | basefx.animateProperty({
- // | node: "nodeId",
- // | properties: { width: 400 },
- // | }).play();
- // Dojo figures out the start value for the width and converts the
- // integer specified for the width to the more expressive but
- // verbose form `{ width: { end: '400', units: 'px' } }` which you
- // can also specify directly. Defaults to 'px' if omitted.
- //
- // example:
- // Animate width, height, and padding over 2 seconds... the
- // pedantic way:
- // | basefx.animateProperty({ node: node, duration:2000,
- // | properties: {
- // | width: { start: '200', end: '400', units:"px" },
- // | height: { start:'200', end: '400', units:"px" },
- // | paddingTop: { start:'5', end:'50', units:"px" }
- // | }
- // | }).play();
- // Note 'paddingTop' is used over 'padding-top'. Multi-name CSS properties
- // are written using "mixed case", as the hyphen is illegal as an object key.
- //
- // example:
- // Plug in a different easing function and register a callback for
- // when the animation ends. Easing functions accept values between
- // zero and one and return a value on that basis. In this case, an
- // exponential-in curve.
- // | basefx.animateProperty({
- // | node: "nodeId",
- // | // dojo figures out the start value
- // | properties: { width: { end: 400 } },
- // | easing: function(n){
- // | return (n==0) ? 0 : Math.pow(2, 10 * (n - 1));
- // | },
- // | onEnd: function(node){
- // | // called when the animation finishes. The animation
- // | // target is passed to this function
- // | }
- // | }).play(500); // delay playing half a second
- //
- // example:
- // Like all `Animation`s, animateProperty returns a handle to the
- // Animation instance, which fires the events common to Dojo FX. Use `aspect.after`
- // to access these events outside of the Animation definition:
- // | var anim = basefx.animateProperty({
- // | node:"someId",
- // | properties:{
- // | width:400, height:500
- // | }
- // | });
- // | aspect.after(anim, "onEnd", function(){
- // | console.log("animation ended");
- // | }, true);
- // | // play the animation now:
- // | anim.play();
- //
- // example:
- // Each property can be a function whose return value is substituted along.
- // Additionally, each measurement (eg: start, end) can be a function. The node
- // reference is passed directly to callbacks.
- // | basefx.animateProperty({
- // | node:"mine",
- // | properties:{
- // | height:function(node){
- // | // shrink this node by 50%
- // | return domGeom.position(node).h / 2
- // | },
- // | width:{
- // | start:function(node){ return 100; },
- // | end:function(node){ return 200; }
- // | }
- // | }
- // | }).play();
- //
- var n = args.node = dom.byId(args.node);
- if(!args.easing){ args.easing = dojo._defaultEasing; }
- var anim = new Animation(args);
- connect.connect(anim, "beforeBegin", anim, function(){
- var pm = {};
- for(var p in this.properties){
- // Make shallow copy of properties into pm because we overwrite
- // some values below. In particular if start/end are functions
- // we don't want to overwrite them or the functions won't be
- // called if the animation is reused.
- if(p == "width" || p == "height"){
- this.node.display = "block";
- }
- var prop = this.properties[p];
- if(lang.isFunction(prop)){
- prop = prop(n);
- }
- prop = pm[p] = _mixin({}, (lang.isObject(prop) ? prop: { end: prop }));
- if(lang.isFunction(prop.start)){
- prop.start = prop.start(n);
- }
- if(lang.isFunction(prop.end)){
- prop.end = prop.end(n);
- }
- var isColor = (p.toLowerCase().indexOf("color") >= 0);
- function getStyle(node, p){
- // domStyle.get(node, "height") can return "auto" or "" on IE; this is more reliable:
- var v = { height: node.offsetHeight, width: node.offsetWidth }[p];
- if(v !== undefined){ return v; }
- v = style.get(node, p);
- return (p == "opacity") ? +v : (isColor ? v : parseFloat(v));
- }
- if(!("end" in prop)){
- prop.end = getStyle(n, p);
- }else if(!("start" in prop)){
- prop.start = getStyle(n, p);
- }
- if(isColor){
- prop.start = new Color(prop.start);
- prop.end = new Color(prop.end);
- }else{
- prop.start = (p == "opacity") ? +prop.start : parseFloat(prop.start);
- }
- }
- this.curve = new PropLine(pm);
- });
- connect.connect(anim, "onAnimate", lang.hitch(style, "set", anim.node));
- return anim; // Animation
- };
- basefx.anim = function( /*DOMNode|String*/ node,
- /*Object*/ properties,
- /*Integer?*/ duration,
- /*Function?*/ easing,
- /*Function?*/ onEnd,
- /*Integer?*/ delay){
- // summary:
- // A simpler interface to `animateProperty()`, also returns
- // an instance of `Animation` but begins the animation
- // immediately, unlike nearly every other Dojo animation API.
- // description:
- // Simpler (but somewhat less powerful) version
- // of `animateProperty`. It uses defaults for many basic properties
- // and allows for positional parameters to be used in place of the
- // packed "property bag" which is used for other Dojo animation
- // methods.
- //
- // The `Animation` object returned will be already playing, so
- // calling play() on it again is (usually) a no-op.
- // node:
- // a DOM node or the id of a node to animate CSS properties on
- // duration:
- // The number of milliseconds over which the animation
- // should run. Defaults to the global animation default duration
- // (350ms).
- // easing:
- // An easing function over which to calculate acceleration
- // and deceleration of the animation through its duration.
- // A default easing algorithm is provided, but you may
- // plug in any you wish. A large selection of easing algorithms
- // are available in `dojo/fx/easing`.
- // onEnd:
- // A function to be called when the animation finishes
- // running.
- // delay:
- // The number of milliseconds to delay beginning the
- // animation by. The default is 0.
- // example:
- // Fade out a node
- // | basefx.anim("id", { opacity: 0 });
- // example:
- // Fade out a node over a full second
- // | basefx.anim("id", { opacity: 0 }, 1000);
- return basefx.animateProperty({ // Animation
- node: node,
- duration: duration || Animation.prototype.duration,
- properties: properties,
- easing: easing,
- onEnd: onEnd
- }).play(delay || 0);
- };
- if( 1 ){
- _mixin(dojo, basefx);
- // Alias to drop come 2.0:
- dojo._Animation = Animation;
- }
- return basefx;
- });
- },
- 'dojo/dom-form':function(){
- define(["./_base/lang", "./dom", "./io-query", "./json"], function(lang, dom, ioq, json){
- // module:
- // dojo/dom-form
- function setValue(/*Object*/ obj, /*String*/ name, /*String*/ value){
- // summary:
- // For the named property in object, set the value. If a value
- // already exists and it is a string, convert the value to be an
- // array of values.
- // Skip it if there is no value
- if(value === null){
- return;
- }
- var val = obj[name];
- if(typeof val == "string"){ // inline'd type check
- obj[name] = [val, value];
- }else if(lang.isArray(val)){
- val.push(value);
- }else{
- obj[name] = value;
- }
- }
- var exclude = "file|submit|image|reset|button";
- var form = {
- // summary:
- // This module defines form-processing functions.
- fieldToObject: function fieldToObject(/*DOMNode|String*/ inputNode){
- // summary:
- // Serialize a form field to a JavaScript object.
- // description:
- // Returns the value encoded in a form field as
- // as a string or an array of strings. Disabled form elements
- // and unchecked radio and checkboxes are skipped. Multi-select
- // elements are returned as an array of string values.
- // inputNode: DOMNode|String
- // returns: Object
- var ret = null;
- inputNode = dom.byId(inputNode);
- if(inputNode){
- var _in = inputNode.name, type = (inputNode.type || "").toLowerCase();
- if(_in && type && !inputNode.disabled){
- if(type == "radio" || type == "checkbox"){
- if(inputNode.checked){
- ret = inputNode.value;
- }
- }else if(inputNode.multiple){
- ret = [];
- var nodes = [inputNode.firstChild];
- while(nodes.length){
- for(var node = nodes.pop(); node; node = node.nextSibling){
- if(node.nodeType == 1 && node.tagName.toLowerCase() == "option"){
- if(node.selected){
- ret.push(node.value);
- }
- }else{
- if(node.nextSibling){
- nodes.push(node.nextSibling);
- }
- if(node.firstChild){
- nodes.push(node.firstChild);
- }
- break;
- }
- }
- }
- }else{
- ret = inputNode.value;
- }
- }
- }
- return ret; // Object
- },
- toObject: function formToObject(/*DOMNode|String*/ formNode){
- // summary:
- // Serialize a form node to a JavaScript object.
- // description:
- // Returns the values encoded in an HTML form as
- // string properties in an object which it then returns. Disabled form
- // elements, buttons, and other non-value form elements are skipped.
- // Multi-select elements are returned as an array of string values.
- // formNode: DOMNode|String
- // example:
- // This form:
- // | <form id="test_form">
- // | <input type="text" name="blah" value="blah">
- // | <input type="text" name="no_value" value="blah" disabled>
- // | <input type="button" name="no_value2" value="blah">
- // | <select type="select" multiple name="multi" size="5">
- // | <option value="blah">blah</option>
- // | <option value="thud" selected>thud</option>
- // | <option value="thonk" selected>thonk</option>
- // | </select>
- // | </form>
- //
- // yields this object structure as the result of a call to
- // formToObject():
- //
- // | {
- // | blah: "blah",
- // | multi: [
- // | "thud",
- // | "thonk"
- // | ]
- // | };
- var ret = {}, elems = dom.byId(formNode).elements;
- for(var i = 0, l = elems.length; i < l; ++i){
- var item = elems[i], _in = item.name, type = (item.type || "").toLowerCase();
- if(_in && type && exclude.indexOf(type) < 0 && !item.disabled){
- setValue(ret, _in, form.fieldToObject(item));
- if(type == "image"){
- ret[_in + ".x"] = ret[_in + ".y"] = ret[_in].x = ret[_in].y = 0;
- }
- }
- }
- return ret; // Object
- },
- toQuery: function formToQuery(/*DOMNode|String*/ formNode){
- // summary:
- // Returns a URL-encoded string representing the form passed as either a
- // node or string ID identifying the form to serialize
- // formNode: DOMNode|String
- // returns: String
- return ioq.objectToQuery(form.toObject(formNode)); // String
- },
- toJson: function formToJson(/*DOMNode|String*/ formNode, /*Boolean?*/ prettyPrint){
- // summary:
- // Create a serialized JSON string from a form node or string
- // ID identifying the form to serialize
- // formNode: DOMNode|String
- // prettyPrint: Boolean?
- // returns: String
- return json.stringify(form.toObject(formNode), null, prettyPrint ? 4 : 0); // String
- }
- };
- return form;
- });
- },
- 'dojo/i18n':function(){
- define(["./_base/kernel", "require", "./has", "./_base/array", "./_base/config", "./_base/lang", "./_base/xhr", "./json", "module"],
- function(dojo, require, has, array, config, lang, xhr, json, module){
- // module:
- // dojo/i18n
- has.add("dojo-preload-i18n-Api",
- // if true, define the preload localizations machinery
- 1
- );
- 1 || has.add("dojo-v1x-i18n-Api",
- // if true, define the v1.x i18n functions
- 1
- );
- var
- thisModule = dojo.i18n =
- {
- // summary:
- // This module implements the dojo/i18n! plugin and the v1.6- i18n API
- // description:
- // We choose to include our own plugin to leverage functionality already contained in dojo
- // and thereby reduce the size of the plugin compared to various loader implementations. Also, this
- // allows foreign AMD loaders to be used without their plugins.
- },
- nlsRe =
- // regexp for reconstructing the master bundle name from parts of the regexp match
- // nlsRe.exec("foo/bar/baz/nls/en-ca/foo") gives:
- // ["foo/bar/baz/nls/en-ca/foo", "foo/bar/baz/nls/", "/", "/", "en-ca", "foo"]
- // nlsRe.exec("foo/bar/baz/nls/foo") gives:
- // ["foo/bar/baz/nls/foo", "foo/bar/baz/nls/", "/", "/", "foo", ""]
- // so, if match[5] is blank, it means this is the top bundle definition.
- // courtesy of http://requirejs.org
- /(^.*(^|\/)nls)(\/|$)([^\/]*)\/?([^\/]*)/,
- getAvailableLocales = function(
- root,
- locale,
- bundlePath,
- bundleName
- ){
- // summary:
- // return a vector of module ids containing all available locales with respect to the target locale
- // For example, assuming:
- //
- // - the root bundle indicates specific bundles for "fr" and "fr-ca",
- // - bundlePath is "myPackage/nls"
- // - bundleName is "myBundle"
- //
- // Then a locale argument of "fr-ca" would return
- //
- // ["myPackage/nls/myBundle", "myPackage/nls/fr/myBundle", "myPackage/nls/fr-ca/myBundle"]
- //
- // Notice that bundles are returned least-specific to most-specific, starting with the root.
- //
- // If root===false indicates we're working with a pre-AMD i18n bundle that doesn't tell about the available locales;
- // therefore, assume everything is available and get 404 errors that indicate a particular localization is not available
- for(var result = [bundlePath + bundleName], localeParts = locale.split("-"), current = "", i = 0; i<localeParts.length; i++){
- current += (current ? "-" : "") + localeParts[i];
- if(!root || root[current]){
- result.push(bundlePath + current + "/" + bundleName);
- }
- }
- return result;
- },
- cache = {},
- getBundleName = function(moduleName, bundleName, locale){
- locale = locale ? locale.toLowerCase() : dojo.locale;
- moduleName = moduleName.replace(/\./g, "/");
- bundleName = bundleName.replace(/\./g, "/");
- return (/root/i.test(locale)) ?
- (moduleName + "/nls/" + bundleName) :
- (moduleName + "/nls/" + locale + "/" + bundleName);
- },
- getL10nName = dojo.getL10nName = function(moduleName, bundleName, locale){
- return moduleName = module.id + "!" + getBundleName(moduleName, bundleName, locale);
- },
- doLoad = function(require, bundlePathAndName, bundlePath, bundleName, locale, load){
- // summary:
- // get the root bundle which instructs which other bundles are required to construct the localized bundle
- require([bundlePathAndName], function(root){
- var current = lang.clone(root.root),
- availableLocales = getAvailableLocales(!root._v1x && root, locale, bundlePath, bundleName);
- require(availableLocales, function(){
- for (var i = 1; i<availableLocales.length; i++){
- current = lang.mixin(lang.clone(current), arguments[i]);
- }
- // target may not have been resolve (e.g., maybe only "fr" exists when "fr-ca" was requested)
- var target = bundlePathAndName + "/" + locale;
- cache[target] = current;
- load();
- });
- });
- },
- normalize = function(id, toAbsMid){
- // summary:
- // id may be relative.
- // preload has form `*preload*<path>/nls/<module>*<flattened locales>` and
- // therefore never looks like a relative
- return /^\./.test(id) ? toAbsMid(id) : id;
- },
- getLocalesToLoad = function(targetLocale){
- var list = config.extraLocale || [];
- list = lang.isArray(list) ? list : [list];
- list.push(targetLocale);
- return list;
- },
- load = function(id, require, load){
- // summary:
- // id is in one of the following formats
- //
- // 1. <path>/nls/<bundle>
- // => load the bundle, localized to config.locale; load all bundles localized to
- // config.extraLocale (if any); return the loaded bundle localized to config.locale.
- //
- // 2. <path>/nls/<locale>/<bundle>
- // => load then return the bundle localized to <locale>
- //
- // 3. *preload*<path>/nls/<module>*<JSON array of available locales>
- // => for config.locale and all config.extraLocale, load all bundles found
- // in the best-matching bundle rollup. A value of 1 is returned, which
- // is meaningless other than to say the plugin is executing the requested
- // preloads
- //
- // In cases 1 and 2, <path> is always normalized to an absolute module id upon entry; see
- // normalize. In case 3, it <path> is assumed to be absolute; this is arranged by the builder.
- //
- // To load a bundle means to insert the bundle into the plugin's cache and publish the bundle
- // value to the loader. Given <path>, <bundle>, and a particular <locale>, the cache key
- //
- // <path>/nls/<bundle>/<locale>
- //
- // will hold the value. Similarly, then plugin will publish this value to the loader by
- //
- // define("<path>/nls/<bundle>/<locale>", <bundle-value>);
- //
- // Given this algorithm, other machinery can provide fast load paths be preplacing
- // values in the plugin's cache, which is public. When a load is demanded the
- // cache is inspected before starting any loading. Explicitly placing values in the plugin
- // cache is an advanced/experimental feature that should not be needed; use at your own risk.
- //
- // For the normal AMD algorithm, the root bundle is loaded first, which instructs the
- // plugin what additional localized bundles are required for a particular locale. These
- // additional locales are loaded and a mix of the root and each progressively-specific
- // locale is returned. For example:
- //
- // 1. The client demands "dojo/i18n!some/path/nls/someBundle
- //
- // 2. The loader demands load(some/path/nls/someBundle)
- //
- // 3. This plugin require's "some/path/nls/someBundle", which is the root bundle.
- //
- // 4. Assuming config.locale is "ab-cd-ef" and the root bundle indicates that localizations
- // are available for "ab" and "ab-cd-ef" (note the missing "ab-cd", then the plugin
- // requires "some/path/nls/ab/someBundle" and "some/path/nls/ab-cd-ef/someBundle"
- //
- // 5. Upon receiving all required bundles, the plugin constructs the value of the bundle
- // ab-cd-ef as...
- //
- // mixin(mixin(mixin({}, require("some/path/nls/someBundle"),
- // require("some/path/nls/ab/someBundle")),
- // require("some/path/nls/ab-cd-ef/someBundle"));
- //
- // This value is inserted into the cache and published to the loader at the
- // key/module-id some/path/nls/someBundle/ab-cd-ef.
- //
- // The special preload signature (case 3) instructs the plugin to stop servicing all normal requests
- // (further preload requests will be serviced) until all ongoing preloading has completed.
- //
- // The preload signature instructs the plugin that a special rollup module is available that contains
- // one or more flattened, localized bundles. The JSON array of available locales indicates which locales
- // are available. Here is an example:
- //
- // *preload*some/path/nls/someModule*["root", "ab", "ab-cd-ef"]
- //
- // This indicates the following rollup modules are available:
- //
- // some/path/nls/someModule_ROOT
- // some/path/nls/someModule_ab
- // some/path/nls/someModule_ab-cd-ef
- //
- // Each of these modules is a normal AMD module that contains one or more flattened bundles in a hash.
- // For example, assume someModule contained the bundles some/bundle/path/someBundle and
- // some/bundle/path/someOtherBundle, then some/path/nls/someModule_ab would be expressed as follows:
- //
- // define({
- // some/bundle/path/someBundle:<value of someBundle, flattened with respect to locale ab>,
- // some/bundle/path/someOtherBundle:<value of someOtherBundle, flattened with respect to locale ab>,
- // });
- //
- // E.g., given this design, preloading for locale=="ab" can execute the following algorithm:
- //
- // require(["some/path/nls/someModule_ab"], function(rollup){
- // for(var p in rollup){
- // var id = p + "/ab",
- // cache[id] = rollup[p];
- // define(id, rollup[p]);
- // }
- // });
- //
- // Similarly, if "ab-cd" is requested, the algorithm can determine that "ab" is the best available and
- // load accordingly.
- //
- // The builder will write such rollups for every layer if a non-empty localeList profile property is
- // provided. Further, the builder will include the following cache entry in the cache associated with
- // any layer.
- //
- // "*now":function(r){r(['dojo/i18n!*preload*<path>/nls/<module>*<JSON array of available locales>']);}
- //
- // The *now special cache module instructs the loader to apply the provided function to context-require
- // with respect to the particular layer being defined. This causes the plugin to hold all normal service
- // requests until all preloading is complete.
- //
- // Notice that this algorithm is rarely better than the standard AMD load algorithm. Consider the normal case
- // where the target locale has a single segment and a layer depends on a single bundle:
- //
- // Without Preloads:
- //
- // 1. Layer loads root bundle.
- // 2. bundle is demanded; plugin loads single localized bundle.
- //
- // With Preloads:
- //
- // 1. Layer causes preloading of target bundle.
- // 2. bundle is demanded; service is delayed until preloading complete; bundle is returned.
- //
- // In each case a single transaction is required to load the target bundle. In cases where multiple bundles
- // are required and/or the locale has multiple segments, preloads still requires a single transaction whereas
- // the normal path requires an additional transaction for each additional bundle/locale-segment. However all
- // of these additional transactions can be done concurrently. Owing to this analysis, the entire preloading
- // algorithm can be discard during a build by setting the has feature dojo-preload-i18n-Api to false.
- if(has("dojo-preload-i18n-Api")){
- var split = id.split("*"),
- preloadDemand = split[1] == "preload";
- if(preloadDemand){
- if(!cache[id]){
- // use cache[id] to prevent multiple preloads of the same preload; this shouldn't happen, but
- // who knows what over-aggressive human optimizers may attempt
- cache[id] = 1;
- preloadL10n(split[2], json.parse(split[3]), 1, require);
- }
- // don't stall the loader!
- load(1);
- }
- if(preloadDemand || waitForPreloads(id, require, load)){
- return;
- }
- }
- var match = nlsRe.exec(id),
- bundlePath = match[1] + "/",
- bundleName = match[5] || match[4],
- bundlePathAndName = bundlePath + bundleName,
- localeSpecified = (match[5] && match[4]),
- targetLocale = localeSpecified || dojo.locale,
- loadTarget = bundlePathAndName + "/" + targetLocale,
- loadList = localeSpecified ? [targetLocale] : getLocalesToLoad(targetLocale),
- remaining = loadList.length,
- finish = function(){
- if(!--remaining){
- load(lang.delegate(cache[loadTarget]));
- }
- };
- array.forEach(loadList, function(locale){
- var target = bundlePathAndName + "/" + locale;
- if(has("dojo-preload-i18n-Api")){
- checkForLegacyModules(target);
- }
- if(!cache[target]){
- doLoad(require, bundlePathAndName, bundlePath, bundleName, locale, finish);
- }else{
- finish();
- }
- });
- };
- if(has("dojo-unit-tests")){
- var unitTests = thisModule.unitTests = [];
- }
- if(has("dojo-preload-i18n-Api") || 1 ){
- var normalizeLocale = thisModule.normalizeLocale = function(locale){
- var result = locale ? locale.toLowerCase() : dojo.locale;
- return result == "root" ? "ROOT" : result;
- },
- isXd = function(mid, contextRequire){
- return ( 1 && 1 ) ?
- contextRequire.isXdUrl(require.toUrl(mid + ".js")) :
- true;
- },
- preloading = 0,
- preloadWaitQueue = [],
- preloadL10n = thisModule._preloadLocalizations = function(/*String*/bundlePrefix, /*Array*/localesGenerated, /*boolean?*/ guaranteedAmdFormat, /*function?*/ contextRequire){
- // summary:
- // Load available flattened resource bundles associated with a particular module for dojo/locale and all dojo/config.extraLocale (if any)
- // description:
- // Only called by built layer files. The entire locale hierarchy is loaded. For example,
- // if locale=="ab-cd", then ROOT, "ab", and "ab-cd" are loaded. This is different than v1.6-
- // in that the v1.6- would only load ab-cd...which was *always* flattened.
- //
- // If guaranteedAmdFormat is true, then the module can be loaded with require thereby circumventing the detection algorithm
- // and the extra possible extra transaction.
- // If this function is called from legacy code, then guaranteedAmdFormat and contextRequire will be undefined. Since the function
- // needs a require in order to resolve module ids, fall back to the context-require associated with this dojo/i18n module, which
- // itself may have been mapped.
- contextRequire = contextRequire || require;
- function doRequire(mid, callback){
- if(isXd(mid, contextRequire) || guaranteedAmdFormat){
- contextRequire([mid], callback);
- }else{
- syncRequire([mid], callback, contextRequire);
- }
- }
- function forEachLocale(locale, func){
- // given locale= "ab-cd-ef", calls func on "ab-cd-ef", "ab-cd", "ab", "ROOT"; stops calling the first time func returns truthy
- var parts = locale.split("-");
- while(parts.length){
- if(func(parts.join("-"))){
- return;
- }
- parts.pop();
- }
- func("ROOT");
- }
- function preload(locale){
- locale = normalizeLocale(locale);
- forEachLocale(locale, function(loc){
- if(array.indexOf(localesGenerated, loc)>=0){
- var mid = bundlePrefix.replace(/\./g, "/")+"_"+loc;
- preloading++;
- doRequire(mid, function(rollup){
- for(var p in rollup){
- cache[require.toAbsMid(p) + "/" + loc] = rollup[p];
- }
- --preloading;
- while(!preloading && preloadWaitQueue.length){
- load.apply(null, preloadWaitQueue.shift());
- }
- });
- return true;
- }
- return false;
- });
- }
- preload();
- array.forEach(dojo.config.extraLocale, preload);
- },
- waitForPreloads = function(id, require, load){
- if(preloading){
- preloadWaitQueue.push([id, require, load]);
- }
- return preloading;
- },
- checkForLegacyModules = function()
- {};
- }
- if( 1 ){
- // this code path assumes the dojo loader and won't work with a standard AMD loader
- var amdValue = {},
- evalBundle =
- // use the function ctor to keep the minifiers away (also come close to global scope, but this is secondary)
- new Function(
- "__bundle", // the bundle to evalutate
- "__checkForLegacyModules", // a function that checks if __bundle defined __mid in the global space
- "__mid", // the mid that __bundle is intended to define
- "__amdValue",
- // returns one of:
- // 1 => the bundle was an AMD bundle
- // a legacy bundle object that is the value of __mid
- // instance of Error => could not figure out how to evaluate bundle
- // used to detect when __bundle calls define
- "var define = function(mid, factory){define.called = 1; __amdValue.result = factory || mid;},"
- + " require = function(){define.called = 1;};"
- + "try{"
- + "define.called = 0;"
- + "eval(__bundle);"
- + "if(define.called==1)"
- // bundle called define; therefore signal it's an AMD bundle
- + "return __amdValue;"
- + "if((__checkForLegacyModules = __checkForLegacyModules(__mid)))"
- // bundle was probably a v1.6- built NLS flattened NLS bundle that defined __mid in the global space
- + "return __checkForLegacyModules;"
- + "}catch(e){}"
- // evaulating the bundle was *neither* an AMD *nor* a legacy flattened bundle
- // either way, re-eval *after* surrounding with parentheses
- + "try{"
- + "return eval('('+__bundle+')');"
- + "}catch(e){"
- + "return e;"
- + "}"
- ),
- syncRequire = function(deps, callback, require){
- var results = [];
- array.forEach(deps, function(mid){
- var url = require.toUrl(mid + ".js");
- function load(text){
- var result = evalBundle(text, checkForLegacyModules, mid, amdValue);
- if(result===amdValue){
- // the bundle was an AMD module; re-inject it through the normal AMD path
- // we gotta do this since it could be an anonymous module and simply evaluating
- // the text here won't provide the loader with the context to know what
- // module is being defined()'d. With browser caching, this should be free; further
- // this entire code path can be circumvented by using the AMD format to begin with
- results.push(cache[url] = amdValue.result);
- }else{
- if(result instanceof Error){
- console.error("failed to evaluate i18n bundle; url=" + url, result);
- result = {};
- }
- // nls/<locale>/<bundle-name> indicates not the root.
- results.push(cache[url] = (/nls\/[^\/]+\/[^\/]+$/.test(url) ? result : {root:result, _v1x:1}));
- }
- }
- if(cache[url]){
- results.push(cache[url]);
- }else{
- var bundle = require.syncLoadNls(mid);
- // don't need to check for legacy since syncLoadNls returns a module if the module
- // (1) was already loaded, or (2) was in the cache. In case 1, if syncRequire is called
- // from getLocalization --> load, then load will have called checkForLegacyModules() before
- // calling syncRequire; if syncRequire is called from preloadLocalizations, then we
- // don't care about checkForLegacyModules() because that will be done when a particular
- // bundle is actually demanded. In case 2, checkForLegacyModules() is never relevant
- // because cached modules are always v1.7+ built modules.
- if(bundle){
- results.push(bundle);
- }else{
- if(!xhr){
- try{
- require.getText(url, true, load);
- }catch(e){
- results.push(cache[url] = {});
- }
- }else{
- xhr.get({
- url:url,
- sync:true,
- load:load,
- error:function(){
- results.push(cache[url] = {});
- }
- });
- }
- }
- }
- });
- callback && callback.apply(null, results);
- };
- checkForLegacyModules = function(target){
- // legacy code may have already loaded [e.g] the raw bundle x/y/z at x.y.z; when true, push into the cache
- for(var result, names = target.split("/"), object = dojo.global[names[0]], i = 1; object && i<names.length-1; object = object[names[i++]]){}
- if(object){
- result = object[names[i]];
- if(!result){
- // fallback for incorrect bundle build of 1.6
- result = object[names[i].replace(/-/g,"_")];
- }
- if(result){
- cache[target] = result;
- }
- }
- return result;
- };
- thisModule.getLocalization = function(moduleName, bundleName, locale){
- var result,
- l10nName = getBundleName(moduleName, bundleName, locale);
- load(
- l10nName,
- // isXd() and syncRequire() need a context-require in order to resolve the mid with respect to a reference module.
- // Since this legacy function does not have the concept of a reference module, resolve with respect to this
- // dojo/i18n module, which, itself may have been mapped.
- (!isXd(l10nName, require) ? function(deps, callback){ syncRequire(deps, callback, require); } : require),
- function(result_){ result = result_; }
- );
- return result;
- };
- if(has("dojo-unit-tests")){
- unitTests.push(function(doh){
- doh.register("tests.i18n.unit", function(t){
- var check;
- check = evalBundle("{prop:1}", checkForLegacyModules, "nonsense", amdValue);
- t.is({prop:1}, check); t.is(undefined, check[1]);
- check = evalBundle("({prop:1})", checkForLegacyModules, "nonsense", amdValue);
- t.is({prop:1}, check); t.is(undefined, check[1]);
- check = evalBundle("{'prop-x':1}", checkForLegacyModules, "nonsense", amdValue);
- t.is({'prop-x':1}, check); t.is(undefined, check[1]);
- check = evalBundle("({'prop-x':1})", checkForLegacyModules, "nonsense", amdValue);
- t.is({'prop-x':1}, check); t.is(undefined, check[1]);
- check = evalBundle("define({'prop-x':1})", checkForLegacyModules, "nonsense", amdValue);
- t.is(amdValue, check); t.is({'prop-x':1}, amdValue.result);
- check = evalBundle("define('some/module', {'prop-x':1})", checkForLegacyModules, "nonsense", amdValue);
- t.is(amdValue, check); t.is({'prop-x':1}, amdValue.result);
- check = evalBundle("this is total nonsense and should throw an error", checkForLegacyModules, "nonsense", amdValue);
- t.is(check instanceof Error, true);
- });
- });
- }
- }
- return lang.mixin(thisModule, {
- dynamic:true,
- normalize:normalize,
- load:load,
- cache:cache
- });
- });
- },
- 'dojo/promise/tracer':function(){
- define([
- "../_base/lang",
- "./Promise",
- "../Evented"
- ], function(lang, Promise, Evented){
- "use strict";
- // module:
- // dojo/promise/tracer
- /*=====
- return {
- // summary:
- // Trace promise fulfillment.
- // description:
- // Trace promise fulfillment. Calling `.trace()` or `.traceError()` on a
- // promise enables tracing. Will emit `resolved`, `rejected` or `progress`
- // events.
- on: function(type, listener){
- // summary:
- // Subscribe to traces.
- // description:
- // See `dojo/Evented#on()`.
- // type: String
- // `resolved`, `rejected`, or `progress`
- // listener: Function
- // The listener is passed the traced value and any arguments
- // that were used with the `.trace()` call.
- }
- };
- =====*/
- var evented = new Evented;
- var emit = evented.emit;
- evented.emit = null;
- // Emit events asynchronously since they should not change the promise state.
- function emitAsync(args){
- setTimeout(function(){
- emit.apply(evented, args);
- }, 0);
- }
- Promise.prototype.trace = function(){
- // summary:
- // Trace the promise.
- // description:
- // Tracing allows you to transparently log progress,
- // resolution and rejection of promises, without affecting the
- // promise itself. Any arguments passed to `trace()` are
- // emitted in trace events. See `dojo/promise/tracer` on how
- // to handle traces.
- // returns: dojo/promise/Promise
- // The promise instance `trace()` is called on.
- var args = lang._toArray(arguments);
- this.then(
- function(value){ emitAsync(["resolved", value].concat(args)); },
- function(error){ emitAsync(["rejected", error].concat(args)); },
- function(update){ emitAsync(["progress", update].concat(args)); }
- );
- return this;
- };
- Promise.prototype.traceRejected = function(){
- // summary:
- // Trace rejection of the promise.
- // description:
- // Tracing allows you to transparently log progress,
- // resolution and rejection of promises, without affecting the
- // promise itself. Any arguments passed to `trace()` are
- // emitted in trace events. See `dojo/promise/tracer` on how
- // to handle traces.
- // returns: dojo/promise/Promise
- // The promise instance `traceRejected()` is called on.
- var args = lang._toArray(arguments);
- this.otherwise(function(error){
- emitAsync(["rejected", error].concat(args));
- });
- return this;
- };
- return evented;
- });
- },
- 'dojo/errors/RequestError':function(){
- define(['./create'], function(create){
- // module:
- // dojo/errors/RequestError
- /*=====
- return function(){
- // summary:
- // TODOC
- };
- =====*/
- return create("RequestError", function(message, response){
- this.response = response;
- });
- });
- },
- 'dojo/_base/html':function(){
- define("dojo/_base/html", ["./kernel", "../dom", "../dom-style", "../dom-attr", "../dom-prop", "../dom-class", "../dom-construct", "../dom-geometry"], function(dojo, dom, style, attr, prop, cls, ctr, geom){
- // module:
- // dojo/dom
- /*=====
- return {
- // summary:
- // This module is a stub for the core dojo DOM API.
- };
- =====*/
- // mix-in dom
- dojo.byId = dom.byId;
- dojo.isDescendant = dom.isDescendant;
- dojo.setSelectable = dom.setSelectable;
- // mix-in dom-attr
- dojo.getAttr = attr.get;
- dojo.setAttr = attr.set;
- dojo.hasAttr = attr.has;
- dojo.removeAttr = attr.remove;
- dojo.getNodeProp = attr.getNodeProp;
- dojo.attr = function(node, name, value){
- // summary:
- // Gets or sets an attribute on an HTML element.
- // description:
- // Handles normalized getting and setting of attributes on DOM
- // Nodes. If 2 arguments are passed, and a the second argument is a
- // string, acts as a getter.
- //
- // If a third argument is passed, or if the second argument is a
- // map of attributes, acts as a setter.
- //
- // When passing functions as values, note that they will not be
- // directly assigned to slots on the node, but rather the default
- // behavior will be removed and the new behavior will be added
- // using `dojo.connect()`, meaning that event handler properties
- // will be normalized and that some caveats with regards to
- // non-standard behaviors for onsubmit apply. Namely that you
- // should cancel form submission using `dojo.stopEvent()` on the
- // passed event object instead of returning a boolean value from
- // the handler itself.
- // node: DOMNode|String
- // id or reference to the element to get or set the attribute on
- // name: String|Object
- // the name of the attribute to get or set.
- // value: String?
- // The value to set for the attribute
- // returns:
- // when used as a getter, the value of the requested attribute
- // or null if that attribute does not have a specified or
- // default value;
- //
- // when used as a setter, the DOM node
- //
- // example:
- // | // get the current value of the "foo" attribute on a node
- // | dojo.attr(dojo.byId("nodeId"), "foo");
- // | // or we can just pass the id:
- // | dojo.attr("nodeId", "foo");
- //
- // example:
- // | // use attr() to set the tab index
- // | dojo.attr("nodeId", "tabIndex", 3);
- // |
- //
- // example:
- // Set multiple values at once, including event handlers:
- // | dojo.attr("formId", {
- // | "foo": "bar",
- // | "tabIndex": -1,
- // | "method": "POST",
- // | "onsubmit": function(e){
- // | // stop submitting the form. Note that the IE behavior
- // | // of returning true or false will have no effect here
- // | // since our handler is connect()ed to the built-in
- // | // onsubmit behavior and so we need to use
- // | // dojo.stopEvent() to ensure that the submission
- // | // doesn't proceed.
- // | dojo.stopEvent(e);
- // |
- // | // submit the form with Ajax
- // | dojo.xhrPost({ form: "formId" });
- // | }
- // | });
- //
- // example:
- // Style is s special case: Only set with an object hash of styles
- // | dojo.attr("someNode",{
- // | id:"bar",
- // | style:{
- // | width:"200px", height:"100px", color:"#000"
- // | }
- // | });
- //
- // example:
- // Again, only set style as an object hash of styles:
- // | var obj = { color:"#fff", backgroundColor:"#000" };
- // | dojo.attr("someNode", "style", obj);
- // |
- // | // though shorter to use `dojo.style()` in this case:
- // | dojo.style("someNode", obj);
- if(arguments.length == 2){
- return attr[typeof name == "string" ? "get" : "set"](node, name);
- }
- return attr.set(node, name, value);
- };
- // mix-in dom-class
- dojo.hasClass = cls.contains;
- dojo.addClass = cls.add;
- dojo.removeClass = cls.remove;
- dojo.toggleClass = cls.toggle;
- dojo.replaceClass = cls.replace;
- // mix-in dom-construct
- dojo._toDom = dojo.toDom = ctr.toDom;
- dojo.place = ctr.place;
- dojo.create = ctr.create;
- dojo.empty = function(node){ ctr.empty(node); };
- dojo._destroyElement = dojo.destroy = function(node){ ctr.destroy(node); };
- // mix-in dom-geometry
- dojo._getPadExtents = dojo.getPadExtents = geom.getPadExtents;
- dojo._getBorderExtents = dojo.getBorderExtents = geom.getBorderExtents;
- dojo._getPadBorderExtents = dojo.getPadBorderExtents = geom.getPadBorderExtents;
- dojo._getMarginExtents = dojo.getMarginExtents = geom.getMarginExtents;
- dojo._getMarginSize = dojo.getMarginSize = geom.getMarginSize;
- dojo._getMarginBox = dojo.getMarginBox = geom.getMarginBox;
- dojo.setMarginBox = geom.setMarginBox;
- dojo._getContentBox = dojo.getContentBox = geom.getContentBox;
- dojo.setContentSize = geom.setContentSize;
- dojo._isBodyLtr = dojo.isBodyLtr = geom.isBodyLtr;
- dojo._docScroll = dojo.docScroll = geom.docScroll;
- dojo._getIeDocumentElementOffset = dojo.getIeDocumentElementOffset = geom.getIeDocumentElementOffset;
- dojo._fixIeBiDiScrollLeft = dojo.fixIeBiDiScrollLeft = geom.fixIeBiDiScrollLeft;
- dojo.position = geom.position;
- dojo.marginBox = function marginBox(/*DomNode|String*/node, /*Object?*/box){
- // summary:
- // Getter/setter for the margin-box of node.
- // description:
- // Getter/setter for the margin-box of node.
- // Returns an object in the expected format of box (regardless
- // if box is passed). The object might look like:
- // `{ l: 50, t: 200, w: 300: h: 150 }`
- // for a node offset from its parent 50px to the left, 200px from
- // the top with a margin width of 300px and a margin-height of
- // 150px.
- // node:
- // id or reference to DOM Node to get/set box for
- // box:
- // If passed, denotes that dojo.marginBox() should
- // update/set the margin box for node. Box is an object in the
- // above format. All properties are optional if passed.
- // example:
- // Retrieve the margin box of a passed node
- // | var box = dojo.marginBox("someNodeId");
- // | console.dir(box);
- //
- // example:
- // Set a node's margin box to the size of another node
- // | var box = dojo.marginBox("someNodeId");
- // | dojo.marginBox("someOtherNode", box);
- return box ? geom.setMarginBox(node, box) : geom.getMarginBox(node); // Object
- };
- dojo.contentBox = function contentBox(/*DomNode|String*/node, /*Object?*/box){
- // summary:
- // Getter/setter for the content-box of node.
- // description:
- // Returns an object in the expected format of box (regardless if box is passed).
- // The object might look like:
- // `{ l: 50, t: 200, w: 300: h: 150 }`
- // for a node offset from its parent 50px to the left, 200px from
- // the top with a content width of 300px and a content-height of
- // 150px. Note that the content box may have a much larger border
- // or margin box, depending on the box model currently in use and
- // CSS values set/inherited for node.
- // While the getter will return top and left values, the
- // setter only accepts setting the width and height.
- // node:
- // id or reference to DOM Node to get/set box for
- // box:
- // If passed, denotes that dojo.contentBox() should
- // update/set the content box for node. Box is an object in the
- // above format, but only w (width) and h (height) are supported.
- // All properties are optional if passed.
- return box ? geom.setContentSize(node, box) : geom.getContentBox(node); // Object
- };
- dojo.coords = function(/*DomNode|String*/node, /*Boolean?*/includeScroll){
- // summary:
- // Deprecated: Use position() for border-box x/y/w/h
- // or marginBox() for margin-box w/h/l/t.
- //
- // Returns an object that measures margin-box (w)idth/(h)eight
- // and absolute position x/y of the border-box. Also returned
- // is computed (l)eft and (t)op values in pixels from the
- // node's offsetParent as returned from marginBox().
- // Return value will be in the form:
- //| { l: 50, t: 200, w: 300: h: 150, x: 100, y: 300 }
- // Does not act as a setter. If includeScroll is passed, the x and
- // y params are affected as one would expect in dojo.position().
- dojo.deprecated("dojo.coords()", "Use dojo.position() or dojo.marginBox().");
- node = dom.byId(node);
- var s = style.getComputedStyle(node), mb = geom.getMarginBox(node, s);
- var abs = geom.position(node, includeScroll);
- mb.x = abs.x;
- mb.y = abs.y;
- return mb; // Object
- };
- // mix-in dom-prop
- dojo.getProp = prop.get;
- dojo.setProp = prop.set;
- dojo.prop = function(/*DomNode|String*/node, /*String|Object*/name, /*String?*/value){
- // summary:
- // Gets or sets a property on an HTML element.
- // description:
- // Handles normalized getting and setting of properties on DOM
- // Nodes. If 2 arguments are passed, and a the second argument is a
- // string, acts as a getter.
- //
- // If a third argument is passed, or if the second argument is a
- // map of attributes, acts as a setter.
- //
- // When passing functions as values, note that they will not be
- // directly assigned to slots on the node, but rather the default
- // behavior will be removed and the new behavior will be added
- // using `dojo.connect()`, meaning that event handler properties
- // will be normalized and that some caveats with regards to
- // non-standard behaviors for onsubmit apply. Namely that you
- // should cancel form submission using `dojo.stopEvent()` on the
- // passed event object instead of returning a boolean value from
- // the handler itself.
- // node:
- // id or reference to the element to get or set the property on
- // name:
- // the name of the property to get or set.
- // value:
- // The value to set for the property
- // returns:
- // when used as a getter, the value of the requested property
- // or null if that attribute does not have a specified or
- // default value;
- //
- // when used as a setter, the DOM node
- //
- // example:
- // | // get the current value of the "foo" property on a node
- // | dojo.prop(dojo.byId("nodeId"), "foo");
- // | // or we can just pass the id:
- // | dojo.prop("nodeId", "foo");
- //
- // example:
- // | // use prop() to set the tab index
- // | dojo.prop("nodeId", "tabIndex", 3);
- // |
- //
- // example:
- // Set multiple values at once, including event handlers:
- // | dojo.prop("formId", {
- // | "foo": "bar",
- // | "tabIndex": -1,
- // | "method": "POST",
- // | "onsubmit": function(e){
- // | // stop submitting the form. Note that the IE behavior
- // | // of returning true or false will have no effect here
- // | // since our handler is connect()ed to the built-in
- // | // onsubmit behavior and so we need to use
- // | // dojo.stopEvent() to ensure that the submission
- // | // doesn't proceed.
- // | dojo.stopEvent(e);
- // |
- // | // submit the form with Ajax
- // | dojo.xhrPost({ form: "formId" });
- // | }
- // | });
- //
- // example:
- // Style is s special case: Only set with an object hash of styles
- // | dojo.prop("someNode",{
- // | id:"bar",
- // | style:{
- // | width:"200px", height:"100px", color:"#000"
- // | }
- // | });
- //
- // example:
- // Again, only set style as an object hash of styles:
- // | var obj = { color:"#fff", backgroundColor:"#000" };
- // | dojo.prop("someNode", "style", obj);
- // |
- // | // though shorter to use `dojo.style()` in this case:
- // | dojo.style("someNode", obj);
- if(arguments.length == 2){
- return prop[typeof name == "string" ? "get" : "set"](node, name);
- }
- // setter
- return prop.set(node, name, value);
- };
- // mix-in dom-style
- dojo.getStyle = style.get;
- dojo.setStyle = style.set;
- dojo.getComputedStyle = style.getComputedStyle;
- dojo.__toPixelValue = dojo.toPixelValue = style.toPixelValue;
- dojo.style = function(node, name, value){
- // summary:
- // Accesses styles on a node. If 2 arguments are
- // passed, acts as a getter. If 3 arguments are passed, acts
- // as a setter.
- // description:
- // Getting the style value uses the computed style for the node, so the value
- // will be a calculated value, not just the immediate node.style value.
- // Also when getting values, use specific style names,
- // like "borderBottomWidth" instead of "border" since compound values like
- // "border" are not necessarily reflected as expected.
- // If you want to get node dimensions, use `dojo.marginBox()`,
- // `dojo.contentBox()` or `dojo.position()`.
- // node: DOMNode|String
- // id or reference to node to get/set style for
- // name: String|Object?
- // the style property to set in DOM-accessor format
- // ("borderWidth", not "border-width") or an object with key/value
- // pairs suitable for setting each property.
- // value: String?
- // If passed, sets value on the node for style, handling
- // cross-browser concerns. When setting a pixel value,
- // be sure to include "px" in the value. For instance, top: "200px".
- // Otherwise, in some cases, some browsers will not apply the style.
- // returns:
- // when used as a getter, return the computed style of the node if passing in an ID or node,
- // or return the normalized, computed value for the property when passing in a node and a style property
- // example:
- // Passing only an ID or node returns the computed style object of
- // the node:
- // | dojo.style("thinger");
- // example:
- // Passing a node and a style property returns the current
- // normalized, computed value for that property:
- // | dojo.style("thinger", "opacity"); // 1 by default
- //
- // example:
- // Passing a node, a style property, and a value changes the
- // current display of the node and returns the new computed value
- // | dojo.style("thinger", "opacity", 0.5); // == 0.5
- //
- // example:
- // Passing a node, an object-style style property sets each of the values in turn and returns the computed style object of the node:
- // | dojo.style("thinger", {
- // | "opacity": 0.5,
- // | "border": "3px solid black",
- // | "height": "300px"
- // | });
- //
- // example:
- // When the CSS style property is hyphenated, the JavaScript property is camelCased.
- // font-size becomes fontSize, and so on.
- // | dojo.style("thinger",{
- // | fontSize:"14pt",
- // | letterSpacing:"1.2em"
- // | });
- //
- // example:
- // dojo/NodeList implements .style() using the same syntax, omitting the "node" parameter, calling
- // dojo.style() on every element of the list. See: `dojo/query` and `dojo/NodeList`
- // | dojo.query(".someClassName").style("visibility","hidden");
- // | // or
- // | dojo.query("#baz > div").style({
- // | opacity:0.75,
- // | fontSize:"13pt"
- // | });
- switch(arguments.length){
- case 1:
- return style.get(node);
- case 2:
- return style[typeof name == "string" ? "get" : "set"](node, name);
- }
- // setter
- return style.set(node, name, value);
- };
- return dojo;
- });
- },
- 'dojo/_base/kernel':function(){
- define(["../has", "./config", "require", "module"], function(has, config, require, module){
- // module:
- // dojo/_base/kernel
- // This module is the foundational module of the dojo boot sequence; it defines the dojo object.
- var
- // loop variables for this module
- i, p,
- // create dojo, dijit, and dojox
- // FIXME: in 2.0 remove dijit, dojox being created by dojo
- dijit = {},
- dojox = {},
- dojo = {
- // summary:
- // This module is the foundational module of the dojo boot sequence; it defines the dojo object.
- // notice dojo takes ownership of the value of the config module
- config:config,
- global:this,
- dijit:dijit,
- dojox:dojox
- };
- // Configure the scope map. For a 100% AMD application, the scope map is not needed other than to provide
- // a _scopeName property for the dojo, dijit, and dojox root object so those packages can create
- // unique names in the global space.
- //
- // Built, legacy modules use the scope map to allow those modules to be expressed as if dojo, dijit, and dojox,
- // where global when in fact they are either global under different names or not global at all. In v1.6-, the
- // config variable "scopeMap" was used to map names as used within a module to global names. This has been
- // subsumed by the AMD map configuration variable which can relocate packages to different names. For backcompat,
- // only the "*" mapping is supported. See http://livedocs.dojotoolkit.org/developer/design/loader#legacy-cross-domain-mode for details.
- //
- // The following computations contort the packageMap for this dojo instance into a scopeMap.
- var scopeMap =
- // a map from a name used in a legacy module to the (global variable name, object addressed by that name)
- // always map dojo, dijit, and dojox
- {
- dojo:["dojo", dojo],
- dijit:["dijit", dijit],
- dojox:["dojox", dojox]
- },
- packageMap =
- // the package map for this dojo instance; note, a foreign loader or no pacakgeMap results in the above default config
- (require.map && require.map[module.id.match(/[^\/]+/)[0]]),
- item;
- // process all mapped top-level names for this instance of dojo
- for(p in packageMap){
- if(scopeMap[p]){
- // mapped dojo, dijit, or dojox
- scopeMap[p][0] = packageMap[p];
- }else{
- // some other top-level name
- scopeMap[p] = [packageMap[p], {}];
- }
- }
- // publish those names to _scopeName and, optionally, the global namespace
- for(p in scopeMap){
- item = scopeMap[p];
- item[1]._scopeName = item[0];
- if(!config.noGlobals){
- this[item[0]] = item[1];
- }
- }
- dojo.scopeMap = scopeMap;
- /*===== dojo.__docParserConfigureScopeMap(scopeMap); =====*/
- // FIXME: dojo.baseUrl and dojo.config.baseUrl should be deprecated
- dojo.baseUrl = dojo.config.baseUrl = require.baseUrl;
- dojo.isAsync = ! 1 || require.async;
- dojo.locale = config.locale;
- var rev = "$Rev: 29801 $".match(/\d+/);
- dojo.version = {
- // summary:
- // Version number of the Dojo Toolkit
- // description:
- // Hash about the version, including
- //
- // - major: Integer: Major version. If total version is "1.2.0beta1", will be 1
- // - minor: Integer: Minor version. If total version is "1.2.0beta1", will be 2
- // - patch: Integer: Patch version. If total version is "1.2.0beta1", will be 0
- // - flag: String: Descriptor flag. If total version is "1.2.0beta1", will be "beta1"
- // - revision: Number: The SVN rev from which dojo was pulled
- major: 1, minor: 8, patch: 1, flag: "",
- revision: rev ? +rev[0] : NaN,
- toString: function(){
- var v = dojo.version;
- return v.major + "." + v.minor + "." + v.patch + v.flag + " (" + v.revision + ")"; // String
- }
- };
- // If 1 is truthy, then as a dojo module is defined it should push it's definitions
- // into the dojo object, and conversely. In 2.0, it will likely be unusual to augment another object
- // as a result of defining a module. This has feature gives a way to force 2.0 behavior as the code
- // is migrated. Absent specific advice otherwise, set extend-dojo to truthy.
- 1 || has.add("extend-dojo", 1);
- (Function("d", "d.eval = function(){return d.global.eval ? d.global.eval(arguments[0]) : eval(arguments[0]);}"))(dojo);
- /*=====
- dojo.eval = function(scriptText){
- // summary:
- // A legacy method created for use exclusively by internal Dojo methods. Do not use this method
- // directly unless you understand its possibly-different implications on the platforms your are targeting.
- // description:
- // Makes an attempt to evaluate scriptText in the global scope. The function works correctly for browsers
- // that support indirect eval.
- //
- // As usual, IE does not. On IE, the only way to implement global eval is to
- // use execScript. Unfortunately, execScript does not return a value and breaks some current usages of dojo.eval.
- // This implementation uses the technique of executing eval in the scope of a function that is a single scope
- // frame below the global scope; thereby coming close to the global scope. Note carefully that
- //
- // dojo.eval("var pi = 3.14;");
- //
- // will define global pi in non-IE environments, but define pi only in a temporary local scope for IE. If you want
- // to define a global variable using dojo.eval, write something like
- //
- // dojo.eval("window.pi = 3.14;")
- // scriptText:
- // The text to evaluation.
- // returns:
- // The result of the evaluation. Often `undefined`
- };
- =====*/
- if( 0 ){
- dojo.exit = function(exitcode){
- quit(exitcode);
- };
- }else{
- dojo.exit = function(){
- };
- }
- 1 || has.add("dojo-guarantee-console",
- // ensure that console.log, console.warn, etc. are defined
- 1
- );
- if( 1 ){
- typeof console != "undefined" || (console = {});
- // Be careful to leave 'log' always at the end
- var cn = [
- "assert", "count", "debug", "dir", "dirxml", "error", "group",
- "groupEnd", "info", "profile", "profileEnd", "time", "timeEnd",
- "trace", "warn", "log"
- ];
- var tn;
- i = 0;
- while((tn = cn[i++])){
- if(!console[tn]){
- (function(){
- var tcn = tn + "";
- console[tcn] = ('log' in console) ? function(){
- var a = Array.apply({}, arguments);
- a.unshift(tcn + ":");
- console["log"](a.join(" "));
- } : function(){};
- console[tcn]._fake = true;
- })();
- }
- }
- }
- has.add("dojo-debug-messages",
- // include dojo.deprecated/dojo.experimental implementations
- !!config.isDebug
- );
- dojo.deprecated = dojo.experimental = function(){};
- if(has("dojo-debug-messages")){
- dojo.deprecated = function(/*String*/ behaviour, /*String?*/ extra, /*String?*/ removal){
- // summary:
- // Log a debug message to indicate that a behavior has been
- // deprecated.
- // behaviour: String
- // The API or behavior being deprecated. Usually in the form
- // of "myApp.someFunction()".
- // extra: String?
- // Text to append to the message. Often provides advice on a
- // new function or facility to achieve the same goal during
- // the deprecation period.
- // removal: String?
- // Text to indicate when in the future the behavior will be
- // removed. Usually a version number.
- // example:
- // | dojo.deprecated("myApp.getTemp()", "use myApp.getLocaleTemp() instead", "1.0");
- var message = "DEPRECATED: " + behaviour;
- if(extra){ message += " " + extra; }
- if(removal){ message += " -- will be removed in version: " + removal; }
- console.warn(message);
- };
- dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
- // summary:
- // Marks code as experimental.
- // description:
- // This can be used to mark a function, file, or module as
- // experimental. Experimental code is not ready to be used, and the
- // APIs are subject to change without notice. Experimental code may be
- // completed deleted without going through the normal deprecation
- // process.
- // moduleName: String
- // The name of a module, or the name of a module file or a specific
- // function
- // extra: String?
- // some additional message for the user
- // example:
- // | dojo.experimental("dojo.data.Result");
- // example:
- // | dojo.experimental("dojo.weather.toKelvin()", "PENDING approval from NOAA");
- var message = "EXPERIMENTAL: " + moduleName + " -- APIs subject to change without notice.";
- if(extra){ message += " " + extra; }
- console.warn(message);
- };
- }
- 1 || has.add("dojo-modulePaths",
- // consume dojo.modulePaths processing
- 1
- );
- if( 1 ){
- // notice that modulePaths won't be applied to any require's before the dojo/_base/kernel factory is run;
- // this is the v1.6- behavior.
- if(config.modulePaths){
- dojo.deprecated("dojo.modulePaths", "use paths configuration");
- var paths = {};
- for(p in config.modulePaths){
- paths[p.replace(/\./g, "/")] = config.modulePaths[p];
- }
- require({paths:paths});
- }
- }
- 1 || has.add("dojo-moduleUrl",
- // include dojo.moduleUrl
- 1
- );
- if( 1 ){
- dojo.moduleUrl = function(/*String*/module, /*String?*/url){
- // summary:
- // Returns a URL relative to a module.
- // example:
- // | var pngPath = dojo.moduleUrl("acme","images/small.png");
- // | console.dir(pngPath); // list the object properties
- // | // create an image and set it's source to pngPath's value:
- // | var img = document.createElement("img");
- // | img.src = pngPath;
- // | // add our image to the document
- // | dojo.body().appendChild(img);
- // example:
- // you may de-reference as far as you like down the package
- // hierarchy. This is sometimes handy to avoid lenghty relative
- // urls or for building portable sub-packages. In this example,
- // the `acme.widget` and `acme.util` directories may be located
- // under different roots (see `dojo.registerModulePath`) but the
- // the modules which reference them can be unaware of their
- // relative locations on the filesystem:
- // | // somewhere in a configuration block
- // | dojo.registerModulePath("acme.widget", "../../acme/widget");
- // | dojo.registerModulePath("acme.util", "../../util");
- // |
- // | // ...
- // |
- // | // code in a module using acme resources
- // | var tmpltPath = dojo.moduleUrl("acme.widget","templates/template.html");
- // | var dataPath = dojo.moduleUrl("acme.util","resources/data.json");
- dojo.deprecated("dojo.moduleUrl()", "use require.toUrl", "2.0");
- // require.toUrl requires a filetype; therefore, just append the suffix "/*.*" to guarantee a filetype, then
- // remove the suffix from the result. This way clients can request a url w/out a filetype. This should be
- // rare, but it maintains backcompat for the v1.x line (note: dojo.moduleUrl will be removed in v2.0).
- // Notice * is an illegal filename so it won't conflict with any real path map that may exist the paths config.
- var result = null;
- if(module){
- result = require.toUrl(module.replace(/\./g, "/") + (url ? ("/" + url) : "") + "/*.*").replace(/\/\*\.\*/, "") + (url ? "" : "/");
- }
- return result;
- };
- }
- dojo._hasResource = {}; // for backward compatibility with layers built with 1.6 tooling
- return dojo;
- });
- },
- 'dojo/io-query':function(){
- define(["./_base/lang"], function(lang){
- // module:
- // dojo/io-query
- var backstop = {};
- return {
- // summary:
- // This module defines query string processing functions.
- objectToQuery: function objectToQuery(/*Object*/ map){
- // summary:
- // takes a name/value mapping object and returns a string representing
- // a URL-encoded version of that object.
- // example:
- // this object:
- //
- // | {
- // | blah: "blah",
- // | multi: [
- // | "thud",
- // | "thonk"
- // | ]
- // | };
- //
- // yields the following query string:
- //
- // | "blah=blah&multi=thud&multi=thonk"
- // FIXME: need to implement encodeAscii!!
- var enc = encodeURIComponent, pairs = [];
- for(var name in map){
- var value = map[name];
- if(value != backstop[name]){
- var assign = enc(name) + "=";
- if(lang.isArray(value)){
- for(var i = 0, l = value.length; i < l; ++i){
- pairs.push(assign + enc(value[i]));
- }
- }else{
- pairs.push(assign + enc(value));
- }
- }
- }
- return pairs.join("&"); // String
- },
- queryToObject: function queryToObject(/*String*/ str){
- // summary:
- // Create an object representing a de-serialized query section of a
- // URL. Query keys with multiple values are returned in an array.
- //
- // example:
- // This string:
- //
- // | "foo=bar&foo=baz&thinger=%20spaces%20=blah&zonk=blarg&"
- //
- // results in this object structure:
- //
- // | {
- // | foo: [ "bar", "baz" ],
- // | thinger: " spaces =blah",
- // | zonk: "blarg"
- // | }
- //
- // Note that spaces and other urlencoded entities are correctly
- // handled.
- // FIXME: should we grab the URL string if we're not passed one?
- var dec = decodeURIComponent, qp = str.split("&"), ret = {}, name, val;
- for(var i = 0, l = qp.length, item; i < l; ++i){
- item = qp[i];
- if(item.length){
- var s = item.indexOf("=");
- if(s < 0){
- name = dec(item);
- val = "";
- }else{
- name = dec(item.slice(0, s));
- val = dec(item.slice(s + 1));
- }
- if(typeof ret[name] == "string"){ // inline'd type check
- ret[name] = [ret[name]];
- }
- if(lang.isArray(ret[name])){
- ret[name].push(val);
- }else{
- ret[name] = val;
- }
- }
- }
- return ret; // Object
- }
- };
- });
- },
- 'dojo/_base/Deferred':function(){
- define([
- "./kernel",
- "../Deferred",
- "../promise/Promise",
- "../errors/CancelError",
- "../has",
- "./lang",
- "../when"
- ], function(dojo, NewDeferred, Promise, CancelError, has, lang, when){
- // module:
- // dojo/_base/Deferred
- var mutator = function(){};
- var freeze = Object.freeze || function(){};
- // A deferred provides an API for creating and resolving a promise.
- var Deferred = dojo.Deferred = function(/*Function?*/ canceller){
- // summary:
- // Deprecated. This module defines the legacy dojo/_base/Deferred API.
- // New code should use dojo/Deferred instead.
- // description:
- // The Deferred API is based on the concept of promises that provide a
- // generic interface into the eventual completion of an asynchronous action.
- // The motivation for promises fundamentally is about creating a
- // separation of concerns that allows one to achieve the same type of
- // call patterns and logical data flow in asynchronous code as can be
- // achieved in synchronous code. Promises allows one
- // to be able to call a function purely with arguments needed for
- // execution, without conflating the call with concerns of whether it is
- // sync or async. One shouldn't need to alter a call's arguments if the
- // implementation switches from sync to async (or vice versa). By having
- // async functions return promises, the concerns of making the call are
- // separated from the concerns of asynchronous interaction (which are
- // handled by the promise).
- //
- // The Deferred is a type of promise that provides methods for fulfilling the
- // promise with a successful result or an error. The most important method for
- // working with Dojo's promises is the then() method, which follows the
- // CommonJS proposed promise API. An example of using a Dojo promise:
- //
- // | var resultingPromise = someAsyncOperation.then(function(result){
- // | ... handle result ...
- // | },
- // | function(error){
- // | ... handle error ...
- // | });
- //
- // The .then() call returns a new promise that represents the result of the
- // execution of the callback. The callbacks will never affect the original promises value.
- //
- // The Deferred instances also provide the following functions for backwards compatibility:
- //
- // - addCallback(handler)
- // - addErrback(handler)
- // - callback(result)
- // - errback(result)
- //
- // Callbacks are allowed to return promises themselves, so
- // you can build complicated sequences of events with ease.
- //
- // The creator of the Deferred may specify a canceller. The canceller
- // is a function that will be called if Deferred.cancel is called
- // before the Deferred fires. You can use this to implement clean
- // aborting of an XMLHttpRequest, etc. Note that cancel will fire the
- // deferred with a CancelledError (unless your canceller returns
- // another kind of error), so the errbacks should be prepared to
- // handle that error for cancellable Deferreds.
- // example:
- // | var deferred = new Deferred();
- // | setTimeout(function(){ deferred.callback({success: true}); }, 1000);
- // | return deferred;
- // example:
- // Deferred objects are often used when making code asynchronous. It
- // may be easiest to write functions in a synchronous manner and then
- // split code using a deferred to trigger a response to a long-lived
- // operation. For example, instead of register a callback function to
- // denote when a rendering operation completes, the function can
- // simply return a deferred:
- //
- // | // callback style:
- // | function renderLotsOfData(data, callback){
- // | var success = false
- // | try{
- // | for(var x in data){
- // | renderDataitem(data[x]);
- // | }
- // | success = true;
- // | }catch(e){ }
- // | if(callback){
- // | callback(success);
- // | }
- // | }
- //
- // | // using callback style
- // | renderLotsOfData(someDataObj, function(success){
- // | // handles success or failure
- // | if(!success){
- // | promptUserToRecover();
- // | }
- // | });
- // | // NOTE: no way to add another callback here!!
- // example:
- // Using a Deferred doesn't simplify the sending code any, but it
- // provides a standard interface for callers and senders alike,
- // providing both with a simple way to service multiple callbacks for
- // an operation and freeing both sides from worrying about details
- // such as "did this get called already?". With Deferreds, new
- // callbacks can be added at any time.
- //
- // | // Deferred style:
- // | function renderLotsOfData(data){
- // | var d = new Deferred();
- // | try{
- // | for(var x in data){
- // | renderDataitem(data[x]);
- // | }
- // | d.callback(true);
- // | }catch(e){
- // | d.errback(new Error("rendering failed"));
- // | }
- // | return d;
- // | }
- //
- // | // using Deferred style
- // | renderLotsOfData(someDataObj).then(null, function(){
- // | promptUserToRecover();
- // | });
- // | // NOTE: addErrback and addCallback both return the Deferred
- // | // again, so we could chain adding callbacks or save the
- // | // deferred for later should we need to be notified again.
- // example:
- // In this example, renderLotsOfData is synchronous and so both
- // versions are pretty artificial. Putting the data display on a
- // timeout helps show why Deferreds rock:
- //
- // | // Deferred style and async func
- // | function renderLotsOfData(data){
- // | var d = new Deferred();
- // | setTimeout(function(){
- // | try{
- // | for(var x in data){
- // | renderDataitem(data[x]);
- // | }
- // | d.callback(true);
- // | }catch(e){
- // | d.errback(new Error("rendering failed"));
- // | }
- // | }, 100);
- // | return d;
- // | }
- //
- // | // using Deferred style
- // | renderLotsOfData(someDataObj).then(null, function(){
- // | promptUserToRecover();
- // | });
- //
- // Note that the caller doesn't have to change his code at all to
- // handle the asynchronous case.
- var result, finished, isError, head, nextListener;
- var promise = (this.promise = new Promise());
- function complete(value){
- if(finished){
- throw new Error("This deferred has already been resolved");
- }
- result = value;
- finished = true;
- notify();
- }
- function notify(){
- var mutated;
- while(!mutated && nextListener){
- var listener = nextListener;
- nextListener = nextListener.next;
- if((mutated = (listener.progress == mutator))){ // assignment and check
- finished = false;
- }
- var func = (isError ? listener.error : listener.resolved);
- if(has("config-useDeferredInstrumentation")){
- if(isError && NewDeferred.instrumentRejected){
- NewDeferred.instrumentRejected(result, !!func);
- }
- }
- if(func){
- try{
- var newResult = func(result);
- if (newResult && typeof newResult.then === "function"){
- newResult.then(lang.hitch(listener.deferred, "resolve"), lang.hitch(listener.deferred, "reject"), lang.hitch(listener.deferred, "progress"));
- continue;
- }
- var unchanged = mutated && newResult === undefined;
- if(mutated && !unchanged){
- isError = newResult instanceof Error;
- }
- listener.deferred[unchanged && isError ? "reject" : "resolve"](unchanged ? result : newResult);
- }catch(e){
- listener.deferred.reject(e);
- }
- }else{
- if(isError){
- listener.deferred.reject(result);
- }else{
- listener.deferred.resolve(result);
- }
- }
- }
- }
- // calling resolve will resolve the promise
- this.resolve = this.callback = function(value){
- // summary:
- // Fulfills the Deferred instance successfully with the provide value
- this.fired = 0;
- this.results = [value, null];
- complete(value);
- };
- // calling error will indicate that the promise failed
- this.reject = this.errback = function(error){
- // summary:
- // Fulfills the Deferred instance as an error with the provided error
- isError = true;
- this.fired = 1;
- if(has("config-useDeferredInstrumentation")){
- if(NewDeferred.instrumentRejected){
- NewDeferred.instrumentRejected(error, !!nextListener);
- }
- }
- complete(error);
- this.results = [null, error];
- };
- // call progress to provide updates on the progress on the completion of the promise
- this.progress = function(update){
- // summary:
- // Send progress events to all listeners
- var listener = nextListener;
- while(listener){
- var progress = listener.progress;
- progress && progress(update);
- listener = listener.next;
- }
- };
- this.addCallbacks = function(callback, errback){
- // summary:
- // Adds callback and error callback for this deferred instance.
- // callback: Function?
- // The callback attached to this deferred object.
- // errback: Function?
- // The error callback attached to this deferred object.
- // returns:
- // Returns this deferred object.
- this.then(callback, errback, mutator);
- return this; // Deferred
- };
- // provide the implementation of the promise
- promise.then = this.then = function(/*Function?*/resolvedCallback, /*Function?*/errorCallback, /*Function?*/progressCallback){
- // summary:
- // Adds a fulfilledHandler, errorHandler, and progressHandler to be called for
- // completion of a promise. The fulfilledHandler is called when the promise
- // is fulfilled. The errorHandler is called when a promise fails. The
- // progressHandler is called for progress events. All arguments are optional
- // and non-function values are ignored. The progressHandler is not only an
- // optional argument, but progress events are purely optional. Promise
- // providers are not required to ever create progress events.
- //
- // This function will return a new promise that is fulfilled when the given
- // fulfilledHandler or errorHandler callback is finished. This allows promise
- // operations to be chained together. The value returned from the callback
- // handler is the fulfillment value for the returned promise. If the callback
- // throws an error, the returned promise will be moved to failed state.
- //
- // returns:
- // Returns a new promise that represents the result of the
- // execution of the callback. The callbacks will never affect the original promises value.
- // example:
- // An example of using a CommonJS compliant promise:
- // | asyncComputeTheAnswerToEverything().
- // | then(addTwo).
- // | then(printResult, onError);
- // | >44
- //
- var returnDeferred = progressCallback == mutator ? this : new Deferred(promise.cancel);
- var listener = {
- resolved: resolvedCallback,
- error: errorCallback,
- progress: progressCallback,
- deferred: returnDeferred
- };
- if(nextListener){
- head = head.next = listener;
- }
- else{
- nextListener = head = listener;
- }
- if(finished){
- notify();
- }
- return returnDeferred.promise; // Promise
- };
- var deferred = this;
- promise.cancel = this.cancel = function(){
- // summary:
- // Cancels the asynchronous operation
- if(!finished){
- var error = canceller && canceller(deferred);
- if(!finished){
- if (!(error instanceof Error)){
- error = new CancelError(error);
- }
- error.log = false;
- deferred.reject(error);
- }
- }
- };
- freeze(promise);
- };
- lang.extend(Deferred, {
- addCallback: function(/*Function*/ callback){
- // summary:
- // Adds successful callback for this deferred instance.
- // returns:
- // Returns this deferred object.
- return this.addCallbacks(lang.hitch.apply(dojo, arguments)); // Deferred
- },
- addErrback: function(/*Function*/ errback){
- // summary:
- // Adds error callback for this deferred instance.
- // returns:
- // Returns this deferred object.
- return this.addCallbacks(null, lang.hitch.apply(dojo, arguments)); // Deferred
- },
- addBoth: function(/*Function*/ callback){
- // summary:
- // Add handler as both successful callback and error callback for this deferred instance.
- // returns:
- // Returns this deferred object.
- var enclosed = lang.hitch.apply(dojo, arguments);
- return this.addCallbacks(enclosed, enclosed); // Deferred
- },
- fired: -1
- });
- Deferred.when = dojo.when = when;
- return Deferred;
- });
- },
- 'dojo/NodeList-dom':function(){
- define(["./_base/kernel", "./query", "./_base/array", "./_base/lang", "./dom-class", "./dom-construct", "./dom-geometry", "./dom-attr", "./dom-style"], function(dojo, query, array, lang, domCls, domCtr, domGeom, domAttr, domStyle){
- // module:
- // dojo/NodeList-dom.js
- /*=====
- return function(){
- // summary:
- // Adds DOM related methods to NodeList, and returns NodeList constructor.
- };
- =====*/
- var magicGuard = function(a){
- // summary:
- // the guard function for dojo.attr() and dojo.style()
- return a.length == 1 && (typeof a[0] == "string"); // inline'd type check
- };
- var orphan = function(node){
- // summary:
- // function to orphan nodes
- var p = node.parentNode;
- if(p){
- p.removeChild(node);
- }
- };
- // FIXME: should we move orphan() to dojo.html?
- var NodeList = query.NodeList,
- awc = NodeList._adaptWithCondition,
- aafe = NodeList._adaptAsForEach,
- aam = NodeList._adaptAsMap;
- function getSet(module){
- return function(node, name, value){
- if(arguments.length == 2){
- return module[typeof name == "string" ? "get" : "set"](node, name);
- }
- // setter
- return module.set(node, name, value);
- };
- }
- lang.extend(NodeList, {
- _normalize: function(/*String||Element||Object||NodeList*/content, /*DOMNode?*/refNode){
- // summary:
- // normalizes data to an array of items to insert.
- // description:
- // If content is an object, it can have special properties "template" and
- // "parse". If "template" is defined, then the template value is run through
- // dojo.string.substitute (if dojo/string.substitute() has been dojo.required elsewhere),
- // or if templateFunc is a function on the content, that function will be used to
- // transform the template into a final string to be used for for passing to dojo/dom-construct.toDom().
- // If content.parse is true, then it is remembered for later, for when the content
- // nodes are inserted into the DOM. At that point, the nodes will be parsed for widgets
- // (if dojo.parser has been dojo.required elsewhere).
- //Wanted to just use a DocumentFragment, but for the array/NodeList
- //case that meant using cloneNode, but we may not want that.
- //Cloning should only happen if the node operations span
- //multiple refNodes. Also, need a real array, not a NodeList from the
- //DOM since the node movements could change those NodeLists.
- var parse = content.parse === true;
- //Do we have an object that needs to be run through a template?
- if(typeof content.template == "string"){
- var templateFunc = content.templateFunc || (dojo.string && dojo.string.substitute);
- content = templateFunc ? templateFunc(content.template, content) : content;
- }
- var type = (typeof content);
- if(type == "string" || type == "number"){
- content = domCtr.toDom(content, (refNode && refNode.ownerDocument));
- if(content.nodeType == 11){
- //DocumentFragment. It cannot handle cloneNode calls, so pull out the children.
- content = lang._toArray(content.childNodes);
- }else{
- content = [content];
- }
- }else if(!lang.isArrayLike(content)){
- content = [content];
- }else if(!lang.isArray(content)){
- //To get to this point, content is array-like, but
- //not an array, which likely means a DOM NodeList. Convert it now.
- content = lang._toArray(content);
- }
- //Pass around the parse info
- if(parse){
- content._runParse = true;
- }
- return content; //Array
- },
- _cloneNode: function(/*DOMNode*/ node){
- // summary:
- // private utility to clone a node. Not very interesting in the vanilla
- // dojo/NodeList case, but delegates could do interesting things like
- // clone event handlers if that is derivable from the node.
- return node.cloneNode(true);
- },
- _place: function(/*Array*/ary, /*DOMNode*/refNode, /*String*/position, /*Boolean*/useClone){
- // summary:
- // private utility to handle placing an array of nodes relative to another node.
- // description:
- // Allows for cloning the nodes in the array, and for
- // optionally parsing widgets, if ary._runParse is true.
- //Avoid a disallowed operation if trying to do an innerHTML on a non-element node.
- if(refNode.nodeType != 1 && position == "only"){
- return;
- }
- var rNode = refNode, tempNode;
- //Always cycle backwards in case the array is really a
- //DOM NodeList and the DOM operations take it out of the live collection.
- var length = ary.length;
- for(var i = length - 1; i >= 0; i--){
- var node = (useClone ? this._cloneNode(ary[i]) : ary[i]);
- //If need widget parsing, use a temp node, instead of waiting after inserting into
- //real DOM because we need to start widget parsing at one node up from current node,
- //which could cause some already parsed widgets to be parsed again.
- if(ary._runParse && dojo.parser && dojo.parser.parse){
- if(!tempNode){
- tempNode = rNode.ownerDocument.createElement("div");
- }
- tempNode.appendChild(node);
- dojo.parser.parse(tempNode);
- node = tempNode.firstChild;
- while(tempNode.firstChild){
- tempNode.removeChild(tempNode.firstChild);
- }
- }
- if(i == length - 1){
- domCtr.place(node, rNode, position);
- }else{
- rNode.parentNode.insertBefore(node, rNode);
- }
- rNode = node;
- }
- },
- position: aam(domGeom.position),
- /*=====
- position: function(){
- // summary:
- // Returns border-box objects (x/y/w/h) of all elements in a node list
- // as an Array (*not* a NodeList). Acts like `dojo.position`, though
- // assumes the node passed is each node in this list.
- return dojo.map(this, dojo.position); // Array
- },
- =====*/
- attr: awc(getSet(domAttr), magicGuard),
- /*=====
- attr: function(property, value){
- // summary:
- // gets or sets the DOM attribute for every element in the
- // NodeList. See also `dojo.attr`
- // property: String
- // the attribute to get/set
- // value: String?
- // optional. The value to set the property to
- // returns:
- // if no value is passed, the result is an array of attribute values
- // If a value is passed, the return is this NodeList
- // example:
- // Make all nodes with a particular class focusable:
- // | dojo.query(".focusable").attr("tabIndex", -1);
- // example:
- // Disable a group of buttons:
- // | dojo.query("button.group").attr("disabled", true);
- // example:
- // innerHTML can be assigned or retrieved as well:
- // | // get the innerHTML (as an array) for each list item
- // | var ih = dojo.query("li.replaceable").attr("innerHTML");
- return; // dojo/NodeList|Array
- },
- =====*/
- style: awc(getSet(domStyle), magicGuard),
- /*=====
- style: function(property, value){
- // summary:
- // gets or sets the CSS property for every element in the NodeList
- // property: String
- // the CSS property to get/set, in JavaScript notation
- // ("lineHieght" instead of "line-height")
- // value: String?
- // optional. The value to set the property to
- // returns:
- // if no value is passed, the result is an array of strings.
- // If a value is passed, the return is this NodeList
- return; // dojo/NodeList
- return; // Array
- },
- =====*/
- addClass: aafe(domCls.add),
- /*=====
- addClass: function(className){
- // summary:
- // adds the specified class to every node in the list
- // className: String|Array
- // A String class name to add, or several space-separated class names,
- // or an array of class names.
- return; // dojo/NodeList
- },
- =====*/
- removeClass: aafe(domCls.remove),
- /*=====
- removeClass: function(className){
- // summary:
- // removes the specified class from every node in the list
- // className: String|Array?
- // An optional String class name to remove, or several space-separated
- // class names, or an array of class names. If omitted, all class names
- // will be deleted.
- // returns:
- // this list
- return; // dojo/NodeList
- },
- =====*/
- toggleClass: aafe(domCls.toggle),
- /*=====
- toggleClass: function(className, condition){
- // summary:
- // Adds a class to node if not present, or removes if present.
- // Pass a boolean condition if you want to explicitly add or remove.
- // condition: Boolean?
- // If passed, true means to add the class, false means to remove.
- // className: String
- // the CSS class to add
- return; // dojo/NodeList
- },
- =====*/
- replaceClass: aafe(domCls.replace),
- /*=====
- replaceClass: function(addClassStr, removeClassStr){
- // summary:
- // Replaces one or more classes on a node if not present.
- // Operates more quickly than calling `removeClass()` and `addClass()`
- // addClassStr: String|Array
- // A String class name to add, or several space-separated class names,
- // or an array of class names.
- // removeClassStr: String|Array?
- // A String class name to remove, or several space-separated class names,
- // or an array of class names.
- return; // dojo/NodeList
- },
- =====*/
- empty: aafe(domCtr.empty),
- /*=====
- empty: function(){
- // summary:
- // clears all content from each node in the list. Effectively
- // equivalent to removing all child nodes from every item in
- // the list.
- return this.forEach("item.innerHTML='';"); // dojo/NodeList
- // FIXME: should we be checking for and/or disposing of widgets below these nodes?
- },
- =====*/
- removeAttr: aafe(domAttr.remove),
- /*=====
- removeAttr: function(name){
- // summary:
- // Removes an attribute from each node in the list.
- // name: String
- // the name of the attribute to remove
- return; // dojo/NodeList
- },
- =====*/
- marginBox: aam(domGeom.getMarginBox),
- /*=====
- marginBox: function(){
- // summary:
- // Returns margin-box size of nodes
- return; // dojo/NodeList
- },
- =====*/
- // FIXME: connectPublisher()? connectRunOnce()?
- /*
- destroy: function(){
- // summary:
- // destroys every item in the list.
- this.forEach(d.destroy);
- // FIXME: should we be checking for and/or disposing of widgets below these nodes?
- },
- */
- place: function(/*String||Node*/ queryOrNode, /*String*/ position){
- // summary:
- // places elements of this node list relative to the first element matched
- // by queryOrNode. Returns the original NodeList. See: `dojo.place`
- // queryOrNode:
- // may be a string representing any valid CSS3 selector or a DOM node.
- // In the selector case, only the first matching element will be used
- // for relative positioning.
- // position:
- // can be one of:
- //
- // - "last" (default)
- // - "first"
- // - "before"
- // - "after"
- // - "only"
- // - "replace"
- //
- // or an offset in the childNodes property
- var item = query(queryOrNode)[0];
- return this.forEach(function(node){ domCtr.place(node, item, position); }); // dojo/NodeList
- },
- orphan: function(/*String?*/ filter){
- // summary:
- // removes elements in this list that match the filter
- // from their parents and returns them as a new NodeList.
- // filter:
- // CSS selector like ".foo" or "div > span"
- // returns:
- // NodeList containing the orphaned elements
- return (filter ? query._filterResult(this, filter) : this).forEach(orphan); // dojo/NodeList
- },
- adopt: function(/*String||Array||DomNode*/ queryOrListOrNode, /*String?*/ position){
- // summary:
- // places any/all elements in queryOrListOrNode at a
- // position relative to the first element in this list.
- // Returns a dojo/NodeList of the adopted elements.
- // queryOrListOrNode:
- // a DOM node or a query string or a query result.
- // Represents the nodes to be adopted relative to the
- // first element of this NodeList.
- // position:
- // can be one of:
- //
- // - "last" (default)
- // - "first"
- // - "before"
- // - "after"
- // - "only"
- // - "replace"
- //
- // or an offset in the childNodes property
- return query(queryOrListOrNode).place(this[0], position)._stash(this); // dojo/NodeList
- },
- // FIXME: do we need this?
- query: function(/*String*/ queryStr){
- // summary:
- // Returns a new list whose members match the passed query,
- // assuming elements of the current NodeList as the root for
- // each search.
- // example:
- // assume a DOM created by this markup:
- // | <div id="foo">
- // | <p>
- // | bacon is tasty, <span>dontcha think?</span>
- // | </p>
- // | </div>
- // | <div id="bar">
- // | <p>great comedians may not be funny <span>in person</span></p>
- // | </div>
- // If we are presented with the following definition for a NodeList:
- // | var l = new NodeList(dojo.byId("foo"), dojo.byId("bar"));
- // it's possible to find all span elements under paragraphs
- // contained by these elements with this sub-query:
- // | var spans = l.query("p span");
- // FIXME: probably slow
- if(!queryStr){ return this; }
- var ret = new NodeList;
- this.map(function(node){
- // FIXME: why would we ever get undefined here?
- query(queryStr, node).forEach(function(subNode){
- if(subNode !== undefined){
- ret.push(subNode);
- }
- });
- });
- return ret._stash(this); // dojo/NodeList
- },
- filter: function(/*String|Function*/ filter){
- // summary:
- // "masks" the built-in javascript filter() method (supported
- // in Dojo via `dojo.filter`) to support passing a simple
- // string filter in addition to supporting filtering function
- // objects.
- // filter:
- // If a string, a CSS rule like ".thinger" or "div > span".
- // example:
- // "regular" JS filter syntax as exposed in dojo.filter:
- // | dojo.query("*").filter(function(item){
- // | // highlight every paragraph
- // | return (item.nodeName == "p");
- // | }).style("backgroundColor", "yellow");
- // example:
- // the same filtering using a CSS selector
- // | dojo.query("*").filter("p").styles("backgroundColor", "yellow");
- var a = arguments, items = this, start = 0;
- if(typeof filter == "string"){ // inline'd type check
- items = query._filterResult(this, a[0]);
- if(a.length == 1){
- // if we only got a string query, pass back the filtered results
- return items._stash(this); // dojo/NodeList
- }
- // if we got a callback, run it over the filtered items
- start = 1;
- }
- return this._wrap(array.filter(items, a[start], a[start + 1]), this); // dojo/NodeList
- },
- /*
- // FIXME: should this be "copyTo" and include parenting info?
- clone: function(){
- // summary:
- // creates node clones of each element of this list
- // and returns a new list containing the clones
- },
- */
- addContent: function(/*String||DomNode||Object||dojo/NodeList*/ content, /*String||Integer?*/ position){
- // summary:
- // add a node, NodeList or some HTML as a string to every item in the
- // list. Returns the original list.
- // description:
- // a copy of the HTML content is added to each item in the
- // list, with an optional position argument. If no position
- // argument is provided, the content is appended to the end of
- // each item.
- // content:
- // DOM node, HTML in string format, a NodeList or an Object. If a DOM node or
- // NodeList, the content will be cloned if the current NodeList has more than one
- // element. Only the DOM nodes are cloned, no event handlers. If it is an Object,
- // it should be an object with at "template" String property that has the HTML string
- // to insert. If dojo.string has already been dojo.required, then dojo.string.substitute
- // will be used on the "template" to generate the final HTML string. Other allowed
- // properties on the object are: "parse" if the HTML
- // string should be parsed for widgets (dojo.require("dojo.parser") to get that
- // option to work), and "templateFunc" if a template function besides dojo.string.substitute
- // should be used to transform the "template".
- // position:
- // can be one of:
- //
- // - "last"||"end" (default)
- // - "first||"start"
- // - "before"
- // - "after"
- // - "replace" (replaces nodes in this NodeList with new content)
- // - "only" (removes other children of the nodes so new content is the only child)
- //
- // or an offset in the childNodes property
- // example:
- // appends content to the end if the position is omitted
- // | dojo.query("h3 > p").addContent("hey there!");
- // example:
- // add something to the front of each element that has a
- // "thinger" property:
- // | dojo.query("[thinger]").addContent("...", "first");
- // example:
- // adds a header before each element of the list
- // | dojo.query(".note").addContent("<h4>NOTE:</h4>", "before");
- // example:
- // add a clone of a DOM node to the end of every element in
- // the list, removing it from its existing parent.
- // | dojo.query(".note").addContent(dojo.byId("foo"));
- // example:
- // Append nodes from a templatized string.
- // | dojo.require("dojo.string");
- // | dojo.query(".note").addContent({
- // | template: '<b>${id}: </b><span>${name}</span>',
- // | id: "user332",
- // | name: "Mr. Anderson"
- // | });
- // example:
- // Append nodes from a templatized string that also has widgets parsed.
- // | dojo.require("dojo.string");
- // | dojo.require("dojo.parser");
- // | var notes = dojo.query(".note").addContent({
- // | template: '<button dojoType="dijit/form/Button">${text}</button>',
- // | parse: true,
- // | text: "Send"
- // | });
- content = this._normalize(content, this[0]);
- for(var i = 0, node; (node = this[i]); i++){
- this._place(content, node, position, i > 0);
- }
- return this; // dojo/NodeList
- }
- });
- return NodeList;
- });
- },
- 'dojo/query':function(){
- define(["./_base/kernel", "./has", "./dom", "./on", "./_base/array", "./_base/lang", "./selector/_loader", "./selector/_loader!default"],
- function(dojo, has, dom, on, array, lang, loader, defaultEngine){
- "use strict";
- has.add("array-extensible", function(){
- // test to see if we can extend an array (not supported in old IE)
- return lang.delegate([], {length: 1}).length == 1 && !has("bug-for-in-skips-shadowed");
- });
-
- var ap = Array.prototype, aps = ap.slice, apc = ap.concat, forEach = array.forEach;
- var tnl = function(/*Array*/ a, /*dojo/NodeList?*/ parent, /*Function?*/ NodeListCtor){
- // summary:
- // decorate an array to make it look like a `dojo/NodeList`.
- // a:
- // Array of nodes to decorate.
- // parent:
- // An optional parent NodeList that generated the current
- // list of nodes. Used to call _stash() so the parent NodeList
- // can be accessed via end() later.
- // NodeListCtor:
- // An optional constructor function to use for any
- // new NodeList calls. This allows a certain chain of
- // NodeList calls to use a different object than dojo/NodeList.
- var nodeList = new (NodeListCtor || this._NodeListCtor || nl)(a);
- return parent ? nodeList._stash(parent) : nodeList;
- };
- var loopBody = function(f, a, o){
- a = [0].concat(aps.call(a, 0));
- o = o || dojo.global;
- return function(node){
- a[0] = node;
- return f.apply(o, a);
- };
- };
- // adapters
- var adaptAsForEach = function(f, o){
- // summary:
- // adapts a single node function to be used in the forEach-type
- // actions. The initial object is returned from the specialized
- // function.
- // f: Function
- // a function to adapt
- // o: Object?
- // an optional context for f
- return function(){
- this.forEach(loopBody(f, arguments, o));
- return this; // Object
- };
- };
- var adaptAsMap = function(f, o){
- // summary:
- // adapts a single node function to be used in the map-type
- // actions. The return is a new array of values, as via `dojo.map`
- // f: Function
- // a function to adapt
- // o: Object?
- // an optional context for f
- return function(){
- return this.map(loopBody(f, arguments, o));
- };
- };
- var adaptAsFilter = function(f, o){
- // summary:
- // adapts a single node function to be used in the filter-type actions
- // f: Function
- // a function to adapt
- // o: Object?
- // an optional context for f
- return function(){
- return this.filter(loopBody(f, arguments, o));
- };
- };
- var adaptWithCondition = function(f, g, o){
- // summary:
- // adapts a single node function to be used in the map-type
- // actions, behaves like forEach() or map() depending on arguments
- // f: Function
- // a function to adapt
- // g: Function
- // a condition function, if true runs as map(), otherwise runs as forEach()
- // o: Object?
- // an optional context for f and g
- return function(){
- var a = arguments, body = loopBody(f, a, o);
- if(g.call(o || dojo.global, a)){
- return this.map(body); // self
- }
- this.forEach(body);
- return this; // self
- };
- };
- var NodeList = function(array){
- // summary:
- // Array-like object which adds syntactic
- // sugar for chaining, common iteration operations, animation, and
- // node manipulation. NodeLists are most often returned as the
- // result of dojo.query() calls.
- // description:
- // NodeList instances provide many utilities that reflect
- // core Dojo APIs for Array iteration and manipulation, DOM
- // manipulation, and event handling. Instead of needing to dig up
- // functions in the dojo.* namespace, NodeLists generally make the
- // full power of Dojo available for DOM manipulation tasks in a
- // simple, chainable way.
- // example:
- // create a node list from a node
- // | new query.NodeList(dojo.byId("foo"));
- // example:
- // get a NodeList from a CSS query and iterate on it
- // | var l = dojo.query(".thinger");
- // | l.forEach(function(node, index, nodeList){
- // | console.log(index, node.innerHTML);
- // | });
- // example:
- // use native and Dojo-provided array methods to manipulate a
- // NodeList without needing to use dojo.* functions explicitly:
- // | var l = dojo.query(".thinger");
- // | // since NodeLists are real arrays, they have a length
- // | // property that is both readable and writable and
- // | // push/pop/shift/unshift methods
- // | console.log(l.length);
- // | l.push(dojo.create("span"));
- // |
- // | // dojo's normalized array methods work too:
- // | console.log( l.indexOf(dojo.byId("foo")) );
- // | // ...including the special "function as string" shorthand
- // | console.log( l.every("item.nodeType == 1") );
- // |
- // | // NodeLists can be [..] indexed, or you can use the at()
- // | // function to get specific items wrapped in a new NodeList:
- // | var node = l[3]; // the 4th element
- // | var newList = l.at(1, 3); // the 2nd and 4th elements
- // example:
- // the style functions you expect are all there too:
- // | // style() as a getter...
- // | var borders = dojo.query(".thinger").style("border");
- // | // ...and as a setter:
- // | dojo.query(".thinger").style("border", "1px solid black");
- // | // class manipulation
- // | dojo.query("li:nth-child(even)").addClass("even");
- // | // even getting the coordinates of all the items
- // | var coords = dojo.query(".thinger").coords();
- // example:
- // DOM manipulation functions from the dojo.* namespace area also available:
- // | // remove all of the elements in the list from their
- // | // parents (akin to "deleting" them from the document)
- // | dojo.query(".thinger").orphan();
- // | // place all elements in the list at the front of #foo
- // | dojo.query(".thinger").place("foo", "first");
- // example:
- // Event handling couldn't be easier. `dojo.connect` is mapped in,
- // and shortcut handlers are provided for most DOM events:
- // | // like dojo.connect(), but with implicit scope
- // | dojo.query("li").connect("onclick", console, "log");
- // |
- // | // many common event handlers are already available directly:
- // | dojo.query("li").onclick(console, "log");
- // | var toggleHovered = dojo.hitch(dojo, "toggleClass", "hovered");
- // | dojo.query("p")
- // | .onmouseenter(toggleHovered)
- // | .onmouseleave(toggleHovered);
- // example:
- // chainability is a key advantage of NodeLists:
- // | dojo.query(".thinger")
- // | .onclick(function(e){ /* ... */ })
- // | .at(1, 3, 8) // get a subset
- // | .style("padding", "5px")
- // | .forEach(console.log);
- var isNew = this instanceof nl && has("array-extensible");
- if(typeof array == "number"){
- array = Array(array);
- }
- var nodeArray = (array && "length" in array) ? array : arguments;
- if(isNew || !nodeArray.sort){
- // make sure it's a real array before we pass it on to be wrapped
- var target = isNew ? this : [],
- l = target.length = nodeArray.length;
- for(var i = 0; i < l; i++){
- target[i] = nodeArray[i];
- }
- if(isNew){
- // called with new operator, this means we are going to use this instance and push
- // the nodes on to it. This is usually much faster since the NodeList properties
- // don't need to be copied (unless the list of nodes is extremely large).
- return target;
- }
- nodeArray = target;
- }
- // called without new operator, use a real array and copy prototype properties,
- // this is slower and exists for back-compat. Should be removed in 2.0.
- lang._mixin(nodeArray, nlp);
- nodeArray._NodeListCtor = function(array){
- // call without new operator to preserve back-compat behavior
- return nl(array);
- };
- return nodeArray;
- };
-
- var nl = NodeList, nlp = nl.prototype =
- has("array-extensible") ? [] : {};// extend an array if it is extensible
- // expose adapters and the wrapper as private functions
- nl._wrap = nlp._wrap = tnl;
- nl._adaptAsMap = adaptAsMap;
- nl._adaptAsForEach = adaptAsForEach;
- nl._adaptAsFilter = adaptAsFilter;
- nl._adaptWithCondition = adaptWithCondition;
- // mass assignment
- // add array redirectors
- forEach(["slice", "splice"], function(name){
- var f = ap[name];
- //Use a copy of the this array via this.slice() to allow .end() to work right in the splice case.
- // CANNOT apply ._stash()/end() to splice since it currently modifies
- // the existing this array -- it would break backward compatibility if we copy the array before
- // the splice so that we can use .end(). So only doing the stash option to this._wrap for slice.
- nlp[name] = function(){ return this._wrap(f.apply(this, arguments), name == "slice" ? this : null); };
- });
- // concat should be here but some browsers with native NodeList have problems with it
- // add array.js redirectors
- forEach(["indexOf", "lastIndexOf", "every", "some"], function(name){
- var f = array[name];
- nlp[name] = function(){ return f.apply(dojo, [this].concat(aps.call(arguments, 0))); };
- });
- lang.extend(NodeList, {
- // copy the constructors
- constructor: nl,
- _NodeListCtor: nl,
- toString: function(){
- // Array.prototype.toString can't be applied to objects, so we use join
- return this.join(",");
- },
- _stash: function(parent){
- // summary:
- // private function to hold to a parent NodeList. end() to return the parent NodeList.
- //
- // example:
- // How to make a `dojo/NodeList` method that only returns the third node in
- // the dojo/NodeList but allows access to the original NodeList by using this._stash:
- // | dojo.extend(NodeList, {
- // | third: function(){
- // | var newNodeList = NodeList(this[2]);
- // | return newNodeList._stash(this);
- // | }
- // | });
- // | // then see how _stash applies a sub-list, to be .end()'ed out of
- // | dojo.query(".foo")
- // | .third()
- // | .addClass("thirdFoo")
- // | .end()
- // | // access to the orig .foo list
- // | .removeClass("foo")
- // |
- //
- this._parent = parent;
- return this; // dojo/NodeList
- },
- on: function(eventName, listener){
- // summary:
- // Listen for events on the nodes in the NodeList. Basic usage is:
- // | query(".my-class").on("click", listener);
- // This supports event delegation by using selectors as the first argument with the event names as
- // pseudo selectors. For example:
- // | dojo.query("#my-list").on("li:click", listener);
- // This will listen for click events within `<li>` elements that are inside the `#my-list` element.
- // Because on supports CSS selector syntax, we can use comma-delimited events as well:
- // | dojo.query("#my-list").on("li button:mouseover, li:click", listener);
- var handles = this.map(function(node){
- return on(node, eventName, listener); // TODO: apply to the NodeList so the same selector engine is used for matches
- });
- handles.remove = function(){
- for(var i = 0; i < handles.length; i++){
- handles[i].remove();
- }
- };
- return handles;
- },
- end: function(){
- // summary:
- // Ends use of the current `NodeList` by returning the previous NodeList
- // that generated the current NodeList.
- // description:
- // Returns the `NodeList` that generated the current `NodeList`. If there
- // is no parent NodeList, an empty NodeList is returned.
- // example:
- // | dojo.query("a")
- // | .filter(".disabled")
- // | // operate on the anchors that only have a disabled class
- // | .style("color", "grey")
- // | .end()
- // | // jump back to the list of anchors
- // | .style(...)
- //
- if(this._parent){
- return this._parent;
- }else{
- //Just return empty list.
- return new this._NodeListCtor(0);
- }
- },
- // http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array#Methods
- // FIXME: handle return values for #3244
- // http://trac.dojotoolkit.org/ticket/3244
- // FIXME:
- // need to wrap or implement:
- // join (perhaps w/ innerHTML/outerHTML overload for toString() of items?)
- // reduce
- // reduceRight
- /*=====
- slice: function(begin, end){
- // summary:
- // Returns a new NodeList, maintaining this one in place
- // description:
- // This method behaves exactly like the Array.slice method
- // with the caveat that it returns a dojo/NodeList and not a
- // raw Array. For more details, see Mozilla's [slice
- // documentation](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/slice)
- // begin: Integer
- // Can be a positive or negative integer, with positive
- // integers noting the offset to begin at, and negative
- // integers denoting an offset from the end (i.e., to the left
- // of the end)
- // end: Integer?
- // Optional parameter to describe what position relative to
- // the NodeList's zero index to end the slice at. Like begin,
- // can be positive or negative.
- return this._wrap(a.slice.apply(this, arguments));
- },
- splice: function(index, howmany, item){
- // summary:
- // Returns a new NodeList, manipulating this NodeList based on
- // the arguments passed, potentially splicing in new elements
- // at an offset, optionally deleting elements
- // description:
- // This method behaves exactly like the Array.splice method
- // with the caveat that it returns a dojo/NodeList and not a
- // raw Array. For more details, see Mozilla's [splice
- // documentation](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/splice)
- // For backwards compatibility, calling .end() on the spliced NodeList
- // does not return the original NodeList -- splice alters the NodeList in place.
- // index: Integer
- // begin can be a positive or negative integer, with positive
- // integers noting the offset to begin at, and negative
- // integers denoting an offset from the end (i.e., to the left
- // of the end)
- // howmany: Integer?
- // Optional parameter to describe what position relative to
- // the NodeList's zero index to end the slice at. Like begin,
- // can be positive or negative.
- // item: Object...?
- // Any number of optional parameters may be passed in to be
- // spliced into the NodeList
- return this._wrap(a.splice.apply(this, arguments)); // dojo/NodeList
- },
- indexOf: function(value, fromIndex){
- // summary:
- // see dojo.indexOf(). The primary difference is that the acted-on
- // array is implicitly this NodeList
- // value: Object
- // The value to search for.
- // fromIndex: Integer?
- // The location to start searching from. Optional. Defaults to 0.
- // description:
- // For more details on the behavior of indexOf, see Mozilla's
- // [indexOf
- // docs](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf)
- // returns:
- // Positive Integer or 0 for a match, -1 of not found.
- return d.indexOf(this, value, fromIndex); // Integer
- },
- lastIndexOf: function(value, fromIndex){
- // summary:
- // see dojo.lastIndexOf(). The primary difference is that the
- // acted-on array is implicitly this NodeList
- // description:
- // For more details on the behavior of lastIndexOf, see
- // Mozilla's [lastIndexOf
- // docs](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf)
- // value: Object
- // The value to search for.
- // fromIndex: Integer?
- // The location to start searching from. Optional. Defaults to 0.
- // returns:
- // Positive Integer or 0 for a match, -1 of not found.
- return d.lastIndexOf(this, value, fromIndex); // Integer
- },
- every: function(callback, thisObject){
- // summary:
- // see `dojo.every()` and the [Array.every
- // docs](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every).
- // Takes the same structure of arguments and returns as
- // dojo.every() with the caveat that the passed array is
- // implicitly this NodeList
- // callback: Function
- // the callback
- // thisObject: Object?
- // the context
- return d.every(this, callback, thisObject); // Boolean
- },
- some: function(callback, thisObject){
- // summary:
- // Takes the same structure of arguments and returns as
- // `dojo.some()` with the caveat that the passed array is
- // implicitly this NodeList. See `dojo.some()` and Mozilla's
- // [Array.some
- // documentation](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some).
- // callback: Function
- // the callback
- // thisObject: Object?
- // the context
- return d.some(this, callback, thisObject); // Boolean
- },
- =====*/
- concat: function(item){
- // summary:
- // Returns a new NodeList comprised of items in this NodeList
- // as well as items passed in as parameters
- // description:
- // This method behaves exactly like the Array.concat method
- // with the caveat that it returns a `NodeList` and not a
- // raw Array. For more details, see the [Array.concat
- // docs](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/concat)
- // item: Object?
- // Any number of optional parameters may be passed in to be
- // spliced into the NodeList
- //return this._wrap(apc.apply(this, arguments));
- // the line above won't work for the native NodeList, or for Dojo NodeLists either :-(
- // implementation notes:
- // Array.concat() doesn't recognize native NodeLists or Dojo NodeLists
- // as arrays, and so does not inline them into a unioned array, but
- // appends them as single entities. Both the original NodeList and the
- // items passed in as parameters must be converted to raw Arrays
- // and then the concatenation result may be re-_wrap()ed as a Dojo NodeList.
- var t = aps.call(this, 0),
- m = array.map(arguments, function(a){
- return aps.call(a, 0);
- });
- return this._wrap(apc.apply(t, m), this); // dojo/NodeList
- },
- map: function(/*Function*/ func, /*Function?*/ obj){
- // summary:
- // see dojo.map(). The primary difference is that the acted-on
- // array is implicitly this NodeList and the return is a
- // NodeList (a subclass of Array)
- return this._wrap(array.map(this, func, obj), this); // dojo/NodeList
- },
- forEach: function(callback, thisObj){
- // summary:
- // see `dojo.forEach()`. The primary difference is that the acted-on
- // array is implicitly this NodeList. If you want the option to break out
- // of the forEach loop, use every() or some() instead.
- forEach(this, callback, thisObj);
- // non-standard return to allow easier chaining
- return this; // dojo/NodeList
- },
- filter: function(/*String|Function*/ filter){
- // summary:
- // "masks" the built-in javascript filter() method (supported
- // in Dojo via `dojo.filter`) to support passing a simple
- // string filter in addition to supporting filtering function
- // objects.
- // filter:
- // If a string, a CSS rule like ".thinger" or "div > span".
- // example:
- // "regular" JS filter syntax as exposed in dojo.filter:
- // | dojo.query("*").filter(function(item){
- // | // highlight every paragraph
- // | return (item.nodeName == "p");
- // | }).style("backgroundColor", "yellow");
- // example:
- // the same filtering using a CSS selector
- // | dojo.query("*").filter("p").styles("backgroundColor", "yellow");
- var a = arguments, items = this, start = 0;
- if(typeof filter == "string"){ // inline'd type check
- items = query._filterResult(this, a[0]);
- if(a.length == 1){
- // if we only got a string query, pass back the filtered results
- return items._stash(this); // dojo/NodeList
- }
- // if we got a callback, run it over the filtered items
- start = 1;
- }
- return this._wrap(array.filter(items, a[start], a[start + 1]), this); // dojo/NodeList
- },
- instantiate: function(/*String|Object*/ declaredClass, /*Object?*/ properties){
- // summary:
- // Create a new instance of a specified class, using the
- // specified properties and each node in the NodeList as a
- // srcNodeRef.
- // example:
- // Grabs all buttons in the page and converts them to dijit/form/Button's.
- // | var buttons = query("button").instantiate(Button, {showLabel: true});
- var c = lang.isFunction(declaredClass) ? declaredClass : lang.getObject(declaredClass);
- properties = properties || {};
- return this.forEach(function(node){
- new c(properties, node);
- }); // dojo/NodeList
- },
- at: function(/*===== index =====*/){
- // summary:
- // Returns a new NodeList comprised of items in this NodeList
- // at the given index or indices.
- //
- // index: Integer...
- // One or more 0-based indices of items in the current
- // NodeList. A negative index will start at the end of the
- // list and go backwards.
- //
- // example:
- // Shorten the list to the first, second, and third elements
- // | query("a").at(0, 1, 2).forEach(fn);
- //
- // example:
- // Retrieve the first and last elements of a unordered list:
- // | query("ul > li").at(0, -1).forEach(cb);
- //
- // example:
- // Do something for the first element only, but end() out back to
- // the original list and continue chaining:
- // | query("a").at(0).onclick(fn).end().forEach(function(n){
- // | console.log(n); // all anchors on the page.
- // | })
- var t = new this._NodeListCtor(0);
- forEach(arguments, function(i){
- if(i < 0){ i = this.length + i; }
- if(this[i]){ t.push(this[i]); }
- }, this);
- return t._stash(this); // dojo/NodeList
- }
- });
- function queryForEngine(engine, NodeList){
- var query = function(/*String*/ query, /*String|DOMNode?*/ root){
- // summary:
- // Returns nodes which match the given CSS selector, searching the
- // entire document by default but optionally taking a node to scope
- // the search by. Returns an instance of NodeList.
- if(typeof root == "string"){
- root = dom.byId(root);
- if(!root){
- return new NodeList([]);
- }
- }
- var results = typeof query == "string" ? engine(query, root) : query ? query.orphan ? query : [query] : [];
- if(results.orphan){
- // already wrapped
- return results;
- }
- return new NodeList(results);
- };
- query.matches = engine.match || function(node, selector, root){
- // summary:
- // Test to see if a node matches a selector
- return query.filter([node], selector, root).length > 0;
- };
- // the engine provides a filtering function, use it to for matching
- query.filter = engine.filter || function(nodes, selector, root){
- // summary:
- // Filters an array of nodes. Note that this does not guarantee to return a NodeList, just an array.
- return query(selector, root).filter(function(node){
- return array.indexOf(nodes, node) > -1;
- });
- };
- if(typeof engine != "function"){
- var search = engine.search;
- engine = function(selector, root){
- // Slick does it backwards (or everyone else does it backwards, probably the latter)
- return search(root || document, selector);
- };
- }
- return query;
- }
- var query = queryForEngine(defaultEngine, NodeList);
- /*=====
- query = function(selector, context){
- // summary:
- // This modules provides DOM querying functionality. The module export is a function
- // that can be used to query for DOM nodes by CSS selector and returns a NodeList
- // representing the matching nodes.
- // selector: String
- // A CSS selector to search for.
- // context: String|DomNode?
- // An optional context to limit the searching scope. Only nodes under `context` will be
- // scanned.
- // example:
- // add an onclick handler to every submit button in the document
- // which causes the form to be sent via Ajax instead:
- // | require(["dojo/query"], function(query){
- // | query("input[type='submit']").on("click", function(e){
- // | dojo.stopEvent(e); // prevent sending the form
- // | var btn = e.target;
- // | dojo.xhrPost({
- // | form: btn.form,
- // | load: function(data){
- // | // replace the form with the response
- // | var div = dojo.doc.createElement("div");
- // | dojo.place(div, btn.form, "after");
- // | div.innerHTML = data;
- // | dojo.style(btn.form, "display", "none");
- // | }
- // | });
- // | });
- // | });
- //
- // description:
- // dojo/query is responsible for loading the appropriate query engine and wrapping
- // its results with a `NodeList`. You can use dojo/query with a specific selector engine
- // by using it as a plugin. For example, if you installed the sizzle package, you could
- // use it as the selector engine with:
- // | require(["dojo/query!sizzle"], function(query){
- // | query("div")...
- //
- // The id after the ! can be a module id of the selector engine or one of the following values:
- //
- // - acme: This is the default engine used by Dojo base, and will ensure that the full
- // Acme engine is always loaded.
- //
- // - css2: If the browser has a native selector engine, this will be used, otherwise a
- // very minimal lightweight selector engine will be loaded that can do simple CSS2 selectors
- // (by #id, .class, tag, and [name=value] attributes, with standard child or descendant (>)
- // operators) and nothing more.
- //
- // - css2.1: If the browser has a native selector engine, this will be used, otherwise the
- // full Acme engine will be loaded.
- //
- // - css3: If the browser has a native selector engine with support for CSS3 pseudo
- // selectors (most modern browsers except IE8), this will be used, otherwise the
- // full Acme engine will be loaded.
- //
- // - Or the module id of a selector engine can be used to explicitly choose the selector engine
- //
- // For example, if you are using CSS3 pseudo selectors in module, you can specify that
- // you will need support them with:
- // | require(["dojo/query!css3"], function(query){
- // | query('#t > h3:nth-child(odd)')...
- //
- // You can also choose the selector engine/load configuration by setting the query-selector:
- // For example:
- // | <script data-dojo-config="query-selector:'css3'" src="dojo.js"></script>
- //
- return new NodeList(); // dojo/NodeList
- };
- =====*/
- // the query that is returned from this module is slightly different than dojo.query,
- // because dojo.query has to maintain backwards compatibility with returning a
- // true array which has performance problems. The query returned from the module
- // does not use true arrays, but rather inherits from Array, making it much faster to
- // instantiate.
- dojo.query = queryForEngine(defaultEngine, function(array){
- // call it without the new operator to invoke the back-compat behavior that returns a true array
- return NodeList(array); // dojo/NodeList
- });
- query.load = function(id, parentRequire, loaded){
- // summary:
- // can be used as AMD plugin to conditionally load new query engine
- // example:
- // | require(["dojo/query!custom"], function(qsa){
- // | // loaded selector/custom.js as engine
- // | qsa("#foobar").forEach(...);
- // | });
- loader.load(id, parentRequire, function(engine){
- loaded(queryForEngine(engine, NodeList));
- });
- };
- dojo._filterQueryResult = query._filterResult = function(nodes, selector, root){
- return new NodeList(query.filter(nodes, selector, root));
- };
- dojo.NodeList = query.NodeList = NodeList;
- return query;
- });
- },
- 'dojo/has':function(){
- define(["require", "module"], function(require, module){
- // module:
- // dojo/has
- // summary:
- // Defines the has.js API and several feature tests used by dojo.
- // description:
- // This module defines the has API as described by the project has.js with the following additional features:
- //
- // - the has test cache is exposed at has.cache.
- // - the method has.add includes a forth parameter that controls whether or not existing tests are replaced
- // - the loader's has cache may be optionally copied into this module's has cahce.
- //
- // This module adopted from https://github.com/phiggins42/has.js; thanks has.js team!
- // try to pull the has implementation from the loader; both the dojo loader and bdLoad provide one
- // if using a foreign loader, then the has cache may be initialized via the config object for this module
- // WARNING: if a foreign loader defines require.has to be something other than the has.js API, then this implementation fail
- var has = require.has || function(){};
- if(! 1 ){
- var
- isBrowser =
- // the most fundamental decision: are we in the browser?
- typeof window != "undefined" &&
- typeof location != "undefined" &&
- typeof document != "undefined" &&
- window.location == location && window.document == document,
- // has API variables
- global = this,
- doc = isBrowser && document,
- element = doc && doc.createElement("DiV"),
- cache = (module.config && module.config()) || {};
- has = function(name){
- // summary:
- // Return the current value of the named feature.
- //
- // name: String|Integer
- // The name (if a string) or identifier (if an integer) of the feature to test.
- //
- // description:
- // Returns the value of the feature named by name. The feature must have been
- // previously added to the cache by has.add.
- return typeof cache[name] == "function" ? (cache[name] = cache[name](global, doc, element)) : cache[name]; // Boolean
- };
- has.cache = cache;
- has.add = function(name, test, now, force){
- // summary:
- // Register a new feature test for some named feature.
- // name: String|Integer
- // The name (if a string) or identifier (if an integer) of the feature to test.
- // test: Function
- // A test function to register. If a function, queued for testing until actually
- // needed. The test function should return a boolean indicating
- // the presence of a feature or bug.
- // now: Boolean?
- // Optional. Omit if `test` is not a function. Provides a way to immediately
- // run the test and cache the result.
- // force: Boolean?
- // Optional. If the test already exists and force is truthy, then the existing
- // test will be replaced; otherwise, add does not replace an existing test (that
- // is, by default, the first test advice wins).
- // example:
- // A redundant test, testFn with immediate execution:
- // | has.add("javascript", function(){ return true; }, true);
- //
- // example:
- // Again with the redundantness. You can do this in your tests, but we should
- // not be doing this in any internal has.js tests
- // | has.add("javascript", true);
- //
- // example:
- // Three things are passed to the testFunction. `global`, `document`, and a generic element
- // from which to work your test should the need arise.
- // | has.add("bug-byid", function(g, d, el){
- // | // g == global, typically window, yadda yadda
- // | // d == document object
- // | // el == the generic element. a `has` element.
- // | return false; // fake test, byid-when-form-has-name-matching-an-id is slightly longer
- // | });
- (typeof cache[name]=="undefined" || force) && (cache[name]= test);
- return now && has(name);
- };
- // since we're operating under a loader that doesn't provide a has API, we must explicitly initialize
- // has as it would have otherwise been initialized by the dojo loader; use has.add to the builder
- // can optimize these away iff desired
- 1 || has.add("host-browser", isBrowser);
- 1 || has.add("dom", isBrowser);
- 1 || has.add("dojo-dom-ready-api", 1);
- 1 || has.add("dojo-sniff", 1);
- }
- if( 1 ){
- // Common application level tests
- has.add("dom-addeventlistener", !!document.addEventListener);
- has.add("touch", "ontouchstart" in document);
- // I don't know if any of these tests are really correct, just a rough guess
- has.add("device-width", screen.availWidth || innerWidth);
- // Tests for DOMNode.attributes[] behavior:
- // - dom-attributes-explicit - attributes[] only lists explicitly user specified attributes
- // - dom-attributes-specified-flag (IE8) - need to check attr.specified flag to skip attributes user didn't specify
- // - Otherwise, in IE6-7. attributes[] will list hundreds of values, so need to do outerHTML to get attrs instead.
- var form = document.createElement("form");
- has.add("dom-attributes-explicit", form.attributes.length == 0); // W3C
- has.add("dom-attributes-specified-flag", form.attributes.length > 0 && form.attributes.length < 40); // IE8
- }
- has.clearElement = function(element){
- // summary:
- // Deletes the contents of the element passed to test functions.
- element.innerHTML= "";
- return element;
- };
- has.normalize = function(id, toAbsMid){
- // summary:
- // Resolves id into a module id based on possibly-nested tenary expression that branches on has feature test value(s).
- //
- // toAbsMid: Function
- // Resolves a relative module id into an absolute module id
- var
- tokens = id.match(/[\?:]|[^:\?]*/g), i = 0,
- get = function(skip){
- var term = tokens[i++];
- if(term == ":"){
- // empty string module name, resolves to 0
- return 0;
- }else{
- // postfixed with a ? means it is a feature to branch on, the term is the name of the feature
- if(tokens[i++] == "?"){
- if(!skip && has(term)){
- // matched the feature, get the first value from the options
- return get();
- }else{
- // did not match, get the second value, passing over the first
- get(true);
- return get(skip);
- }
- }
- // a module
- return term || 0;
- }
- };
- id = get();
- return id && toAbsMid(id);
- };
- has.load = function(id, parentRequire, loaded){
- // summary:
- // Conditional loading of AMD modules based on a has feature test value.
- // id: String
- // Gives the resolved module id to load.
- // parentRequire: Function
- // The loader require function with respect to the module that contained the plugin resource in it's
- // dependency list.
- // loaded: Function
- // Callback to loader that consumes result of plugin demand.
- if(id){
- parentRequire([id], loaded);
- }else{
- loaded();
- }
- };
- return has;
- });
- },
- 'dojo/_base/loader':function(){
- define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"], function(dojo, has, require, thisModule, json, lang, array) {
- // module:
- // dojo/_base/loader
- // This module defines the v1.x synchronous loader API.
- // signal the loader in sync mode...
- //>>pure-amd
- if (! 1 ){
- console.error("cannot load the Dojo v1.x loader with a foreign loader");
- return 0;
- }
- 1 || has.add("dojo-fast-sync-require", 1);
- var makeErrorToken = function(id){
- return {src:thisModule.id, id:id};
- },
- slashName = function(name){
- return name.replace(/\./g, "/");
- },
- buildDetectRe = /\/\/>>built/,
- dojoRequireCallbacks = [],
- dojoRequireModuleStack = [],
- dojoRequirePlugin = function(mid, require, loaded){
- dojoRequireCallbacks.push(loaded);
- array.forEach(mid.split(","), function(mid){
- var module = getModule(mid, require.module);
- dojoRequireModuleStack.push(module);
- injectModule(module);
- });
- checkDojoRequirePlugin();
- },
- checkDojoRequirePlugin = ( 1 ?
- // This version of checkDojoRequirePlugin makes the observation that all dojoRequireCallbacks can be released
- // when all *non-dojo/require!, dojo/loadInit!* modules are either executed, not requested, or arrived. This is
- // the case since there are no more modules the loader is waiting for, therefore, dojo/require! must have
- // everything it needs on board.
- //
- // The potential weakness of this algorithm is that dojo/require will not execute callbacks until *all* dependency
- // trees are ready. It is possible that some trees may be ready earlier than others, and this extra wait is non-optimal.
- // Still, for big projects, this seems better than the original algorithm below that proved slow in some cases.
- // Note, however, the original algorithm had the potential to execute partial trees, but that potential was never enabled.
- // There are also other optimization available with the original algorithm that have not been explored.
- function(){
- var module, mid;
- for(mid in modules){
- module = modules[mid];
- if(module.noReqPluginCheck===undefined){
- // tag the module as either a loadInit or require plugin or not for future reference
- module.noReqPluginCheck = /loadInit\!/.test(mid) || /require\!/.test(mid) ? 1 : 0;
- }
- if(!module.executed && !module.noReqPluginCheck && module.injected==requested){
- return;
- }
- }
- guardCheckComplete(function(){
- var oldCallbacks = dojoRequireCallbacks;
- dojoRequireCallbacks = [];
- array.forEach(oldCallbacks, function(cb){cb(1);});
- });
- } : (function(){
- // Note: this is the original checkDojoRequirePlugin that is much slower than the algorithm above. However, we know it
- // works, so we leave it here in case the algorithm above fails in some corner case.
- //
- // checkDojoRequirePlugin inspects all of the modules demanded by a dojo/require!<module-list> dependency
- // to see if they have arrived. The loader does not release *any* of these modules to be instantiated
- // until *all* of these modules are on board, thereby preventing the evaluation of a module with dojo.require's
- // that reference modules that are not available.
- //
- // The algorithm works by traversing the dependency graphs (remember, there can be cycles so they are not trees)
- // of each module in the dojoRequireModuleStack array (which contains the list of modules demanded by dojo/require!).
- // The moment a single module is discovered that is missing, the algorithm gives up and indicates that not all
- // modules are on board. dojo/loadInit! and dojo/require! are ignored because there dependencies are inserted
- // directly in dojoRequireModuleStack. For example, if "your/module" module depends on "dojo/require!my/module", then
- // *both* "dojo/require!my/module" and "my/module" will be in dojoRequireModuleStack. Obviously, if "my/module"
- // is on board, then "dojo/require!my/module" is also satisfied, so the algorithm doesn't check for "dojo/require!my/module".
- //
- // Note: inserting a dojo/require!<some-module-list> dependency in the dojoRequireModuleStack achieves nothing
- // with the current algorithm; however, having such modules present makes it possible to optimize the algorithm
- //
- // Note: prior versions of this algorithm had an optimization that signaled loaded on dojo/require! dependencies
- // individually (rather than waiting for them all to be resolved). The implementation proved problematic with cycles
- // and plugins. However, it is possible to reattach that strategy in the future.
- // a set from module-id to {undefined | 1 | 0}, where...
- // undefined => the module has not been inspected
- // 0 => the module or at least one of its dependencies has not arrived
- // 1 => the module is a loadInit! or require! plugin resource, or is currently being traversed (therefore, assume
- // OK until proven otherwise), or has been completely traversed and all dependencies have arrived
- var touched,
- traverse = function(m){
- touched[m.mid] = 1;
- for(var t, module, deps = m.deps || [], i= 0; i<deps.length; i++){
- module = deps[i];
- if(!(t = touched[module.mid])){
- if(t===0 || !traverse(module)){
- touched[m.mid] = 0;
- return false;
- }
- }
- }
- return true;
- };
- return function(){
- // initialize the touched hash with easy-to-compute values that help short circuit recursive algorithm;
- // recall loadInit/require plugin modules are dependencies of modules in dojoRequireModuleStack...
- // which would cause a circular dependency chain that would never be resolved if checked here
- // notice all dependencies of any particular loadInit/require plugin module will already
- // be checked since those are pushed into dojoRequireModuleStack explicitly by the
- // plugin...so if a particular loadInitPlugin module's dependencies are not really
- // on board, that *will* be detected elsewhere in the traversal.
- var module, mid;
- touched = {};
- for(mid in modules){
- module = modules[mid];
- if(module.executed || module.noReqPluginCheck){
- touched[mid] = 1;
- }else{
- if(module.noReqPluginCheck!==0){
- // tag the module as either a loadInit or require plugin or not for future reference
- module.noReqPluginCheck = /loadInit\!/.test(mid) || /require\!/.test(mid) ? 1 : 0;
- }
- if(module.noReqPluginCheck){
- touched[mid] = 1;
- }else if(module.injected!==arrived){
- // not executed, has not arrived, and is not a loadInit or require plugin resource
- touched[mid] = 0;
- }// else, leave undefined and we'll traverse the dependencies
- }
- }
- for(var t, i = 0, end = dojoRequireModuleStack.length; i<end; i++){
- module = dojoRequireModuleStack[i];
- if(!(t = touched[module.mid])){
- if(t===0 || !traverse(module)){
- return;
- }
- }
- }
- guardCheckComplete(function(){
- var oldCallbacks = dojoRequireCallbacks;
- dojoRequireCallbacks = [];
- array.forEach(oldCallbacks, function(cb){cb(1);});
- });
- };
- })()),
- dojoLoadInitPlugin = function(mid, require, loaded){
- // mid names a module that defines a "dojo load init" bundle, an object with two properties:
- //
- // * names: a vector of module ids that give top-level names to define in the lexical scope of def
- // * def: a function that contains some some legacy loader API applications
- //
- // The point of def is to possibly cause some modules to be loaded (but not executed) by dojo/require! where the module
- // ids are possibly-determined at runtime. For example, here is dojox.gfx from v1.6 expressed as an AMD module using the dojo/loadInit
- // and dojo/require plugins.
- //
- // // dojox/gfx:
- //
- // define("*loadInit_12, {
- // names:["dojo", "dijit", "dojox"],
- // def: function(){
- // dojo.loadInit(function(){
- // var gfx = lang.getObject("dojox.gfx", true);
- //
- // //
- // // code required to set gfx properties ommitted...
- // //
- //
- // // now use the calculations to include the runtime-dependent module
- // dojo.require("dojox.gfx." + gfx.renderer);
- // });
- // }
- // });
- //
- // define(["dojo", "dojo/loadInit!" + id].concat("dojo/require!dojox/gfx/matric,dojox/gfx/_base"), function(dojo){
- // // when this AMD factory function is executed, the following modules are guaranteed downloaded but not executed:
- // // "dojox.gfx." + gfx.renderer
- // // dojox.gfx.matrix
- // // dojox.gfx._base
- // dojo.provide("dojo.gfx");
- // dojo.require("dojox.gfx.matrix");
- // dojo.require("dojox.gfx._base");
- // dojo.require("dojox.gfx." + gfx.renderer);
- // return lang.getObject("dojo.gfx");
- // });
- // })();
- //
- // The idea is to run the legacy loader API with global variables shadowed, which allows these variables to
- // be relocated. For example, dojox and dojo could be relocated to different names by giving a map and the code above will
- // execute properly (because the plugin below resolves the load init bundle.names module with respect to the module that demanded
- // the plugin resource).
- //
- // Note that the relocation is specified in the runtime configuration; relocated names need not be set at build-time.
- //
- // Warning: this is not the best way to express dojox.gfx as and AMD module. In fact, the module has been properly converted in
- // v1.7. However, this technique allows the builder to convert legacy modules into AMD modules and guarantee the codepath is the
- // same in the converted AMD module.
- require([mid], function(bundle){
- // notice how names is resolved with respect to the module that demanded the plugin resource
- require(bundle.names, function(){
- // bring the bundle names into scope
- for(var scopeText = "", args= [], i = 0; i<arguments.length; i++){
- scopeText+= "var " + bundle.names[i] + "= arguments[" + i + "]; ";
- args.push(arguments[i]);
- }
- eval(scopeText);
- var callingModule = require.module,
- // the list of modules that need to be downloaded but not executed before the callingModule can be executed
- requireList = [],
- // the list of i18n bundles that are xdomain; undefined if none
- i18nDeps,
- syncLoaderApi = {
- provide:function(moduleName){
- // mark modules that arrive consequent to multiple provides in this module as arrived since they can't be injected
- moduleName = slashName(moduleName);
- var providedModule = getModule(moduleName, callingModule);
- if(providedModule!==callingModule){
- setArrived(providedModule);
- }
- },
- require:function(moduleName, omitModuleCheck){
- moduleName = slashName(moduleName);
- omitModuleCheck && (getModule(moduleName, callingModule).result = nonmodule);
- requireList.push(moduleName);
- },
- requireLocalization:function(moduleName, bundleName, locale){
- // since we're going to need dojo/i8n, add it to i18nDeps if not already there
- if(!i18nDeps){
- // don't have to map since that will occur when the dependency is resolved
- i18nDeps = ["dojo/i18n"];
- }
- // figure out if the bundle is xdomain; if so, add it to the i18nDepsSet
- locale = (locale || dojo.locale).toLowerCase();
- moduleName = slashName(moduleName) + "/nls/" + (/root/i.test(locale) ? "" : locale + "/") + slashName(bundleName);
- if(getModule(moduleName, callingModule).isXd){
- // don't have to map since that will occur when the dependency is resolved
- i18nDeps.push("dojo/i18n!" + moduleName);
- }// else the bundle will be loaded synchronously when the module is evaluated
- },
- loadInit:function(f){
- f();
- }
- },
- hold = {},
- p;
- // hijack the correct dojo and apply bundle.def
- try{
- for(p in syncLoaderApi){
- hold[p] = dojo[p];
- dojo[p] = syncLoaderApi[p];
- }
- bundle.def.apply(null, args);
- }catch(e){
- signal("error", [makeErrorToken("failedDojoLoadInit"), e]);
- }finally{
- for(p in syncLoaderApi){
- dojo[p] = hold[p];
- }
- }
- if(i18nDeps){
- requireList = requireList.concat(i18nDeps);
- }
- if(requireList.length){
- dojoRequirePlugin(requireList.join(","), require, loaded);
- }else{
- loaded();
- }
- });
- });
- },
- extractApplication = function(
- text, // the text to search
- startSearch, // the position in text to start looking for the closing paren
- startApplication // the position in text where the function application expression starts
- ){
- // find end of the call by finding the matching end paren
- // Warning: as usual, this will fail in the presense of unmatched right parans contained in strings, regexs, or unremoved comments
- var parenRe = /\(|\)/g,
- matchCount = 1,
- match;
- parenRe.lastIndex = startSearch;
- while((match = parenRe.exec(text))){
- if(match[0] == ")"){
- matchCount -= 1;
- }else{
- matchCount += 1;
- }
- if(matchCount == 0){
- break;
- }
- }
- if(matchCount != 0){
- throw "unmatched paren around character " + parenRe.lastIndex + " in: " + text;
- }
- //Put the master matching string in the results.
- return [dojo.trim(text.substring(startApplication, parenRe.lastIndex))+";\n", parenRe.lastIndex];
- },
- // the following regex is taken from 1.6. It is a very poor technique to remove comments and
- // will fail in some cases; for example, consider the code...
- //
- // var message = "Category-1 */* Category-2";
- //
- // The regex that follows will see a /* comment and trash the code accordingly. In fact, there are all
- // kinds of cases like this with strings and regexs that will cause this design to fail miserably.
- //
- // Alternative regex designs exist that will result in less-likely failures, but will still fail in many cases.
- // The only solution guaranteed 100% correct is to parse the code and that seems overkill for this
- // backcompat/unbuilt-xdomain layer. In the end, since it's been this way for a while, we won't change it.
- // See the opening paragraphs of Chapter 7 or ECME-262 which describes the lexical abiguity further.
- removeCommentRe = /(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg,
- syncLoaderApiRe = /(^|\s)dojo\.(loadInit|require|provide|requireLocalization|requireIf|requireAfterIf|platformRequire)\s*\(/mg,
- amdLoaderApiRe = /(^|\s)(require|define)\s*\(/m,
- extractLegacyApiApplications = function(text, noCommentText){
- // scan the noCommentText for any legacy loader API applications. Copy such applications into result (this is
- // used by the builder). Move dojo.loadInit applications to loadInitApplications string. Copy all other applications
- // to otherApplications string. If no applications were found, return 0, signalling an AMD module. Otherwise, return
- // loadInitApplications + otherApplications. Fixup text by replacing
- //
- // dojo.loadInit(// etc...
- //
- // with
- //
- // \n 0 && dojo.loadInit(// etc...
- //
- // Which results in the dojo.loadInit from *not* being applied. This design goes a long way towards protecting the
- // code from an over-agressive removeCommentRe. However...
- //
- // WARNING: the removeCommentRe will cause an error if a detected comment removes all or part of a legacy-loader application
- // that is not in a comment.
- var match, startSearch, startApplication, application,
- loadInitApplications = [],
- otherApplications = [],
- allApplications = [];
- // noCommentText may be provided by a build app with comments extracted by a better method than regex (hopefully)
- noCommentText = noCommentText || text.replace(removeCommentRe, function(match){
- // remove iff the detected comment has text that looks like a sync loader API application; this helps by
- // removing as little as possible, minimizing the changes the janky regex will kill the module
- syncLoaderApiRe.lastIndex = amdLoaderApiRe.lastIndex = 0;
- return (syncLoaderApiRe.test(match) || amdLoaderApiRe.test(match)) ? "" : match;
- });
- // find and extract all dojo.loadInit applications
- while((match = syncLoaderApiRe.exec(noCommentText))){
- startSearch = syncLoaderApiRe.lastIndex;
- startApplication = startSearch - match[0].length;
- application = extractApplication(noCommentText, startSearch, startApplication);
- if(match[2]=="loadInit"){
- loadInitApplications.push(application[0]);
- }else{
- otherApplications.push(application[0]);
- }
- syncLoaderApiRe.lastIndex = application[1];
- }
- allApplications = loadInitApplications.concat(otherApplications);
- if(allApplications.length || !amdLoaderApiRe.test(noCommentText)){
- // either there were some legacy loader API applications or there were no AMD API applications
- return [text.replace(/(^|\s)dojo\.loadInit\s*\(/g, "\n0 && dojo.loadInit("), allApplications.join(""), allApplications];
- }else{
- // legacy loader API *was not* detected and AMD API *was* detected; therefore, assume it's an AMD module
- return 0;
- }
- },
- transformToAmd = function(module, text){
- // This is roughly the equivalent of dojo._xdCreateResource in 1.6-; however, it expresses a v1.6- dojo
- // module in terms of AMD define instead of creating the dojo proprietary xdomain module expression.
- // The module could have originated from several sources:
- //
- // * amd require() a module, e.g., require(["my/module"])
- // * amd require() a nonmodule, e.g., require(["my/resource.js"')
- // * amd define() deps vector (always a module)
- // * dojo.require() a module, e.g. dojo.require("my.module")
- // * dojo.require() a nonmodule, e.g., dojo.require("my.module", true)
- // * dojo.requireIf/requireAfterIf/platformRequire a module
- //
- // The module is scanned for legacy loader API applications; if none are found, then assume the module is an
- // AMD module and return 0. Otherwise, a synthetic dojo/loadInit plugin resource is created and the module text
- // is rewritten as an AMD module with the single dependency of this synthetic resource. When the dojo/loadInit
- // plugin loaded the synthetic resource, it will cause all dojo.loadInit's to be executed, find all dojo.require's
- // (either directly consequent to dojo.require or indirectly consequent to dojo.require[After]If or
- // dojo.platformRequire, and finally cause loading of all dojo.required modules with the dojo/require plugin. Thus,
- // when the dojo/loadInit plugin reports it has been loaded, all modules required by the given module are guaranteed
- // loaded (but not executed). This then allows the module to execute it's code path without interupts, thereby
- // following the synchronous code path.
- //
- // Notice that this function behaves the same whether or not it happens to be in a mapped dojo/loader module.
- var extractResult, id, names = [], namesAsStrings = [];
- if(buildDetectRe.test(text) || !(extractResult = extractLegacyApiApplications(text))){
- // buildDetectRe.test(text) => a built module, always AMD
- // extractResult==0 => no sync API
- return 0;
- }
- // manufacture a synthetic module id that can never be a real mdule id (just like require does)
- id = module.mid + "-*loadInit";
- // construct the dojo/loadInit names vector which causes any relocated names to be defined as lexical variables under their not-relocated name
- // the dojo/loadInit plugin assumes the first name in names is "dojo"
- for(var p in getModule("dojo", module).result.scopeMap){
- names.push(p);
- namesAsStrings.push('"' + p + '"');
- }
- // rewrite the module as a synthetic dojo/loadInit plugin resource + the module expressed as an AMD module that depends on this synthetic resource
- // don't have to map dojo/init since that will occur when the dependency is resolved
- return "// xdomain rewrite of " + module.mid + "\n" +
- "define('" + id + "',{\n" +
- "\tnames:" + dojo.toJson(names) + ",\n" +
- "\tdef:function(" + names.join(",") + "){" + extractResult[1] + "}" +
- "});\n\n" +
- "define(" + dojo.toJson(names.concat(["dojo/loadInit!"+id])) + ", function(" + names.join(",") + "){\n" + extractResult[0] + "});";
- },
- loaderVars = require.initSyncLoader(dojoRequirePlugin, checkDojoRequirePlugin, transformToAmd),
- sync =
- loaderVars.sync,
- requested =
- loaderVars.requested,
- arrived =
- loaderVars.arrived,
- nonmodule =
- loaderVars.nonmodule,
- executing =
- loaderVars.executing,
- executed =
- loaderVars.executed,
- syncExecStack =
- loaderVars.syncExecStack,
- modules =
- loaderVars.modules,
- execQ =
- loaderVars.execQ,
- getModule =
- loaderVars.getModule,
- injectModule =
- loaderVars.injectModule,
- setArrived =
- loaderVars.setArrived,
- signal =
- loaderVars.signal,
- finishExec =
- loaderVars.finishExec,
- execModule =
- loaderVars.execModule,
- getLegacyMode =
- loaderVars.getLegacyMode,
- guardCheckComplete =
- loaderVars.guardCheckComplete;
- // there is exactly one dojoRequirePlugin among possibly-many dojo/_base/loader's (owing to mapping)
- dojoRequirePlugin = loaderVars.dojoRequirePlugin;
- dojo.provide = function(mid){
- var executingModule = syncExecStack[0],
- module = lang.mixin(getModule(slashName(mid), require.module), {
- executed:executing,
- result:lang.getObject(mid, true)
- });
- setArrived(module);
- if(executingModule){
- (executingModule.provides || (executingModule.provides = [])).push(function(){
- module.result = lang.getObject(mid);
- delete module.provides;
- module.executed!==executed && finishExec(module);
- });
- }// else dojo.provide called not consequent to loading; therefore, give up trying to publish module value to loader namespace
- return module.result;
- };
- has.add("config-publishRequireResult", 1, 0, 0);
- dojo.require = function(moduleName, omitModuleCheck) {
- // summary:
- // loads a Javascript module from the appropriate URI
- //
- // moduleName: String
- // module name to load, using periods for separators,
- // e.g. "dojo.date.locale". Module paths are de-referenced by dojo's
- // internal mapping of locations to names and are disambiguated by
- // longest prefix. See `dojo.registerModulePath()` for details on
- // registering new modules.
- //
- // omitModuleCheck: Boolean?
- // if `true`, omitModuleCheck skips the step of ensuring that the
- // loaded file actually defines the symbol it is referenced by.
- // For example if it called as `dojo.require("a.b.c")` and the
- // file located at `a/b/c.js` does not define an object `a.b.c`,
- // and exception will be throws whereas no exception is raised
- // when called as `dojo.require("a.b.c", true)`
- //
- // description:
- // Modules are loaded via dojo.require by using one of two loaders: the normal loader
- // and the xdomain loader. The xdomain loader is used when dojo was built with a
- // custom build that specified loader=xdomain and the module lives on a modulePath
- // that is a whole URL, with protocol and a domain. The versions of Dojo that are on
- // the Google and AOL CDNs use the xdomain loader.
- //
- // If the module is loaded via the xdomain loader, it is an asynchronous load, since
- // the module is added via a dynamically created script tag. This
- // means that dojo.require() can return before the module has loaded. However, this
- // should only happen in the case where you do dojo.require calls in the top-level
- // HTML page, or if you purposely avoid the loader checking for dojo.require
- // dependencies in your module by using a syntax like dojo["require"] to load the module.
- //
- // Sometimes it is useful to not have the loader detect the dojo.require calls in the
- // module so that you can dynamically load the modules as a result of an action on the
- // page, instead of right at module load time.
- //
- // Also, for script blocks in an HTML page, the loader does not pre-process them, so
- // it does not know to download the modules before the dojo.require calls occur.
- //
- // So, in those two cases, when you want on-the-fly module loading or for script blocks
- // in the HTML page, special care must be taken if the dojo.required code is loaded
- // asynchronously. To make sure you can execute code that depends on the dojo.required
- // modules, be sure to add the code that depends on the modules in a dojo.addOnLoad()
- // callback. dojo.addOnLoad waits for all outstanding modules to finish loading before
- // executing.
- //
- // This type of syntax works with both xdomain and normal loaders, so it is good
- // practice to always use this idiom for on-the-fly code loading and in HTML script
- // blocks. If at some point you change loaders and where the code is loaded from,
- // it will all still work.
- //
- // More on how dojo.require
- // `dojo.require("A.B")` first checks to see if symbol A.B is
- // defined. If it is, it is simply returned (nothing to do).
- //
- // If it is not defined, it will look for `A/B.js` in the script root
- // directory.
- //
- // `dojo.require` throws an exception if it cannot find a file
- // to load, or if the symbol `A.B` is not defined after loading.
- //
- // It returns the object `A.B`, but note the caveats above about on-the-fly loading and
- // HTML script blocks when the xdomain loader is loading a module.
- //
- // `dojo.require()` does nothing about importing symbols into
- // the current namespace. It is presumed that the caller will
- // take care of that.
- //
- // example:
- // To use dojo.require in conjunction with dojo.ready:
- //
- // | dojo.require("foo");
- // | dojo.require("bar");
- // | dojo.addOnLoad(function(){
- // | //you can now safely do something with foo and bar
- // | });
- //
- // example:
- // For example, to import all symbols into a local block, you might write:
- //
- // | with (dojo.require("A.B")) {
- // | ...
- // | }
- //
- // And to import just the leaf symbol to a local variable:
- //
- // | var B = dojo.require("A.B");
- // | ...
- //
- // returns:
- // the required namespace object
- function doRequire(mid, omitModuleCheck){
- var module = getModule(slashName(mid), require.module);
- if(syncExecStack.length && syncExecStack[0].finish){
- // switched to async loading in the middle of evaluating a legacy module; stop
- // applying dojo.require so the remaining dojo.requires are applied in order
- syncExecStack[0].finish.push(mid);
- return undefined;
- }
- // recall module.executed has values {0, executing, executed}; therefore, truthy indicates executing or executed
- if(module.executed){
- return module.result;
- }
- omitModuleCheck && (module.result = nonmodule);
- // rcg...why here and in two lines??
- var currentMode = getLegacyMode();
- // recall, in sync mode to inject is to *eval* the module text
- // if the module is a legacy module, this is the same as executing
- // but if the module is an AMD module, this means defining, not executing
- injectModule(module);
- // the inject may have changed the mode
- currentMode = getLegacyMode();
- // in sync mode to dojo.require is to execute
- if(module.executed!==executed && module.injected===arrived){
- // the module was already here before injectModule was called probably finishing up a xdomain
- // load, but maybe a module given to the loader directly rather than having the loader retrieve it
- loaderVars.guardCheckComplete(function(){
- execModule(module);
- });
- }
- if(module.executed){
- return module.result;
- }
- if(currentMode==sync){
- // the only way to get here is in sync mode and dojo.required a module that
- // * was loaded async in the injectModule application a few lines up
- // * was an AMD module that had deps that are being loaded async and therefore couldn't execute
- if(module.cjs){
- // the module was an AMD module; unshift, not push, which causes the current traversal to be reattempted from the top
- execQ.unshift(module);
- }else{
- // the module was a legacy module
- syncExecStack.length && (syncExecStack[0].finish= [mid]);
- }
- }else{
- // the loader wasn't in sync mode on entry; probably async mode; therefore, no expectation of getting
- // the module value synchronously; make sure it gets executed though
- execQ.push(module);
- }
- return undefined;
- }
- var result = doRequire(moduleName, omitModuleCheck);
- if(has("config-publishRequireResult") && !lang.exists(moduleName) && result!==undefined){
- lang.setObject(moduleName, result);
- }
- return result;
- };
- dojo.loadInit = function(f) {
- f();
- };
- dojo.registerModulePath = function(/*String*/moduleName, /*String*/prefix){
- // summary:
- // Maps a module name to a path
- // description:
- // An unregistered module is given the default path of ../[module],
- // relative to Dojo root. For example, module acme is mapped to
- // ../acme. If you want to use a different module name, use
- // dojo.registerModulePath.
- // example:
- // If your dojo.js is located at this location in the web root:
- // | /myapp/js/dojo/dojo/dojo.js
- // and your modules are located at:
- // | /myapp/js/foo/bar.js
- // | /myapp/js/foo/baz.js
- // | /myapp/js/foo/thud/xyzzy.js
- // Your application can tell Dojo to locate the "foo" namespace by calling:
- // | dojo.registerModulePath("foo", "../../foo");
- // At which point you can then use dojo.require() to load the
- // modules (assuming they provide() the same things which are
- // required). The full code might be:
- // | <script type="text/javascript"
- // | src="/myapp/js/dojo/dojo/dojo.js"></script>
- // | <script type="text/javascript">
- // | dojo.registerModulePath("foo", "../../foo");
- // | dojo.require("foo.bar");
- // | dojo.require("foo.baz");
- // | dojo.require("foo.thud.xyzzy");
- // | </script>
- var paths = {};
- paths[moduleName.replace(/\./g, "/")] = prefix;
- require({paths:paths});
- };
- dojo.platformRequire = function(/*Object*/modMap){
- // summary:
- // require one or more modules based on which host environment
- // Dojo is currently operating in
- // description:
- // This method takes a "map" of arrays which one can use to
- // optionally load dojo modules. The map is indexed by the
- // possible dojo.name_ values, with two additional values:
- // "default" and "common". The items in the "default" array will
- // be loaded if none of the other items have been choosen based on
- // dojo.name_, set by your host environment. The items in the
- // "common" array will *always* be loaded, regardless of which
- // list is chosen.
- // example:
- // | dojo.platformRequire({
- // | browser: [
- // | "foo.sample", // simple module
- // | "foo.test",
- // | ["foo.bar.baz", true] // skip object check in _loadModule (dojo.require)
- // | ],
- // | default: [ "foo.sample._base" ],
- // | common: [ "important.module.common" ]
- // | });
- var result = (modMap.common || []).concat(modMap[dojo._name] || modMap["default"] || []),
- temp;
- while(result.length){
- if(lang.isArray(temp = result.shift())){
- dojo.require.apply(dojo, temp);
- }else{
- dojo.require(temp);
- }
- }
- };
- dojo.requireIf = dojo.requireAfterIf = function(/*Boolean*/ condition, /*String*/ moduleName, /*Boolean?*/omitModuleCheck){
- // summary:
- // If the condition is true then call `dojo.require()` for the specified
- // resource
- //
- // example:
- // | dojo.requireIf(dojo.isBrowser, "my.special.Module");
- if(condition){
- dojo.require(moduleName, omitModuleCheck);
- }
- };
- dojo.requireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale){
- require(["../i18n"], function(i18n){
- i18n.getLocalization(moduleName, bundleName, locale);
- });
- };
- return {
- // summary:
- // This module defines the v1.x synchronous loader API.
- extractLegacyApiApplications:extractLegacyApiApplications,
- require:dojoRequirePlugin,
- loadInit:dojoLoadInitPlugin
- };
- });
- },
- 'dojo/json':function(){
- define(["./has"], function(has){
- "use strict";
- var hasJSON = typeof JSON != "undefined";
- has.add("json-parse", hasJSON); // all the parsers work fine
- // Firefox 3.5/Gecko 1.9 fails to use replacer in stringify properly https://bugzilla.mozilla.org/show_bug.cgi?id=509184
- has.add("json-stringify", hasJSON && JSON.stringify({a:0}, function(k,v){return v||1;}) == '{"a":1}');
- /*=====
- return {
- // summary:
- // Functions to parse and serialize JSON
- parse: function(str, strict){
- // summary:
- // Parses a [JSON](http://json.org) string to return a JavaScript object.
- // description:
- // This function follows [native JSON API](https://developer.mozilla.org/en/JSON)
- // Throws for invalid JSON strings. This delegates to eval() if native JSON
- // support is not available. By default this will evaluate any valid JS expression.
- // With the strict parameter set to true, the parser will ensure that only
- // valid JSON strings are parsed (otherwise throwing an error). Without the strict
- // parameter, the content passed to this method must come
- // from a trusted source.
- // str:
- // a string literal of a JSON item, for instance:
- // `'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'`
- // strict:
- // When set to true, this will ensure that only valid, secure JSON is ever parsed.
- // Make sure this is set to true for untrusted content. Note that on browsers/engines
- // without native JSON support, setting this to true will run slower.
- },
- stringify: function(value, replacer, spacer){
- // summary:
- // Returns a [JSON](http://json.org) serialization of an object.
- // description:
- // Returns a [JSON](http://json.org) serialization of an object.
- // This function follows [native JSON API](https://developer.mozilla.org/en/JSON)
- // Note that this doesn't check for infinite recursion, so don't do that!
- // value:
- // A value to be serialized.
- // replacer:
- // A replacer function that is called for each value and can return a replacement
- // spacer:
- // A spacer string to be used for pretty printing of JSON
- // example:
- // simple serialization of a trivial object
- // | define(["dojo/json"], function(JSON){
- // | var jsonStr = JSON.stringify({ howdy: "stranger!", isStrange: true });
- // | doh.is('{"howdy":"stranger!","isStrange":true}', jsonStr);
- }
- };
- =====*/
- if(has("json-stringify")){
- return JSON;
- }else{
- var escapeString = function(/*String*/str){
- // summary:
- // Adds escape sequences for non-visual characters, double quote and
- // backslash and surrounds with double quotes to form a valid string
- // literal.
- return ('"' + str.replace(/(["\\])/g, '\\$1') + '"').
- replace(/[\f]/g, "\\f").replace(/[\b]/g, "\\b").replace(/[\n]/g, "\\n").
- replace(/[\t]/g, "\\t").replace(/[\r]/g, "\\r"); // string
- };
- return {
- parse: has("json-parse") ? JSON.parse : function(str, strict){
- if(strict && !/^([\s\[\{]*(?:"(?:\\.|[^"])+"|-?\d[\d\.]*(?:[Ee][+-]?\d+)?|null|true|false|)[\s\]\}]*(?:,|:|$))+$/.test(str)){
- throw new SyntaxError("Invalid characters in JSON");
- }
- return eval('(' + str + ')');
- },
- stringify: function(value, replacer, spacer){
- var undef;
- if(typeof replacer == "string"){
- spacer = replacer;
- replacer = null;
- }
- function stringify(it, indent, key){
- if(replacer){
- it = replacer(key, it);
- }
- var val, objtype = typeof it;
- if(objtype == "number"){
- return isFinite(it) ? it + "" : "null";
- }
- if(objtype == "boolean"){
- return it + "";
- }
- if(it === null){
- return "null";
- }
- if(typeof it == "string"){
- return escapeString(it);
- }
- if(objtype == "function" || objtype == "undefined"){
- return undef; // undefined
- }
- // short-circuit for objects that support "json" serialization
- // if they return "self" then just pass-through...
- if(typeof it.toJSON == "function"){
- return stringify(it.toJSON(key), indent, key);
- }
- if(it instanceof Date){
- return '"{FullYear}-{Month+}-{Date}T{Hours}:{Minutes}:{Seconds}Z"'.replace(/\{(\w+)(\+)?\}/g, function(t, prop, plus){
- var num = it["getUTC" + prop]() + (plus ? 1 : 0);
- return num < 10 ? "0" + num : num;
- });
- }
- if(it.valueOf() !== it){
- // primitive wrapper, try again unwrapped:
- return stringify(it.valueOf(), indent, key);
- }
- var nextIndent= spacer ? (indent + spacer) : "";
- /* we used to test for DOM nodes and throw, but FF serializes them as {}, so cross-browser consistency is probably not efficiently attainable */
-
- var sep = spacer ? " " : "";
- var newLine = spacer ? "\n" : "";
-
- // array
- if(it instanceof Array){
- var itl = it.length, res = [];
- for(key = 0; key < itl; key++){
- var obj = it[key];
- val = stringify(obj, nextIndent, key);
- if(typeof val != "string"){
- val = "null";
- }
- res.push(newLine + nextIndent + val);
- }
- return "[" + res.join(",") + newLine + indent + "]";
- }
- // generic object code path
- var output = [];
- for(key in it){
- var keyStr;
- if(it.hasOwnProperty(key)){
- if(typeof key == "number"){
- keyStr = '"' + key + '"';
- }else if(typeof key == "string"){
- keyStr = escapeString(key);
- }else{
- // skip non-string or number keys
- continue;
- }
- val = stringify(it[key], nextIndent, key);
- if(typeof val != "string"){
- // skip non-serializable values
- continue;
- }
- // At this point, the most non-IE browsers don't get in this branch
- // (they have native JSON), so push is definitely the way to
- output.push(newLine + nextIndent + keyStr + ":" + sep + val);
- }
- }
- return "{" + output.join(",") + newLine + indent + "}"; // String
- }
- return stringify(value, "", "");
- }
- };
- }
- });
- },
- 'dojo/_base/declare':function(){
- define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
- // module:
- // dojo/_base/declare
- var mix = lang.mixin, op = Object.prototype, opts = op.toString,
- xtor = new Function, counter = 0, cname = "constructor";
- function err(msg, cls){ throw new Error("declare" + (cls ? " " + cls : "") + ": " + msg); }
- // C3 Method Resolution Order (see http://www.python.org/download/releases/2.3/mro/)
- function c3mro(bases, className){
- var result = [], roots = [{cls: 0, refs: []}], nameMap = {}, clsCount = 1,
- l = bases.length, i = 0, j, lin, base, top, proto, rec, name, refs;
- // build a list of bases naming them if needed
- for(; i < l; ++i){
- base = bases[i];
- if(!base){
- err("mixin #" + i + " is unknown. Did you use dojo.require to pull it in?", className);
- }else if(opts.call(base) != "[object Function]"){
- err("mixin #" + i + " is not a callable constructor.", className);
- }
- lin = base._meta ? base._meta.bases : [base];
- top = 0;
- // add bases to the name map
- for(j = lin.length - 1; j >= 0; --j){
- proto = lin[j].prototype;
- if(!proto.hasOwnProperty("declaredClass")){
- proto.declaredClass = "uniqName_" + (counter++);
- }
- name = proto.declaredClass;
- if(!nameMap.hasOwnProperty(name)){
- nameMap[name] = {count: 0, refs: [], cls: lin[j]};
- ++clsCount;
- }
- rec = nameMap[name];
- if(top && top !== rec){
- rec.refs.push(top);
- ++top.count;
- }
- top = rec;
- }
- ++top.count;
- roots[0].refs.push(top);
- }
- // remove classes without external references recursively
- while(roots.length){
- top = roots.pop();
- result.push(top.cls);
- --clsCount;
- // optimization: follow a single-linked chain
- while(refs = top.refs, refs.length == 1){
- top = refs[0];
- if(!top || --top.count){
- // branch or end of chain => do not end to roots
- top = 0;
- break;
- }
- result.push(top.cls);
- --clsCount;
- }
- if(top){
- // branch
- for(i = 0, l = refs.length; i < l; ++i){
- top = refs[i];
- if(!--top.count){
- roots.push(top);
- }
- }
- }
- }
- if(clsCount){
- err("can't build consistent linearization", className);
- }
- // calculate the superclass offset
- base = bases[0];
- result[0] = base ?
- base._meta && base === result[result.length - base._meta.bases.length] ?
- base._meta.bases.length : 1 : 0;
- return result;
- }
- function inherited(args, a, f){
- var name, chains, bases, caller, meta, base, proto, opf, pos,
- cache = this._inherited = this._inherited || {};
- // crack arguments
- if(typeof args == "string"){
- name = args;
- args = a;
- a = f;
- }
- f = 0;
- caller = args.callee;
- name = name || caller.nom;
- if(!name){
- err("can't deduce a name to call inherited()", this.declaredClass);
- }
- meta = this.constructor._meta;
- bases = meta.bases;
- pos = cache.p;
- if(name != cname){
- // method
- if(cache.c !== caller){
- // cache bust
- pos = 0;
- base = bases[0];
- meta = base._meta;
- if(meta.hidden[name] !== caller){
- // error detection
- chains = meta.chains;
- if(chains && typeof chains[name] == "string"){
- err("calling chained method with inherited: " + name, this.declaredClass);
- }
- // find caller
- do{
- meta = base._meta;
- proto = base.prototype;
- if(meta && (proto[name] === caller && proto.hasOwnProperty(name) || meta.hidden[name] === caller)){
- break;
- }
- }while(base = bases[++pos]); // intentional assignment
- pos = base ? pos : -1;
- }
- }
- // find next
- base = bases[++pos];
- if(base){
- proto = base.prototype;
- if(base._meta && proto.hasOwnProperty(name)){
- f = proto[name];
- }else{
- opf = op[name];
- do{
- proto = base.prototype;
- f = proto[name];
- if(f && (base._meta ? proto.hasOwnProperty(name) : f !== opf)){
- break;
- }
- }while(base = bases[++pos]); // intentional assignment
- }
- }
- f = base && f || op[name];
- }else{
- // constructor
- if(cache.c !== caller){
- // cache bust
- pos = 0;
- meta = bases[0]._meta;
- if(meta && meta.ctor !== caller){
- // error detection
- chains = meta.chains;
- if(!chains || chains.constructor !== "manual"){
- err("calling chained constructor with inherited", this.declaredClass);
- }
- // find caller
- while(base = bases[++pos]){ // intentional assignment
- meta = base._meta;
- if(meta && meta.ctor === caller){
- break;
- }
- }
- pos = base ? pos : -1;
- }
- }
- // find next
- while(base = bases[++pos]){ // intentional assignment
- meta = base._meta;
- f = meta ? meta.ctor : base;
- if(f){
- break;
- }
- }
- f = base && f;
- }
- // cache the found super method
- cache.c = f;
- cache.p = pos;
- // now we have the result
- if(f){
- return a === true ? f : f.apply(this, a || args);
- }
- // intentionally no return if a super method was not found
- }
- function getInherited(name, args){
- if(typeof name == "string"){
- return this.__inherited(name, args, true);
- }
- return this.__inherited(name, true);
- }
- function inherited__debug(args, a1, a2){
- var f = this.getInherited(args, a1);
- if(f){ return f.apply(this, a2 || a1 || args); }
- // intentionally no return if a super method was not found
- }
- var inheritedImpl = dojo.config.isDebug ? inherited__debug : inherited;
- // emulation of "instanceof"
- function isInstanceOf(cls){
- var bases = this.constructor._meta.bases;
- for(var i = 0, l = bases.length; i < l; ++i){
- if(bases[i] === cls){
- return true;
- }
- }
- return this instanceof cls;
- }
- function mixOwn(target, source){
- // add props adding metadata for incoming functions skipping a constructor
- for(var name in source){
- if(name != cname && source.hasOwnProperty(name)){
- target[name] = source[name];
- }
- }
- if(has("bug-for-in-skips-shadowed")){
- for(var extraNames= lang._extraNames, i= extraNames.length; i;){
- name = extraNames[--i];
- if(name != cname && source.hasOwnProperty(name)){
- target[name] = source[name];
- }
- }
- }
- }
- // implementation of safe mixin function
- function safeMixin(target, source){
- // summary:
- // Mix in properties skipping a constructor and decorating functions
- // like it is done by declare().
- // target: Object
- // Target object to accept new properties.
- // source: Object
- // Source object for new properties.
- // description:
- // This function is used to mix in properties like lang.mixin does,
- // but it skips a constructor property and decorates functions like
- // declare() does.
- //
- // It is meant to be used with classes and objects produced with
- // declare. Functions mixed in with dojo.safeMixin can use
- // this.inherited() like normal methods.
- //
- // This function is used to implement extend() method of a constructor
- // produced with declare().
- //
- // example:
- // | var A = declare(null, {
- // | m1: function(){
- // | console.log("A.m1");
- // | },
- // | m2: function(){
- // | console.log("A.m2");
- // | }
- // | });
- // | var B = declare(A, {
- // | m1: function(){
- // | this.inherited(arguments);
- // | console.log("B.m1");
- // | }
- // | });
- // | B.extend({
- // | m2: function(){
- // | this.inherited(arguments);
- // | console.log("B.m2");
- // | }
- // | });
- // | var x = new B();
- // | dojo.safeMixin(x, {
- // | m1: function(){
- // | this.inherited(arguments);
- // | console.log("X.m1");
- // | },
- // | m2: function(){
- // | this.inherited(arguments);
- // | console.log("X.m2");
- // | }
- // | });
- // | x.m2();
- // | // prints:
- // | // A.m1
- // | // B.m1
- // | // X.m1
- var name, t;
- // add props adding metadata for incoming functions skipping a constructor
- for(name in source){
- t = source[name];
- if((t !== op[name] || !(name in op)) && name != cname){
- if(opts.call(t) == "[object Function]"){
- // non-trivial function method => attach its name
- t.nom = name;
- }
- target[name] = t;
- }
- }
- if(has("bug-for-in-skips-shadowed")){
- for(var extraNames= lang._extraNames, i= extraNames.length; i;){
- name = extraNames[--i];
- t = source[name];
- if((t !== op[name] || !(name in op)) && name != cname){
- if(opts.call(t) == "[object Function]"){
- // non-trivial function method => attach its name
- t.nom = name;
- }
- target[name] = t;
- }
- }
- }
- return target;
- }
- function extend(source){
- declare.safeMixin(this.prototype, source);
- return this;
- }
- function createSubclass(mixins){
- return declare([this].concat(mixins));
- }
- // chained constructor compatible with the legacy declare()
- function chainedConstructor(bases, ctorSpecial){
- return function(){
- var a = arguments, args = a, a0 = a[0], f, i, m,
- l = bases.length, preArgs;
- if(!(this instanceof a.callee)){
- // not called via new, so force it
- return applyNew(a);
- }
- //this._inherited = {};
- // perform the shaman's rituals of the original declare()
- // 1) call two types of the preamble
- if(ctorSpecial && (a0 && a0.preamble || this.preamble)){
- // full blown ritual
- preArgs = new Array(bases.length);
- // prepare parameters
- preArgs[0] = a;
- for(i = 0;;){
- // process the preamble of the 1st argument
- a0 = a[0];
- if(a0){
- f = a0.preamble;
- if(f){
- a = f.apply(this, a) || a;
- }
- }
- // process the preamble of this class
- f = bases[i].prototype;
- f = f.hasOwnProperty("preamble") && f.preamble;
- if(f){
- a = f.apply(this, a) || a;
- }
- // one peculiarity of the preamble:
- // it is called if it is not needed,
- // e.g., there is no constructor to call
- // let's watch for the last constructor
- // (see ticket #9795)
- if(++i == l){
- break;
- }
- preArgs[i] = a;
- }
- }
- // 2) call all non-trivial constructors using prepared arguments
- for(i = l - 1; i >= 0; --i){
- f = bases[i];
- m = f._meta;
- f = m ? m.ctor : f;
- if(f){
- f.apply(this, preArgs ? preArgs[i] : a);
- }
- }
- // 3) continue the original ritual: call the postscript
- f = this.postscript;
- if(f){
- f.apply(this, args);
- }
- };
- }
- // chained constructor compatible with the legacy declare()
- function singleConstructor(ctor, ctorSpecial){
- return function(){
- var a = arguments, t = a, a0 = a[0], f;
- if(!(this instanceof a.callee)){
- // not called via new, so force it
- return applyNew(a);
- }
- //this._inherited = {};
- // perform the shaman's rituals of the original declare()
- // 1) call two types of the preamble
- if(ctorSpecial){
- // full blown ritual
- if(a0){
- // process the preamble of the 1st argument
- f = a0.preamble;
- if(f){
- t = f.apply(this, t) || t;
- }
- }
- f = this.preamble;
- if(f){
- // process the preamble of this class
- f.apply(this, t);
- // one peculiarity of the preamble:
- // it is called even if it is not needed,
- // e.g., there is no constructor to call
- // let's watch for the last constructor
- // (see ticket #9795)
- }
- }
- // 2) call a constructor
- if(ctor){
- ctor.apply(this, a);
- }
- // 3) continue the original ritual: call the postscript
- f = this.postscript;
- if(f){
- f.apply(this, a);
- }
- };
- }
- // plain vanilla constructor (can use inherited() to call its base constructor)
- function simpleConstructor(bases){
- return function(){
- var a = arguments, i = 0, f, m;
- if(!(this instanceof a.callee)){
- // not called via new, so force it
- return applyNew(a);
- }
- //this._inherited = {};
- // perform the shaman's rituals of the original declare()
- // 1) do not call the preamble
- // 2) call the top constructor (it can use this.inherited())
- for(; f = bases[i]; ++i){ // intentional assignment
- m = f._meta;
- f = m ? m.ctor : f;
- if(f){
- f.apply(this, a);
- break;
- }
- }
- // 3) call the postscript
- f = this.postscript;
- if(f){
- f.apply(this, a);
- }
- };
- }
- function chain(name, bases, reversed){
- return function(){
- var b, m, f, i = 0, step = 1;
- if(reversed){
- i = bases.length - 1;
- step = -1;
- }
- for(; b = bases[i]; i += step){ // intentional assignment
- m = b._meta;
- f = (m ? m.hidden : b.prototype)[name];
- if(f){
- f.apply(this, arguments);
- }
- }
- };
- }
- // forceNew(ctor)
- // return a new object that inherits from ctor.prototype but
- // without actually running ctor on the object.
- function forceNew(ctor){
- // create object with correct prototype using a do-nothing
- // constructor
- xtor.prototype = ctor.prototype;
- var t = new xtor;
- xtor.prototype = null; // clean up
- return t;
- }
- // applyNew(args)
- // just like 'new ctor()' except that the constructor and its arguments come
- // from args, which must be an array or an arguments object
- function applyNew(args){
- // create an object with ctor's prototype but without
- // calling ctor on it.
- var ctor = args.callee, t = forceNew(ctor);
- // execute the real constructor on the new object
- ctor.apply(t, args);
- return t;
- }
- function declare(className, superclass, props){
- // summary:
- // Create a feature-rich constructor from compact notation.
- // className: String?
- // The optional name of the constructor (loosely, a "class")
- // stored in the "declaredClass" property in the created prototype.
- // It will be used as a global name for a created constructor.
- // superclass: Function|Function[]
- // May be null, a Function, or an Array of Functions. This argument
- // specifies a list of bases (the left-most one is the most deepest
- // base).
- // props: Object
- // An object whose properties are copied to the created prototype.
- // Add an instance-initialization function by making it a property
- // named "constructor".
- // returns: dojo/_base/declare.__DeclareCreatedObject
- // New constructor function.
- // description:
- // Create a constructor using a compact notation for inheritance and
- // prototype extension.
- //
- // Mixin ancestors provide a type of multiple inheritance.
- // Prototypes of mixin ancestors are copied to the new class:
- // changes to mixin prototypes will not affect classes to which
- // they have been mixed in.
- //
- // Ancestors can be compound classes created by this version of
- // declare(). In complex cases all base classes are going to be
- // linearized according to C3 MRO algorithm
- // (see http://www.python.org/download/releases/2.3/mro/ for more
- // details).
- //
- // "className" is cached in "declaredClass" property of the new class,
- // if it was supplied. The immediate super class will be cached in
- // "superclass" property of the new class.
- //
- // Methods in "props" will be copied and modified: "nom" property
- // (the declared name of the method) will be added to all copied
- // functions to help identify them for the internal machinery. Be
- // very careful, while reusing methods: if you use the same
- // function under different names, it can produce errors in some
- // cases.
- //
- // It is possible to use constructors created "manually" (without
- // declare()) as bases. They will be called as usual during the
- // creation of an instance, their methods will be chained, and even
- // called by "this.inherited()".
- //
- // Special property "-chains-" governs how to chain methods. It is
- // a dictionary, which uses method names as keys, and hint strings
- // as values. If a hint string is "after", this method will be
- // called after methods of its base classes. If a hint string is
- // "before", this method will be called before methods of its base
- // classes.
- //
- // If "constructor" is not mentioned in "-chains-" property, it will
- // be chained using the legacy mode: using "after" chaining,
- // calling preamble() method before each constructor, if available,
- // and calling postscript() after all constructors were executed.
- // If the hint is "after", it is chained as a regular method, but
- // postscript() will be called after the chain of constructors.
- // "constructor" cannot be chained "before", but it allows
- // a special hint string: "manual", which means that constructors
- // are not going to be chained in any way, and programmer will call
- // them manually using this.inherited(). In the latter case
- // postscript() will be called after the construction.
- //
- // All chaining hints are "inherited" from base classes and
- // potentially can be overridden. Be very careful when overriding
- // hints! Make sure that all chained methods can work in a proposed
- // manner of chaining.
- //
- // Once a method was chained, it is impossible to unchain it. The
- // only exception is "constructor". You don't need to define a
- // method in order to supply a chaining hint.
- //
- // If a method is chained, it cannot use this.inherited() because
- // all other methods in the hierarchy will be called automatically.
- //
- // Usually constructors and initializers of any kind are chained
- // using "after" and destructors of any kind are chained as
- // "before". Note that chaining assumes that chained methods do not
- // return any value: any returned value will be discarded.
- //
- // example:
- // | declare("my.classes.bar", my.classes.foo, {
- // | // properties to be added to the class prototype
- // | someValue: 2,
- // | // initialization function
- // | constructor: function(){
- // | this.myComplicatedObject = new ReallyComplicatedObject();
- // | },
- // | // other functions
- // | someMethod: function(){
- // | doStuff();
- // | }
- // | });
- //
- // example:
- // | var MyBase = declare(null, {
- // | // constructor, properties, and methods go here
- // | // ...
- // | });
- // | var MyClass1 = declare(MyBase, {
- // | // constructor, properties, and methods go here
- // | // ...
- // | });
- // | var MyClass2 = declare(MyBase, {
- // | // constructor, properties, and methods go here
- // | // ...
- // | });
- // | var MyDiamond = declare([MyClass1, MyClass2], {
- // | // constructor, properties, and methods go here
- // | // ...
- // | });
- //
- // example:
- // | var F = function(){ console.log("raw constructor"); };
- // | F.prototype.method = function(){
- // | console.log("raw method");
- // | };
- // | var A = declare(F, {
- // | constructor: function(){
- // | console.log("A.constructor");
- // | },
- // | method: function(){
- // | console.log("before calling F.method...");
- // | this.inherited(arguments);
- // | console.log("...back in A");
- // | }
- // | });
- // | new A().method();
- // | // will print:
- // | // raw constructor
- // | // A.constructor
- // | // before calling F.method...
- // | // raw method
- // | // ...back in A
- //
- // example:
- // | var A = declare(null, {
- // | "-chains-": {
- // | destroy: "before"
- // | }
- // | });
- // | var B = declare(A, {
- // | constructor: function(){
- // | console.log("B.constructor");
- // | },
- // | destroy: function(){
- // | console.log("B.destroy");
- // | }
- // | });
- // | var C = declare(B, {
- // | constructor: function(){
- // | console.log("C.constructor");
- // | },
- // | destroy: function(){
- // | console.log("C.destroy");
- // | }
- // | });
- // | new C().destroy();
- // | // prints:
- // | // B.constructor
- // | // C.constructor
- // | // C.destroy
- // | // B.destroy
- //
- // example:
- // | var A = declare(null, {
- // | "-chains-": {
- // | constructor: "manual"
- // | }
- // | });
- // | var B = declare(A, {
- // | constructor: function(){
- // | // ...
- // | // call the base constructor with new parameters
- // | this.inherited(arguments, [1, 2, 3]);
- // | // ...
- // | }
- // | });
- //
- // example:
- // | var A = declare(null, {
- // | "-chains-": {
- // | m1: "before"
- // | },
- // | m1: function(){
- // | console.log("A.m1");
- // | },
- // | m2: function(){
- // | console.log("A.m2");
- // | }
- // | });
- // | var B = declare(A, {
- // | "-chains-": {
- // | m2: "after"
- // | },
- // | m1: function(){
- // | console.log("B.m1");
- // | },
- // | m2: function(){
- // | console.log("B.m2");
- // | }
- // | });
- // | var x = new B();
- // | x.m1();
- // | // prints:
- // | // B.m1
- // | // A.m1
- // | x.m2();
- // | // prints:
- // | // A.m2
- // | // B.m2
- // crack parameters
- if(typeof className != "string"){
- props = superclass;
- superclass = className;
- className = "";
- }
- props = props || {};
- var proto, i, t, ctor, name, bases, chains, mixins = 1, parents = superclass;
- // build a prototype
- if(opts.call(superclass) == "[object Array]"){
- // C3 MRO
- bases = c3mro(superclass, className);
- t = bases[0];
- mixins = bases.length - t;
- superclass = bases[mixins];
- }else{
- bases = [0];
- if(superclass){
- if(opts.call(superclass) == "[object Function]"){
- t = superclass._meta;
- bases = bases.concat(t ? t.bases : superclass);
- }else{
- err("base class is not a callable constructor.", className);
- }
- }else if(superclass !== null){
- err("unknown base class. Did you use dojo.require to pull it in?", className);
- }
- }
- if(superclass){
- for(i = mixins - 1;; --i){
- proto = forceNew(superclass);
- if(!i){
- // stop if nothing to add (the last base)
- break;
- }
- // mix in properties
- t = bases[i];
- (t._meta ? mixOwn : mix)(proto, t.prototype);
- // chain in new constructor
- ctor = new Function;
- ctor.superclass = superclass;
- ctor.prototype = proto;
- superclass = proto.constructor = ctor;
- }
- }else{
- proto = {};
- }
- // add all properties
- declare.safeMixin(proto, props);
- // add constructor
- t = props.constructor;
- if(t !== op.constructor){
- t.nom = cname;
- proto.constructor = t;
- }
- // collect chains and flags
- for(i = mixins - 1; i; --i){ // intentional assignment
- t = bases[i]._meta;
- if(t && t.chains){
- chains = mix(chains || {}, t.chains);
- }
- }
- if(proto["-chains-"]){
- chains = mix(chains || {}, proto["-chains-"]);
- }
- // build ctor
- t = !chains || !chains.hasOwnProperty(cname);
- bases[0] = ctor = (chains && chains.constructor === "manual") ? simpleConstructor(bases) :
- (bases.length == 1 ? singleConstructor(props.constructor, t) : chainedConstructor(bases, t));
- // add meta information to the constructor
- ctor._meta = {bases: bases, hidden: props, chains: chains,
- parents: parents, ctor: props.constructor};
- ctor.superclass = superclass && superclass.prototype;
- ctor.extend = extend;
- ctor.createSubclass = createSubclass;
- ctor.prototype = proto;
- proto.constructor = ctor;
- // add "standard" methods to the prototype
- proto.getInherited = getInherited;
- proto.isInstanceOf = isInstanceOf;
- proto.inherited = inheritedImpl;
- proto.__inherited = inherited;
- // add name if specified
- if(className){
- proto.declaredClass = className;
- lang.setObject(className, ctor);
- }
- // build chains and add them to the prototype
- if(chains){
- for(name in chains){
- if(proto[name] && typeof chains[name] == "string" && name != cname){
- t = proto[name] = chain(name, bases, chains[name] === "after");
- t.nom = name;
- }
- }
- }
- // chained methods do not return values
- // no need to chain "invisible" functions
- return ctor; // Function
- }
- /*=====
- declare.__DeclareCreatedObject = {
- // summary:
- // dojo/_base/declare() returns a constructor `C`. `new C()` returns an Object with the following
- // methods, in addition to the methods and properties specified via the arguments passed to declare().
- inherited: function(name, args, newArgs){
- // summary:
- // Calls a super method.
- // name: String?
- // The optional method name. Should be the same as the caller's
- // name. Usually "name" is specified in complex dynamic cases, when
- // the calling method was dynamically added, undecorated by
- // declare(), and it cannot be determined.
- // args: Arguments
- // The caller supply this argument, which should be the original
- // "arguments".
- // newArgs: Object?
- // If "true", the found function will be returned without
- // executing it.
- // If Array, it will be used to call a super method. Otherwise
- // "args" will be used.
- // returns:
- // Whatever is returned by a super method, or a super method itself,
- // if "true" was specified as newArgs.
- // description:
- // This method is used inside method of classes produced with
- // declare() to call a super method (next in the chain). It is
- // used for manually controlled chaining. Consider using the regular
- // chaining, because it is faster. Use "this.inherited()" only in
- // complex cases.
- //
- // This method cannot me called from automatically chained
- // constructors including the case of a special (legacy)
- // constructor chaining. It cannot be called from chained methods.
- //
- // If "this.inherited()" cannot find the next-in-chain method, it
- // does nothing and returns "undefined". The last method in chain
- // can be a default method implemented in Object, which will be
- // called last.
- //
- // If "name" is specified, it is assumed that the method that
- // received "args" is the parent method for this call. It is looked
- // up in the chain list and if it is found the next-in-chain method
- // is called. If it is not found, the first-in-chain method is
- // called.
- //
- // If "name" is not specified, it will be derived from the calling
- // method (using a methoid property "nom").
- //
- // example:
- // | var B = declare(A, {
- // | method1: function(a, b, c){
- // | this.inherited(arguments);
- // | },
- // | method2: function(a, b){
- // | return this.inherited(arguments, [a + b]);
- // | }
- // | });
- // | // next method is not in the chain list because it is added
- // | // manually after the class was created.
- // | B.prototype.method3 = function(){
- // | console.log("This is a dynamically-added method.");
- // | this.inherited("method3", arguments);
- // | };
- // example:
- // | var B = declare(A, {
- // | method: function(a, b){
- // | var super = this.inherited(arguments, true);
- // | // ...
- // | if(!super){
- // | console.log("there is no super method");
- // | return 0;
- // | }
- // | return super.apply(this, arguments);
- // | }
- // | });
- return {}; // Object
- },
- getInherited: function(name, args){
- // summary:
- // Returns a super method.
- // name: String?
- // The optional method name. Should be the same as the caller's
- // name. Usually "name" is specified in complex dynamic cases, when
- // the calling method was dynamically added, undecorated by
- // declare(), and it cannot be determined.
- // args: Arguments
- // The caller supply this argument, which should be the original
- // "arguments".
- // returns:
- // Returns a super method (Function) or "undefined".
- // description:
- // This method is a convenience method for "this.inherited()".
- // It uses the same algorithm but instead of executing a super
- // method, it returns it, or "undefined" if not found.
- //
- // example:
- // | var B = declare(A, {
- // | method: function(a, b){
- // | var super = this.getInherited(arguments);
- // | // ...
- // | if(!super){
- // | console.log("there is no super method");
- // | return 0;
- // | }
- // | return super.apply(this, arguments);
- // | }
- // | });
- return {}; // Object
- },
- isInstanceOf: function(cls){
- // summary:
- // Checks the inheritance chain to see if it is inherited from this
- // class.
- // cls: Function
- // Class constructor.
- // returns:
- // "true", if this object is inherited from this class, "false"
- // otherwise.
- // description:
- // This method is used with instances of classes produced with
- // declare() to determine of they support a certain interface or
- // not. It models "instanceof" operator.
- //
- // example:
- // | var A = declare(null, {
- // | // constructor, properties, and methods go here
- // | // ...
- // | });
- // | var B = declare(null, {
- // | // constructor, properties, and methods go here
- // | // ...
- // | });
- // | var C = declare([A, B], {
- // | // constructor, properties, and methods go here
- // | // ...
- // | });
- // | var D = declare(A, {
- // | // constructor, properties, and methods go here
- // | // ...
- // | });
- // |
- // | var a = new A(), b = new B(), c = new C(), d = new D();
- // |
- // | console.log(a.isInstanceOf(A)); // true
- // | console.log(b.isInstanceOf(A)); // false
- // | console.log(c.isInstanceOf(A)); // true
- // | console.log(d.isInstanceOf(A)); // true
- // |
- // | console.log(a.isInstanceOf(B)); // false
- // | console.log(b.isInstanceOf(B)); // true
- // | console.log(c.isInstanceOf(B)); // true
- // | console.log(d.isInstanceOf(B)); // false
- // |
- // | console.log(a.isInstanceOf(C)); // false
- // | console.log(b.isInstanceOf(C)); // false
- // | console.log(c.isInstanceOf(C)); // true
- // | console.log(d.isInstanceOf(C)); // false
- // |
- // | console.log(a.isInstanceOf(D)); // false
- // | console.log(b.isInstanceOf(D)); // false
- // | console.log(c.isInstanceOf(D)); // false
- // | console.log(d.isInstanceOf(D)); // true
- return {}; // Object
- },
- extend: function(source){
- // summary:
- // Adds all properties and methods of source to constructor's
- // prototype, making them available to all instances created with
- // constructor. This method is specific to constructors created with
- // declare().
- // source: Object
- // Source object which properties are going to be copied to the
- // constructor's prototype.
- // description:
- // Adds source properties to the constructor's prototype. It can
- // override existing properties.
- //
- // This method is similar to dojo.extend function, but it is specific
- // to constructors produced by declare(). It is implemented
- // using dojo.safeMixin, and it skips a constructor property,
- // and properly decorates copied functions.
- //
- // example:
- // | var A = declare(null, {
- // | m1: function(){},
- // | s1: "Popokatepetl"
- // | });
- // | A.extend({
- // | m1: function(){},
- // | m2: function(){},
- // | f1: true,
- // | d1: 42
- // | });
- }
- };
- =====*/
- // For back-compat, remove for 2.0
- dojo.safeMixin = declare.safeMixin = safeMixin;
- dojo.declare = declare;
- return declare;
- });
- },
- 'dojo/dom':function(){
- define(["./sniff", "./_base/lang", "./_base/window"],
- function(has, lang, win){
- // module:
- // dojo/dom
- // FIXME: need to add unit tests for all the semi-public methods
- if(has("ie") <= 7){
- try{
- document.execCommand("BackgroundImageCache", false, true);
- }catch(e){
- // sane browsers don't have cache "issues"
- }
- }
- // =============================
- // DOM Functions
- // =============================
- // the result object
- var dom = {
- // summary:
- // This module defines the core dojo DOM API.
- };
- if(has("ie")){
- dom.byId = function(id, doc){
- if(typeof id != "string"){
- return id;
- }
- var _d = doc || win.doc, te = id && _d.getElementById(id);
- // attributes.id.value is better than just id in case the
- // user has a name=id inside a form
- if(te && (te.attributes.id.value == id || te.id == id)){
- return te;
- }else{
- var eles = _d.all[id];
- if(!eles || eles.nodeName){
- eles = [eles];
- }
- // if more than 1, choose first with the correct id
- var i = 0;
- while((te = eles[i++])){
- if((te.attributes && te.attributes.id && te.attributes.id.value == id) || te.id == id){
- return te;
- }
- }
- }
- };
- }else{
- dom.byId = function(id, doc){
- // inline'd type check.
- // be sure to return null per documentation, to match IE branch.
- return ((typeof id == "string") ? (doc || win.doc).getElementById(id) : id) || null; // DOMNode
- };
- }
- /*=====
- dom.byId = function(id, doc){
- // summary:
- // Returns DOM node with matching `id` attribute or falsy value (ex: null or undefined)
- // if not found. If `id` is a DomNode, this function is a no-op.
- //
- // id: String|DOMNode
- // A string to match an HTML id attribute or a reference to a DOM Node
- //
- // doc: Document?
- // Document to work in. Defaults to the current value of
- // dojo.doc. Can be used to retrieve
- // node references from other documents.
- //
- // example:
- // Look up a node by ID:
- // | var n = dojo.byId("foo");
- //
- // example:
- // Check if a node exists, and use it.
- // | var n = dojo.byId("bar");
- // | if(n){ doStuff() ... }
- //
- // example:
- // Allow string or DomNode references to be passed to a custom function:
- // | var foo = function(nodeOrId){
- // | nodeOrId = dojo.byId(nodeOrId);
- // | // ... more stuff
- // | }
- };
- =====*/
- dom.isDescendant = function(/*DOMNode|String*/ node, /*DOMNode|String*/ ancestor){
- // summary:
- // Returns true if node is a descendant of ancestor
- // node: DOMNode|String
- // string id or node reference to test
- // ancestor: DOMNode|String
- // string id or node reference of potential parent to test against
- //
- // example:
- // Test is node id="bar" is a descendant of node id="foo"
- // | if(dojo.isDescendant("bar", "foo")){ ... }
- try{
- node = dom.byId(node);
- ancestor = dom.byId(ancestor);
- while(node){
- if(node == ancestor){
- return true; // Boolean
- }
- node = node.parentNode;
- }
- }catch(e){ /* squelch, return false */ }
- return false; // Boolean
- };
- // TODO: do we need this function in the base?
- dom.setSelectable = function(/*DOMNode|String*/ node, /*Boolean*/ selectable){
- // summary:
- // Enable or disable selection on a node
- // node: DOMNode|String
- // id or reference to node
- // selectable: Boolean
- // state to put the node in. false indicates unselectable, true
- // allows selection.
- // example:
- // Make the node id="bar" unselectable
- // | dojo.setSelectable("bar");
- // example:
- // Make the node id="bar" selectable
- // | dojo.setSelectable("bar", true);
- node = dom.byId(node);
- if(has("mozilla")){
- node.style.MozUserSelect = selectable ? "" : "none";
- }else if(has("khtml") || has("webkit")){
- node.style.KhtmlUserSelect = selectable ? "auto" : "none";
- }else if(has("ie")){
- var v = (node.unselectable = selectable ? "" : "on"),
- cs = node.getElementsByTagName("*"), i = 0, l = cs.length;
- for(; i < l; ++i){
- cs.item(i).unselectable = v;
- }
- }
- //FIXME: else? Opera?
- };
- return dom;
- });
- },
- 'dojo/_base/browser':function(){
- if(require.has){
- require.has.add("config-selectorEngine", "acme");
- }
- define([
- "../ready",
- "./kernel",
- "./connect", // until we decide if connect is going back into non-browser environments
- "./unload",
- "./window",
- "./event",
- "./html",
- "./NodeList",
- "../query",
- "./xhr",
- "./fx"], function(dojo){
- // module:
- // dojo/_base/browser
- /*=====
- return {
- // summary:
- // This module causes the browser-only base modules to be loaded.
- };
- =====*/
- return dojo;
- });
- },
- 'dojo/selector/acme':function(){
- define([
- "../dom", "../sniff", "../_base/array", "../_base/lang", "../_base/window"
- ], function(dom, has, array, lang, win){
- // module:
- // dojo/selector/acme
- /*
- acme architectural overview:
- acme is a relatively full-featured CSS3 query library. It is
- designed to take any valid CSS3 selector and return the nodes matching
- the selector. To do this quickly, it processes queries in several
- steps, applying caching where profitable.
- The steps (roughly in reverse order of the way they appear in the code):
- 1.) check to see if we already have a "query dispatcher"
- - if so, use that with the given parameterization. Skip to step 4.
- 2.) attempt to determine which branch to dispatch the query to:
- - JS (optimized DOM iteration)
- - native (FF3.1+, Safari 3.1+, IE 8+)
- 3.) tokenize and convert to executable "query dispatcher"
- - this is where the lion's share of the complexity in the
- system lies. In the DOM version, the query dispatcher is
- assembled as a chain of "yes/no" test functions pertaining to
- a section of a simple query statement (".blah:nth-child(odd)"
- but not "div div", which is 2 simple statements). Individual
- statement dispatchers are cached (to prevent re-definition)
- as are entire dispatch chains (to make re-execution of the
- same query fast)
- 4.) the resulting query dispatcher is called in the passed scope
- (by default the top-level document)
- - for DOM queries, this results in a recursive, top-down
- evaluation of nodes based on each simple query section
- - for native implementations, this may mean working around spec
- bugs. So be it.
- 5.) matched nodes are pruned to ensure they are unique (if necessary)
- */
- ////////////////////////////////////////////////////////////////////////
- // Toolkit aliases
- ////////////////////////////////////////////////////////////////////////
- // if you are extracting acme for use in your own system, you will
- // need to provide these methods and properties. No other porting should be
- // necessary, save for configuring the system to use a class other than
- // dojo/NodeList as the return instance instantiator
- var trim = lang.trim;
- var each = array.forEach;
- var getDoc = function(){ return win.doc; };
- // NOTE(alex): the spec is idiotic. CSS queries should ALWAYS be case-sensitive, but nooooooo
- var cssCaseBug = (getDoc().compatMode) == "BackCompat";
- ////////////////////////////////////////////////////////////////////////
- // Global utilities
- ////////////////////////////////////////////////////////////////////////
- var specials = ">~+";
- // global thunk to determine whether we should treat the current query as
- // case sensitive or not. This switch is flipped by the query evaluator
- // based on the document passed as the context to search.
- var caseSensitive = false;
- // how high?
- var yesman = function(){ return true; };
- ////////////////////////////////////////////////////////////////////////
- // Tokenizer
- ////////////////////////////////////////////////////////////////////////
- var getQueryParts = function(query){
- // summary:
- // state machine for query tokenization
- // description:
- // instead of using a brittle and slow regex-based CSS parser,
- // acme implements an AST-style query representation. This
- // representation is only generated once per query. For example,
- // the same query run multiple times or under different root nodes
- // does not re-parse the selector expression but instead uses the
- // cached data structure. The state machine implemented here
- // terminates on the last " " (space) character and returns an
- // ordered array of query component structures (or "parts"). Each
- // part represents an operator or a simple CSS filtering
- // expression. The structure for parts is documented in the code
- // below.
- // NOTE:
- // this code is designed to run fast and compress well. Sacrifices
- // to readability and maintainability have been made. Your best
- // bet when hacking the tokenizer is to put The Donnas on *really*
- // loud (may we recommend their "Spend The Night" release?) and
- // just assume you're gonna make mistakes. Keep the unit tests
- // open and run them frequently. Knowing is half the battle ;-)
- if(specials.indexOf(query.slice(-1)) >= 0){
- // if we end with a ">", "+", or "~", that means we're implicitly
- // searching all children, so make it explicit
- query += " * ";
- }else{
- // if you have not provided a terminator, one will be provided for
- // you...
- query += " ";
- }
- var ts = function(/*Integer*/ s, /*Integer*/ e){
- // trim and slice.
- // take an index to start a string slice from and an end position
- // and return a trimmed copy of that sub-string
- return trim(query.slice(s, e));
- };
- // the overall data graph of the full query, as represented by queryPart objects
- var queryParts = [];
- // state keeping vars
- var inBrackets = -1, inParens = -1, inMatchFor = -1,
- inPseudo = -1, inClass = -1, inId = -1, inTag = -1, currentQuoteChar,
- lc = "", cc = "", pStart;
- // iteration vars
- var x = 0, // index in the query
- ql = query.length,
- currentPart = null, // data structure representing the entire clause
- _cp = null; // the current pseudo or attr matcher
- // several temporary variables are assigned to this structure during a
- // potential sub-expression match:
- // attr:
- // a string representing the current full attribute match in a
- // bracket expression
- // type:
- // if there's an operator in a bracket expression, this is
- // used to keep track of it
- // value:
- // the internals of parenthetical expression for a pseudo. for
- // :nth-child(2n+1), value might be "2n+1"
- var endTag = function(){
- // called when the tokenizer hits the end of a particular tag name.
- // Re-sets state variables for tag matching and sets up the matcher
- // to handle the next type of token (tag or operator).
- if(inTag >= 0){
- var tv = (inTag == x) ? null : ts(inTag, x); // .toLowerCase();
- currentPart[ (specials.indexOf(tv) < 0) ? "tag" : "oper" ] = tv;
- inTag = -1;
- }
- };
- var endId = function(){
- // called when the tokenizer might be at the end of an ID portion of a match
- if(inId >= 0){
- currentPart.id = ts(inId, x).replace(/\\/g, "");
- inId = -1;
- }
- };
- var endClass = function(){
- // called when the tokenizer might be at the end of a class name
- // match. CSS allows for multiple classes, so we augment the
- // current item with another class in its list
- if(inClass >= 0){
- currentPart.classes.push(ts(inClass + 1, x).replace(/\\/g, ""));
- inClass = -1;
- }
- };
- var endAll = function(){
- // at the end of a simple fragment, so wall off the matches
- endId();
- endTag();
- endClass();
- };
- var endPart = function(){
- endAll();
- if(inPseudo >= 0){
- currentPart.pseudos.push({ name: ts(inPseudo + 1, x) });
- }
- // hint to the selector engine to tell it whether or not it
- // needs to do any iteration. Many simple selectors don't, and
- // we can avoid significant construction-time work by advising
- // the system to skip them
- currentPart.loops = (
- currentPart.pseudos.length ||
- currentPart.attrs.length ||
- currentPart.classes.length );
- currentPart.oquery = currentPart.query = ts(pStart, x); // save the full expression as a string
- // otag/tag are hints to suggest to the system whether or not
- // it's an operator or a tag. We save a copy of otag since the
- // tag name is cast to upper-case in regular HTML matches. The
- // system has a global switch to figure out if the current
- // expression needs to be case sensitive or not and it will use
- // otag or tag accordingly
- currentPart.otag = currentPart.tag = (currentPart["oper"]) ? null : (currentPart.tag || "*");
- if(currentPart.tag){
- // if we're in a case-insensitive HTML doc, we likely want
- // the toUpperCase when matching on element.tagName. If we
- // do it here, we can skip the string op per node
- // comparison
- currentPart.tag = currentPart.tag.toUpperCase();
- }
- // add the part to the list
- if(queryParts.length && (queryParts[queryParts.length-1].oper)){
- // operators are always infix, so we remove them from the
- // list and attach them to the next match. The evaluator is
- // responsible for sorting out how to handle them.
- currentPart.infixOper = queryParts.pop();
- currentPart.query = currentPart.infixOper.query + " " + currentPart.query;
- /*
- console.debug( "swapping out the infix",
- currentPart.infixOper,
- "and attaching it to",
- currentPart);
- */
- }
- queryParts.push(currentPart);
- currentPart = null;
- };
- // iterate over the query, character by character, building up a
- // list of query part objects
- for(; lc=cc, cc=query.charAt(x), x < ql; x++){
- // cc: the current character in the match
- // lc: the last character (if any)
- // someone is trying to escape something, so don't try to match any
- // fragments. We assume we're inside a literal.
- if(lc == "\\"){ continue; }
- if(!currentPart){ // a part was just ended or none has yet been created
- // NOTE: I hate all this alloc, but it's shorter than writing tons of if's
- pStart = x;
- // rules describe full CSS sub-expressions, like:
- // #someId
- // .className:first-child
- // but not:
- // thinger > div.howdy[type=thinger]
- // the indidual components of the previous query would be
- // split into 3 parts that would be represented a structure like:
- // [
- // {
- // query: "thinger",
- // tag: "thinger",
- // },
- // {
- // query: "div.howdy[type=thinger]",
- // classes: ["howdy"],
- // infixOper: {
- // query: ">",
- // oper: ">",
- // }
- // },
- // ]
- currentPart = {
- query: null, // the full text of the part's rule
- pseudos: [], // CSS supports multiple pseud-class matches in a single rule
- attrs: [], // CSS supports multi-attribute match, so we need an array
- classes: [], // class matches may be additive, e.g.: .thinger.blah.howdy
- tag: null, // only one tag...
- oper: null, // ...or operator per component. Note that these wind up being exclusive.
- id: null, // the id component of a rule
- getTag: function(){
- return caseSensitive ? this.otag : this.tag;
- }
- };
- // if we don't have a part, we assume we're going to start at
- // the beginning of a match, which should be a tag name. This
- // might fault a little later on, but we detect that and this
- // iteration will still be fine.
- inTag = x;
- }
- // Skip processing all quoted characters.
- // If we are inside quoted text then currentQuoteChar stores the character that began the quote,
- // thus that character that will end it.
- if(currentQuoteChar){
- if(cc == currentQuoteChar){
- currentQuoteChar = null;
- }
- continue;
- }else if (cc == "'" || cc == '"'){
- currentQuoteChar = cc;
- continue;
- }
- if(inBrackets >= 0){
- // look for a the close first
- if(cc == "]"){ // if we're in a [...] clause and we end, do assignment
- if(!_cp.attr){
- // no attribute match was previously begun, so we
- // assume this is an attribute existence match in the
- // form of [someAttributeName]
- _cp.attr = ts(inBrackets+1, x);
- }else{
- // we had an attribute already, so we know that we're
- // matching some sort of value, as in [attrName=howdy]
- _cp.matchFor = ts((inMatchFor||inBrackets+1), x);
- }
- var cmf = _cp.matchFor;
- if(cmf){
- // try to strip quotes from the matchFor value. We want
- // [attrName=howdy] to match the same
- // as [attrName = 'howdy' ]
- if( (cmf.charAt(0) == '"') || (cmf.charAt(0) == "'") ){
- _cp.matchFor = cmf.slice(1, -1);
- }
- }
- // remove backslash escapes from an attribute match, since DOM
- // querying will get attribute values without backslashes
- if(_cp.matchFor){
- _cp.matchFor = _cp.matchFor.replace(/\\/g, "");
- }
- // end the attribute by adding it to the list of attributes.
- currentPart.attrs.push(_cp);
- _cp = null; // necessary?
- inBrackets = inMatchFor = -1;
- }else if(cc == "="){
- // if the last char was an operator prefix, make sure we
- // record it along with the "=" operator.
- var addToCc = ("|~^$*".indexOf(lc) >=0 ) ? lc : "";
- _cp.type = addToCc+cc;
- _cp.attr = ts(inBrackets+1, x-addToCc.length);
- inMatchFor = x+1;
- }
- // now look for other clause parts
- }else if(inParens >= 0){
- // if we're in a parenthetical expression, we need to figure
- // out if it's attached to a pseudo-selector rule like
- // :nth-child(1)
- if(cc == ")"){
- if(inPseudo >= 0){
- _cp.value = ts(inParens+1, x);
- }
- inPseudo = inParens = -1;
- }
- }else if(cc == "#"){
- // start of an ID match
- endAll();
- inId = x+1;
- }else if(cc == "."){
- // start of a class match
- endAll();
- inClass = x;
- }else if(cc == ":"){
- // start of a pseudo-selector match
- endAll();
- inPseudo = x;
- }else if(cc == "["){
- // start of an attribute match.
- endAll();
- inBrackets = x;
- // provide a new structure for the attribute match to fill-in
- _cp = {
- /*=====
- attr: null, type: null, matchFor: null
- =====*/
- };
- }else if(cc == "("){
- // we really only care if we've entered a parenthetical
- // expression if we're already inside a pseudo-selector match
- if(inPseudo >= 0){
- // provide a new structure for the pseudo match to fill-in
- _cp = {
- name: ts(inPseudo+1, x),
- value: null
- };
- currentPart.pseudos.push(_cp);
- }
- inParens = x;
- }else if(
- (cc == " ") &&
- // if it's a space char and the last char is too, consume the
- // current one without doing more work
- (lc != cc)
- ){
- endPart();
- }
- }
- return queryParts;
- };
- ////////////////////////////////////////////////////////////////////////
- // DOM query infrastructure
- ////////////////////////////////////////////////////////////////////////
- var agree = function(first, second){
- // the basic building block of the yes/no chaining system. agree(f1,
- // f2) generates a new function which returns the boolean results of
- // both of the passed functions to a single logical-anded result. If
- // either are not passed, the other is used exclusively.
- if(!first){ return second; }
- if(!second){ return first; }
- return function(){
- return first.apply(window, arguments) && second.apply(window, arguments);
- };
- };
- var getArr = function(i, arr){
- // helps us avoid array alloc when we don't need it
- var r = arr||[]; // FIXME: should this be 'new d._NodeListCtor()' ?
- if(i){ r.push(i); }
- return r;
- };
- var _isElement = function(n){ return (1 == n.nodeType); };
- // FIXME: need to coalesce _getAttr with defaultGetter
- var blank = "";
- var _getAttr = function(elem, attr){
- if(!elem){ return blank; }
- if(attr == "class"){
- return elem.className || blank;
- }
- if(attr == "for"){
- return elem.htmlFor || blank;
- }
- if(attr == "style"){
- return elem.style.cssText || blank;
- }
- return (caseSensitive ? elem.getAttribute(attr) : elem.getAttribute(attr, 2)) || blank;
- };
- var attrs = {
- "*=": function(attr, value){
- return function(elem){
- // E[foo*="bar"]
- // an E element whose "foo" attribute value contains
- // the substring "bar"
- return (_getAttr(elem, attr).indexOf(value)>=0);
- };
- },
- "^=": function(attr, value){
- // E[foo^="bar"]
- // an E element whose "foo" attribute value begins exactly
- // with the string "bar"
- return function(elem){
- return (_getAttr(elem, attr).indexOf(value)==0);
- };
- },
- "$=": function(attr, value){
- // E[foo$="bar"]
- // an E element whose "foo" attribute value ends exactly
- // with the string "bar"
- return function(elem){
- var ea = " "+_getAttr(elem, attr);
- var lastIndex = ea.lastIndexOf(value);
- return lastIndex > -1 && (lastIndex==(ea.length-value.length));
- };
- },
- "~=": function(attr, value){
- // E[foo~="bar"]
- // an E element whose "foo" attribute value is a list of
- // space-separated values, one of which is exactly equal
- // to "bar"
- // return "[contains(concat(' ',@"+attr+",' '), ' "+ value +" ')]";
- var tval = " "+value+" ";
- return function(elem){
- var ea = " "+_getAttr(elem, attr)+" ";
- return (ea.indexOf(tval)>=0);
- };
- },
- "|=": function(attr, value){
- // E[hreflang|="en"]
- // an E element whose "hreflang" attribute has a
- // hyphen-separated list of values beginning (from the
- // left) with "en"
- var valueDash = value+"-";
- return function(elem){
- var ea = _getAttr(elem, attr);
- return (
- (ea == value) ||
- (ea.indexOf(valueDash)==0)
- );
- };
- },
- "=": function(attr, value){
- return function(elem){
- return (_getAttr(elem, attr) == value);
- };
- }
- };
- // avoid testing for node type if we can. Defining this in the negative
- // here to avoid negation in the fast path.
- var _noNES = (typeof getDoc().firstChild.nextElementSibling == "undefined");
- var _ns = !_noNES ? "nextElementSibling" : "nextSibling";
- var _ps = !_noNES ? "previousElementSibling" : "previousSibling";
- var _simpleNodeTest = (_noNES ? _isElement : yesman);
- var _lookLeft = function(node){
- // look left
- while(node = node[_ps]){
- if(_simpleNodeTest(node)){ return false; }
- }
- return true;
- };
- var _lookRight = function(node){
- // look right
- while(node = node[_ns]){
- if(_simpleNodeTest(node)){ return false; }
- }
- return true;
- };
- var getNodeIndex = function(node){
- var root = node.parentNode;
- root = root.nodeType != 7 ? root : root.nextSibling; // PROCESSING_INSTRUCTION_NODE
- var i = 0,
- tret = root.children || root.childNodes,
- ci = (node["_i"]||node.getAttribute("_i")||-1),
- cl = (root["_l"]|| (typeof root.getAttribute !== "undefined" ? root.getAttribute("_l") : -1));
- if(!tret){ return -1; }
- var l = tret.length;
- // we calculate the parent length as a cheap way to invalidate the
- // cache. It's not 100% accurate, but it's much more honest than what
- // other libraries do
- if( cl == l && ci >= 0 && cl >= 0 ){
- // if it's legit, tag and release
- return ci;
- }
- // else re-key things
- if(has("ie") && typeof root.setAttribute !== "undefined"){
- root.setAttribute("_l", l);
- }else{
- root["_l"] = l;
- }
- ci = -1;
- for(var te = root["firstElementChild"]||root["firstChild"]; te; te = te[_ns]){
- if(_simpleNodeTest(te)){
- if(has("ie")){
- te.setAttribute("_i", ++i);
- }else{
- te["_i"] = ++i;
- }
- if(node === te){
- // NOTE:
- // shortcutting the return at this step in indexing works
- // very well for benchmarking but we avoid it here since
- // it leads to potential O(n^2) behavior in sequential
- // getNodexIndex operations on a previously un-indexed
- // parent. We may revisit this at a later time, but for
- // now we just want to get the right answer more often
- // than not.
- ci = i;
- }
- }
- }
- return ci;
- };
- var isEven = function(elem){
- return !((getNodeIndex(elem)) % 2);
- };
- var isOdd = function(elem){
- return ((getNodeIndex(elem)) % 2);
- };
- var pseudos = {
- "checked": function(name, condition){
- return function(elem){
- return !!("checked" in elem ? elem.checked : elem.selected);
- };
- },
- "disabled": function(name, condition){
- return function(elem){
- return elem.disabled;
- };
- },
- "enabled": function(name, condition){
- return function(elem){
- return !elem.disabled;
- };
- },
- "first-child": function(){ return _lookLeft; },
- "last-child": function(){ return _lookRight; },
- "only-child": function(name, condition){
- return function(node){
- return _lookLeft(node) && _lookRight(node);
- };
- },
- "empty": function(name, condition){
- return function(elem){
- // DomQuery and jQuery get this wrong, oddly enough.
- // The CSS 3 selectors spec is pretty explicit about it, too.
- var cn = elem.childNodes;
- var cnl = elem.childNodes.length;
- // if(!cnl){ return true; }
- for(var x=cnl-1; x >= 0; x--){
- var nt = cn[x].nodeType;
- if((nt === 1)||(nt == 3)){ return false; }
- }
- return true;
- };
- },
- "contains": function(name, condition){
- var cz = condition.charAt(0);
- if( cz == '"' || cz == "'" ){ //remove quote
- condition = condition.slice(1, -1);
- }
- return function(elem){
- return (elem.innerHTML.indexOf(condition) >= 0);
- };
- },
- "not": function(name, condition){
- var p = getQueryParts(condition)[0];
- var ignores = { el: 1 };
- if(p.tag != "*"){
- ignores.tag = 1;
- }
- if(!p.classes.length){
- ignores.classes = 1;
- }
- var ntf = getSimpleFilterFunc(p, ignores);
- return function(elem){
- return (!ntf(elem));
- };
- },
- "nth-child": function(name, condition){
- var pi = parseInt;
- // avoid re-defining function objects if we can
- if(condition == "odd"){
- return isOdd;
- }else if(condition == "even"){
- return isEven;
- }
- // FIXME: can we shorten this?
- if(condition.indexOf("n") != -1){
- var tparts = condition.split("n", 2);
- var pred = tparts[0] ? ((tparts[0] == '-') ? -1 : pi(tparts[0])) : 1;
- var idx = tparts[1] ? pi(tparts[1]) : 0;
- var lb = 0, ub = -1;
- if(pred > 0){
- if(idx < 0){
- idx = (idx % pred) && (pred + (idx % pred));
- }else if(idx>0){
- if(idx >= pred){
- lb = idx - idx % pred;
- }
- idx = idx % pred;
- }
- }else if(pred<0){
- pred *= -1;
- // idx has to be greater than 0 when pred is negative;
- // shall we throw an error here?
- if(idx > 0){
- ub = idx;
- idx = idx % pred;
- }
- }
- if(pred > 0){
- return function(elem){
- var i = getNodeIndex(elem);
- return (i>=lb) && (ub<0 || i<=ub) && ((i % pred) == idx);
- };
- }else{
- condition = idx;
- }
- }
- var ncount = pi(condition);
- return function(elem){
- return (getNodeIndex(elem) == ncount);
- };
- }
- };
- var defaultGetter = (has("ie") && (has("ie") < 9 || has("quirks"))) ? function(cond){
- var clc = cond.toLowerCase();
- if(clc == "class"){ cond = "className"; }
- return function(elem){
- return (caseSensitive ? elem.getAttribute(cond) : elem[cond]||elem[clc]);
- };
- } : function(cond){
- return function(elem){
- return (elem && elem.getAttribute && elem.hasAttribute(cond));
- };
- };
- var getSimpleFilterFunc = function(query, ignores){
- // generates a node tester function based on the passed query part. The
- // query part is one of the structures generated by the query parser
- // when it creates the query AST. The "ignores" object specifies which
- // (if any) tests to skip, allowing the system to avoid duplicating
- // work where it may have already been taken into account by other
- // factors such as how the nodes to test were fetched in the first
- // place
- if(!query){ return yesman; }
- ignores = ignores||{};
- var ff = null;
- if(!("el" in ignores)){
- ff = agree(ff, _isElement);
- }
- if(!("tag" in ignores)){
- if(query.tag != "*"){
- ff = agree(ff, function(elem){
- return (elem && ((caseSensitive ? elem.tagName : elem.tagName.toUpperCase()) == query.getTag()));
- });
- }
- }
- if(!("classes" in ignores)){
- each(query.classes, function(cname, idx, arr){
- // get the class name
- /*
- var isWildcard = cname.charAt(cname.length-1) == "*";
- if(isWildcard){
- cname = cname.substr(0, cname.length-1);
- }
- // I dislike the regex thing, even if memoized in a cache, but it's VERY short
- var re = new RegExp("(?:^|\\s)" + cname + (isWildcard ? ".*" : "") + "(?:\\s|$)");
- */
- var re = new RegExp("(?:^|\\s)" + cname + "(?:\\s|$)");
- ff = agree(ff, function(elem){
- return re.test(elem.className);
- });
- ff.count = idx;
- });
- }
- if(!("pseudos" in ignores)){
- each(query.pseudos, function(pseudo){
- var pn = pseudo.name;
- if(pseudos[pn]){
- ff = agree(ff, pseudos[pn](pn, pseudo.value));
- }
- });
- }
- if(!("attrs" in ignores)){
- each(query.attrs, function(attr){
- var matcher;
- var a = attr.attr;
- // type, attr, matchFor
- if(attr.type && attrs[attr.type]){
- matcher = attrs[attr.type](a, attr.matchFor);
- }else if(a.length){
- matcher = defaultGetter(a);
- }
- if(matcher){
- ff = agree(ff, matcher);
- }
- });
- }
- if(!("id" in ignores)){
- if(query.id){
- ff = agree(ff, function(elem){
- return (!!elem && (elem.id == query.id));
- });
- }
- }
- if(!ff){
- if(!("default" in ignores)){
- ff = yesman;
- }
- }
- return ff;
- };
- var _nextSibling = function(filterFunc){
- return function(node, ret, bag){
- while(node = node[_ns]){
- if(_noNES && (!_isElement(node))){ continue; }
- if(
- (!bag || _isUnique(node, bag)) &&
- filterFunc(node)
- ){
- ret.push(node);
- }
- break;
- }
- return ret;
- };
- };
- var _nextSiblings = function(filterFunc){
- return function(root, ret, bag){
- var te = root[_ns];
- while(te){
- if(_simpleNodeTest(te)){
- if(bag && !_isUnique(te, bag)){
- break;
- }
- if(filterFunc(te)){
- ret.push(te);
- }
- }
- te = te[_ns];
- }
- return ret;
- };
- };
- // get an array of child *elements*, skipping text and comment nodes
- var _childElements = function(filterFunc){
- filterFunc = filterFunc||yesman;
- return function(root, ret, bag){
- // get an array of child elements, skipping text and comment nodes
- var te, x = 0, tret = root.children || root.childNodes;
- while(te = tret[x++]){
- if(
- _simpleNodeTest(te) &&
- (!bag || _isUnique(te, bag)) &&
- (filterFunc(te, x))
- ){
- ret.push(te);
- }
- }
- return ret;
- };
- };
- // test to see if node is below root
- var _isDescendant = function(node, root){
- var pn = node.parentNode;
- while(pn){
- if(pn == root){
- break;
- }
- pn = pn.parentNode;
- }
- return !!pn;
- };
- var _getElementsFuncCache = {};
- var getElementsFunc = function(query){
- var retFunc = _getElementsFuncCache[query.query];
- // if we've got a cached dispatcher, just use that
- if(retFunc){ return retFunc; }
- // else, generate a new on
- // NOTE:
- // this function returns a function that searches for nodes and
- // filters them. The search may be specialized by infix operators
- // (">", "~", or "+") else it will default to searching all
- // descendants (the " " selector). Once a group of children is
- // found, a test function is applied to weed out the ones we
- // don't want. Many common cases can be fast-pathed. We spend a
- // lot of cycles to create a dispatcher that doesn't do more work
- // than necessary at any point since, unlike this function, the
- // dispatchers will be called every time. The logic of generating
- // efficient dispatchers looks like this in pseudo code:
- //
- // # if it's a purely descendant query (no ">", "+", or "~" modifiers)
- // if infixOperator == " ":
- // if only(id):
- // return def(root):
- // return d.byId(id, root);
- //
- // elif id:
- // return def(root):
- // return filter(d.byId(id, root));
- //
- // elif cssClass && getElementsByClassName:
- // return def(root):
- // return filter(root.getElementsByClassName(cssClass));
- //
- // elif only(tag):
- // return def(root):
- // return root.getElementsByTagName(tagName);
- //
- // else:
- // # search by tag name, then filter
- // return def(root):
- // return filter(root.getElementsByTagName(tagName||"*"));
- //
- // elif infixOperator == ">":
- // # search direct children
- // return def(root):
- // return filter(root.children);
- //
- // elif infixOperator == "+":
- // # search next sibling
- // return def(root):
- // return filter(root.nextElementSibling);
- //
- // elif infixOperator == "~":
- // # search rightward siblings
- // return def(root):
- // return filter(nextSiblings(root));
- var io = query.infixOper;
- var oper = (io ? io.oper : "");
- // the default filter func which tests for all conditions in the query
- // part. This is potentially inefficient, so some optimized paths may
- // re-define it to test fewer things.
- var filterFunc = getSimpleFilterFunc(query, { el: 1 });
- var qt = query.tag;
- var wildcardTag = ("*" == qt);
- var ecs = getDoc()["getElementsByClassName"];
- if(!oper){
- // if there's no infix operator, then it's a descendant query. ID
- // and "elements by class name" variants can be accelerated so we
- // call them out explicitly:
- if(query.id){
- // testing shows that the overhead of yesman() is acceptable
- // and can save us some bytes vs. re-defining the function
- // everywhere.
- filterFunc = (!query.loops && wildcardTag) ?
- yesman :
- getSimpleFilterFunc(query, { el: 1, id: 1 });
- retFunc = function(root, arr){
- var te = dom.byId(query.id, (root.ownerDocument||root));
- if(!te || !filterFunc(te)){ return; }
- if(9 == root.nodeType){ // if root's a doc, we just return directly
- return getArr(te, arr);
- }else{ // otherwise check ancestry
- if(_isDescendant(te, root)){
- return getArr(te, arr);
- }
- }
- };
- }else if(
- ecs &&
- // isAlien check. Workaround for Prototype.js being totally evil/dumb.
- /\{\s*\[native code\]\s*\}/.test(String(ecs)) &&
- query.classes.length &&
- !cssCaseBug
- ){
- // it's a class-based query and we've got a fast way to run it.
- // ignore class and ID filters since we will have handled both
- filterFunc = getSimpleFilterFunc(query, { el: 1, classes: 1, id: 1 });
- var classesString = query.classes.join(" ");
- retFunc = function(root, arr, bag){
- var ret = getArr(0, arr), te, x=0;
- var tret = root.getElementsByClassName(classesString);
- while((te = tret[x++])){
- if(filterFunc(te, root) && _isUnique(te, bag)){
- ret.push(te);
- }
- }
- return ret;
- };
- }else if(!wildcardTag && !query.loops){
- // it's tag only. Fast-path it.
- retFunc = function(root, arr, bag){
- var ret = getArr(0, arr), te, x=0;
- var tag = query.getTag(),
- tret = tag ? root.getElementsByTagName(tag) : [];
- while((te = tret[x++])){
- if(_isUnique(te, bag)){
- ret.push(te);
- }
- }
- return ret;
- };
- }else{
- // the common case:
- // a descendant selector without a fast path. By now it's got
- // to have a tag selector, even if it's just "*" so we query
- // by that and filter
- filterFunc = getSimpleFilterFunc(query, { el: 1, tag: 1, id: 1 });
- retFunc = function(root, arr, bag){
- var ret = getArr(0, arr), te, x=0;
- // we use getTag() to avoid case sensitivity issues
- var tag = query.getTag(),
- tret = tag ? root.getElementsByTagName(tag) : [];
- while((te = tret[x++])){
- if(filterFunc(te, root) && _isUnique(te, bag)){
- ret.push(te);
- }
- }
- return ret;
- };
- }
- }else{
- // the query is scoped in some way. Instead of querying by tag we
- // use some other collection to find candidate nodes
- var skipFilters = { el: 1 };
- if(wildcardTag){
- skipFilters.tag = 1;
- }
- filterFunc = getSimpleFilterFunc(query, skipFilters);
- if("+" == oper){
- retFunc = _nextSibling(filterFunc);
- }else if("~" == oper){
- retFunc = _nextSiblings(filterFunc);
- }else if(">" == oper){
- retFunc = _childElements(filterFunc);
- }
- }
- // cache it and return
- return _getElementsFuncCache[query.query] = retFunc;
- };
- var filterDown = function(root, queryParts){
- // NOTE:
- // this is the guts of the DOM query system. It takes a list of
- // parsed query parts and a root and finds children which match
- // the selector represented by the parts
- var candidates = getArr(root), qp, x, te, qpl = queryParts.length, bag, ret;
- for(var i = 0; i < qpl; i++){
- ret = [];
- qp = queryParts[i];
- x = candidates.length - 1;
- if(x > 0){
- // if we have more than one root at this level, provide a new
- // hash to use for checking group membership but tell the
- // system not to post-filter us since we will already have been
- // guaranteed to be unique
- bag = {};
- ret.nozip = true;
- }
- var gef = getElementsFunc(qp);
- for(var j = 0; (te = candidates[j]); j++){
- // for every root, get the elements that match the descendant
- // selector, adding them to the "ret" array and filtering them
- // via membership in this level's bag. If there are more query
- // parts, then this level's return will be used as the next
- // level's candidates
- gef(te, ret, bag);
- }
- if(!ret.length){ break; }
- candidates = ret;
- }
- return ret;
- };
- ////////////////////////////////////////////////////////////////////////
- // the query runner
- ////////////////////////////////////////////////////////////////////////
- // these are the primary caches for full-query results. The query
- // dispatcher functions are generated then stored here for hash lookup in
- // the future
- var _queryFuncCacheDOM = {},
- _queryFuncCacheQSA = {};
- // this is the second level of splitting, from full-length queries (e.g.,
- // "div.foo .bar") into simple query expressions (e.g., ["div.foo",
- // ".bar"])
- var getStepQueryFunc = function(query){
- var qparts = getQueryParts(trim(query));
- // if it's trivial, avoid iteration and zipping costs
- if(qparts.length == 1){
- // we optimize this case here to prevent dispatch further down the
- // chain, potentially slowing things down. We could more elegantly
- // handle this in filterDown(), but it's slower for simple things
- // that need to be fast (e.g., "#someId").
- var tef = getElementsFunc(qparts[0]);
- return function(root){
- var r = tef(root, []);
- if(r){ r.nozip = true; }
- return r;
- };
- }
- // otherwise, break it up and return a runner that iterates over the parts recursively
- return function(root){
- return filterDown(root, qparts);
- };
- };
- // NOTES:
- // * we can't trust QSA for anything but document-rooted queries, so
- // caching is split into DOM query evaluators and QSA query evaluators
- // * caching query results is dirty and leak-prone (or, at a minimum,
- // prone to unbounded growth). Other toolkits may go this route, but
- // they totally destroy their own ability to manage their memory
- // footprint. If we implement it, it should only ever be with a fixed
- // total element reference # limit and an LRU-style algorithm since JS
- // has no weakref support. Caching compiled query evaluators is also
- // potentially problematic, but even on large documents the size of the
- // query evaluators is often < 100 function objects per evaluator (and
- // LRU can be applied if it's ever shown to be an issue).
- // * since IE's QSA support is currently only for HTML documents and even
- // then only in IE 8's "standards mode", we have to detect our dispatch
- // route at query time and keep 2 separate caches. Ugg.
- // we need to determine if we think we can run a given query via
- // querySelectorAll or if we'll need to fall back on DOM queries to get
- // there. We need a lot of information about the environment and the query
- // to make the determination (e.g. does it support QSA, does the query in
- // question work in the native QSA impl, etc.).
- // IE QSA queries may incorrectly include comment nodes, so we throw the
- // zipping function into "remove" comments mode instead of the normal "skip
- // it" which every other QSA-clued browser enjoys
- var noZip = has("ie") ? "commentStrip" : "nozip";
- var qsa = "querySelectorAll";
- var qsaAvail = !!getDoc()[qsa];
- //Don't bother with n+3 type of matches, IE complains if we modify those.
- var infixSpaceRe = /\\[>~+]|n\+\d|([^ \\])?([>~+])([^ =])?/g;
- var infixSpaceFunc = function(match, pre, ch, post){
- return ch ? (pre ? pre + " " : "") + ch + (post ? " " + post : "") : /*n+3*/ match;
- };
-
- //Don't apply the infixSpaceRe to attribute value selectors
- var attRe = /([^[]*)([^\]]*])?/g;
- var attFunc = function(match, nonAtt, att){
- return nonAtt.replace(infixSpaceRe, infixSpaceFunc) + (att||"");
- };
- var getQueryFunc = function(query, forceDOM){
- //Normalize query. The CSS3 selectors spec allows for omitting spaces around
- //infix operators, >, ~ and +
- //Do the work here since detection for spaces is used as a simple "not use QSA"
- //test below.
- query = query.replace(attRe, attFunc);
- if(qsaAvail){
- // if we've got a cached variant and we think we can do it, run it!
- var qsaCached = _queryFuncCacheQSA[query];
- if(qsaCached && !forceDOM){ return qsaCached; }
- }
- // else if we've got a DOM cached variant, assume that we already know
- // all we need to and use it
- var domCached = _queryFuncCacheDOM[query];
- if(domCached){ return domCached; }
- // TODO:
- // today we're caching DOM and QSA branches separately so we
- // recalc useQSA every time. If we had a way to tag root+query
- // efficiently, we'd be in good shape to do a global cache.
- var qcz = query.charAt(0);
- var nospace = (-1 == query.indexOf(" "));
- // byId searches are wicked fast compared to QSA, even when filtering
- // is required
- if( (query.indexOf("#") >= 0) && (nospace) ){
- forceDOM = true;
- }
- var useQSA = (
- qsaAvail && (!forceDOM) &&
- // as per CSS 3, we can't currently start w/ combinator:
- // http://www.w3.org/TR/css3-selectors/#w3cselgrammar
- (specials.indexOf(qcz) == -1) &&
- // IE's QSA impl sucks on pseudos
- (!has("ie") || (query.indexOf(":") == -1)) &&
- (!(cssCaseBug && (query.indexOf(".") >= 0))) &&
- // FIXME:
- // need to tighten up browser rules on ":contains" and "|=" to
- // figure out which aren't good
- // Latest webkit (around 531.21.8) does not seem to do well with :checked on option
- // elements, even though according to spec, selected options should
- // match :checked. So go nonQSA for it:
- // http://bugs.dojotoolkit.org/ticket/5179
- (query.indexOf(":contains") == -1) && (query.indexOf(":checked") == -1) &&
- (query.indexOf("|=") == -1) // some browsers don't grok it
- );
- // TODO:
- // if we've got a descendant query (e.g., "> .thinger" instead of
- // just ".thinger") in a QSA-able doc, but are passed a child as a
- // root, it should be possible to give the item a synthetic ID and
- // trivially rewrite the query to the form "#synid > .thinger" to
- // use the QSA branch
- if(useQSA){
- var tq = (specials.indexOf(query.charAt(query.length-1)) >= 0) ?
- (query + " *") : query;
- return _queryFuncCacheQSA[query] = function(root){
- try{
- // the QSA system contains an egregious spec bug which
- // limits us, effectively, to only running QSA queries over
- // entire documents. See:
- // http://ejohn.org/blog/thoughts-on-queryselectorall/
- // despite this, we can also handle QSA runs on simple
- // selectors, but we don't want detection to be expensive
- // so we're just checking for the presence of a space char
- // right now. Not elegant, but it's cheaper than running
- // the query parser when we might not need to
- if(!((9 == root.nodeType) || nospace)){ throw ""; }
- var r = root[qsa](tq);
- // skip expensive duplication checks and just wrap in a NodeList
- r[noZip] = true;
- return r;
- }catch(e){
- // else run the DOM branch on this query, ensuring that we
- // default that way in the future
- return getQueryFunc(query, true)(root);
- }
- };
- }else{
- // DOM branch
- var parts = query.match(/([^\s,](?:"(?:\\.|[^"])+"|'(?:\\.|[^'])+'|[^,])*)/g);
- return _queryFuncCacheDOM[query] = ((parts.length < 2) ?
- // if not a compound query (e.g., ".foo, .bar"), cache and return a dispatcher
- getStepQueryFunc(query) :
- // if it *is* a complex query, break it up into its
- // constituent parts and return a dispatcher that will
- // merge the parts when run
- function(root){
- var pindex = 0, // avoid array alloc for every invocation
- ret = [],
- tp;
- while((tp = parts[pindex++])){
- ret = ret.concat(getStepQueryFunc(tp)(root));
- }
- return ret;
- }
- );
- }
- };
- var _zipIdx = 0;
- // NOTE:
- // this function is Moo inspired, but our own impl to deal correctly
- // with XML in IE
- var _nodeUID = has("ie") ? function(node){
- if(caseSensitive){
- // XML docs don't have uniqueID on their nodes
- return (node.getAttribute("_uid") || node.setAttribute("_uid", ++_zipIdx) || _zipIdx);
- }else{
- return node.uniqueID;
- }
- } :
- function(node){
- return (node._uid || (node._uid = ++_zipIdx));
- };
- // determine if a node in is unique in a "bag". In this case we don't want
- // to flatten a list of unique items, but rather just tell if the item in
- // question is already in the bag. Normally we'd just use hash lookup to do
- // this for us but IE's DOM is busted so we can't really count on that. On
- // the upside, it gives us a built in unique ID function.
- var _isUnique = function(node, bag){
- if(!bag){ return 1; }
- var id = _nodeUID(node);
- if(!bag[id]){ return bag[id] = 1; }
- return 0;
- };
- // attempt to efficiently determine if an item in a list is a dupe,
- // returning a list of "uniques", hopefully in document order
- var _zipIdxName = "_zipIdx";
- var _zip = function(arr){
- if(arr && arr.nozip){
- return arr;
- }
- var ret = [];
- if(!arr || !arr.length){ return ret; }
- if(arr[0]){
- ret.push(arr[0]);
- }
- if(arr.length < 2){ return ret; }
- _zipIdx++;
- // we have to fork here for IE and XML docs because we can't set
- // expandos on their nodes (apparently). *sigh*
- var x, te;
- if(has("ie") && caseSensitive){
- var szidx = _zipIdx+"";
- arr[0].setAttribute(_zipIdxName, szidx);
- for(x = 1; te = arr[x]; x++){
- if(arr[x].getAttribute(_zipIdxName) != szidx){
- ret.push(te);
- }
- te.setAttribute(_zipIdxName, szidx);
- }
- }else if(has("ie") && arr.commentStrip){
- try{
- for(x = 1; te = arr[x]; x++){
- if(_isElement(te)){
- ret.push(te);
- }
- }
- }catch(e){ /* squelch */ }
- }else{
- if(arr[0]){ arr[0][_zipIdxName] = _zipIdx; }
- for(x = 1; te = arr[x]; x++){
- if(arr[x][_zipIdxName] != _zipIdx){
- ret.push(te);
- }
- te[_zipIdxName] = _zipIdx;
- }
- }
- return ret;
- };
- // the main executor
- var query = function(/*String*/ query, /*String|DOMNode?*/ root){
- // summary:
- // Returns nodes which match the given CSS3 selector, searching the
- // entire document by default but optionally taking a node to scope
- // the search by. Returns an array.
- // description:
- // dojo.query() is the swiss army knife of DOM node manipulation in
- // Dojo. Much like Prototype's "$$" (bling-bling) function or JQuery's
- // "$" function, dojo.query provides robust, high-performance
- // CSS-based node selector support with the option of scoping searches
- // to a particular sub-tree of a document.
- //
- // Supported Selectors:
- // --------------------
- //
- // acme supports a rich set of CSS3 selectors, including:
- //
- // - class selectors (e.g., `.foo`)
- // - node type selectors like `span`
- // - ` ` descendant selectors
- // - `>` child element selectors
- // - `#foo` style ID selectors
- // - `*` universal selector
- // - `~`, the preceded-by sibling selector
- // - `+`, the immediately preceded-by sibling selector
- // - attribute queries:
- // - `[foo]` attribute presence selector
- // - `[foo='bar']` attribute value exact match
- // - `[foo~='bar']` attribute value list item match
- // - `[foo^='bar']` attribute start match
- // - `[foo$='bar']` attribute end match
- // - `[foo*='bar']` attribute substring match
- // - `:first-child`, `:last-child`, and `:only-child` positional selectors
- // - `:empty` content emtpy selector
- // - `:checked` pseudo selector
- // - `:nth-child(n)`, `:nth-child(2n+1)` style positional calculations
- // - `:nth-child(even)`, `:nth-child(odd)` positional selectors
- // - `:not(...)` negation pseudo selectors
- //
- // Any legal combination of these selectors will work with
- // `dojo.query()`, including compound selectors ("," delimited).
- // Very complex and useful searches can be constructed with this
- // palette of selectors and when combined with functions for
- // manipulation presented by dojo/NodeList, many types of DOM
- // manipulation operations become very straightforward.
- //
- // Unsupported Selectors:
- // ----------------------
- //
- // While dojo.query handles many CSS3 selectors, some fall outside of
- // what's reasonable for a programmatic node querying engine to
- // handle. Currently unsupported selectors include:
- //
- // - namespace-differentiated selectors of any form
- // - all `::` pseduo-element selectors
- // - certain pseudo-selectors which don't get a lot of day-to-day use:
- // - `:root`, `:lang()`, `:target`, `:focus`
- // - all visual and state selectors:
- // - `:root`, `:active`, `:hover`, `:visited`, `:link`,
- // `:enabled`, `:disabled`
- // - `:*-of-type` pseudo selectors
- //
- // dojo.query and XML Documents:
- // -----------------------------
- //
- // `dojo.query` (as of dojo 1.2) supports searching XML documents
- // in a case-sensitive manner. If an HTML document is served with
- // a doctype that forces case-sensitivity (e.g., XHTML 1.1
- // Strict), dojo.query() will detect this and "do the right
- // thing". Case sensitivity is dependent upon the document being
- // searched and not the query used. It is therefore possible to
- // use case-sensitive queries on strict sub-documents (iframes,
- // etc.) or XML documents while still assuming case-insensitivity
- // for a host/root document.
- //
- // Non-selector Queries:
- // ---------------------
- //
- // If something other than a String is passed for the query,
- // `dojo.query` will return a new `dojo/NodeList` instance
- // constructed from that parameter alone and all further
- // processing will stop. This means that if you have a reference
- // to a node or NodeList, you can quickly construct a new NodeList
- // from the original by calling `dojo.query(node)` or
- // `dojo.query(list)`.
- //
- // query:
- // The CSS3 expression to match against. For details on the syntax of
- // CSS3 selectors, see <http://www.w3.org/TR/css3-selectors/#selectors>
- // root:
- // A DOMNode (or node id) to scope the search from. Optional.
- // returns: Array
- // example:
- // search the entire document for elements with the class "foo":
- // | dojo.query(".foo");
- // these elements will match:
- // | <span class="foo"></span>
- // | <span class="foo bar"></span>
- // | <p class="thud foo"></p>
- // example:
- // search the entire document for elements with the classes "foo" *and* "bar":
- // | dojo.query(".foo.bar");
- // these elements will match:
- // | <span class="foo bar"></span>
- // while these will not:
- // | <span class="foo"></span>
- // | <p class="thud foo"></p>
- // example:
- // find `<span>` elements which are descendants of paragraphs and
- // which have a "highlighted" class:
- // | dojo.query("p span.highlighted");
- // the innermost span in this fragment matches:
- // | <p class="foo">
- // | <span>...
- // | <span class="highlighted foo bar">...</span>
- // | </span>
- // | </p>
- // example:
- // set an "odd" class on all odd table rows inside of the table
- // `#tabular_data`, using the `>` (direct child) selector to avoid
- // affecting any nested tables:
- // | dojo.query("#tabular_data > tbody > tr:nth-child(odd)").addClass("odd");
- // example:
- // remove all elements with the class "error" from the document
- // and store them in a list:
- // | var errors = dojo.query(".error").orphan();
- // example:
- // add an onclick handler to every submit button in the document
- // which causes the form to be sent via Ajax instead:
- // | dojo.query("input[type='submit']").onclick(function(e){
- // | dojo.stopEvent(e); // prevent sending the form
- // | var btn = e.target;
- // | dojo.xhrPost({
- // | form: btn.form,
- // | load: function(data){
- // | // replace the form with the response
- // | var div = dojo.doc.createElement("div");
- // | dojo.place(div, btn.form, "after");
- // | div.innerHTML = data;
- // | dojo.style(btn.form, "display", "none");
- // | }
- // | });
- // | });
- root = root || getDoc();
- // throw the big case sensitivity switch
- var od = root.ownerDocument || root; // root is either Document or a node inside the document
- caseSensitive = (od.createElement("div").tagName === "div");
- // NOTE:
- // adding "true" as the 2nd argument to getQueryFunc is useful for
- // testing the DOM branch without worrying about the
- // behavior/performance of the QSA branch.
- var r = getQueryFunc(query)(root);
- // FIXME:
- // need to investigate this branch WRT #8074 and #8075
- if(r && r.nozip){
- return r;
- }
- return _zip(r); // dojo/NodeList
- };
- query.filter = function(/*Node[]*/ nodeList, /*String*/ filter, /*String|DOMNode?*/ root){
- // summary:
- // function for filtering a NodeList based on a selector, optimized for simple selectors
- var tmpNodeList = [],
- parts = getQueryParts(filter),
- filterFunc =
- (parts.length == 1 && !/[^\w#\.]/.test(filter)) ?
- getSimpleFilterFunc(parts[0]) :
- function(node){
- return array.indexOf(query(filter, dom.byId(root)), node) != -1;
- };
- for(var x = 0, te; te = nodeList[x]; x++){
- if(filterFunc(te)){ tmpNodeList.push(te); }
- }
- return tmpNodeList;
- };
- return query;
- });
- },
- 'dojo/errors/RequestTimeoutError':function(){
- define("dojo/errors/RequestTimeoutError", ['./create', './RequestError'], function(create, RequestError){
- // module:
- // dojo/errors/RequestTimeoutError
- /*=====
- return function(){
- // summary:
- // TODOC
- };
- =====*/
- return create("RequestTimeoutError", null, RequestError, {
- dojoType: "timeout"
- });
- });
- },
- 'dojo/dom-style':function(){
- define("dojo/dom-style", ["./sniff", "./dom"], function(has, dom){
- // module:
- // dojo/dom-style
- // =============================
- // Style Functions
- // =============================
- // getComputedStyle drives most of the style code.
- // Wherever possible, reuse the returned object.
- //
- // API functions below that need to access computed styles accept an
- // optional computedStyle parameter.
- // If this parameter is omitted, the functions will call getComputedStyle themselves.
- // This way, calling code can access computedStyle once, and then pass the reference to
- // multiple API functions.
- // Although we normally eschew argument validation at this
- // level, here we test argument 'node' for (duck)type,
- // by testing nodeType, ecause 'document' is the 'parentNode' of 'body'
- // it is frequently sent to this function even
- // though it is not Element.
- var getComputedStyle, style = {
- // summary:
- // This module defines the core dojo DOM style API.
- };
- if(has("webkit")){
- getComputedStyle = function(/*DomNode*/ node){
- var s;
- if(node.nodeType == 1){
- var dv = node.ownerDocument.defaultView;
- s = dv.getComputedStyle(node, null);
- if(!s && node.style){
- node.style.display = "";
- s = dv.getComputedStyle(node, null);
- }
- }
- return s || {};
- };
- }else if(has("ie") && (has("ie") < 9 || has("quirks"))){
- getComputedStyle = function(node){
- // IE (as of 7) doesn't expose Element like sane browsers
- // currentStyle can be null on IE8!
- return node.nodeType == 1 /* ELEMENT_NODE*/ && node.currentStyle ? node.currentStyle : {};
- };
- }else{
- getComputedStyle = function(node){
- return node.nodeType == 1 /* ELEMENT_NODE*/ ?
- node.ownerDocument.defaultView.getComputedStyle(node, null) : {};
- };
- }
- style.getComputedStyle = getComputedStyle;
- /*=====
- style.getComputedStyle = function(node){
- // summary:
- // Returns a "computed style" object.
- //
- // description:
- // Gets a "computed style" object which can be used to gather
- // information about the current state of the rendered node.
- //
- // Note that this may behave differently on different browsers.
- // Values may have different formats and value encodings across
- // browsers.
- //
- // Note also that this method is expensive. Wherever possible,
- // reuse the returned object.
- //
- // Use the dojo.style() method for more consistent (pixelized)
- // return values.
- //
- // node: DOMNode
- // A reference to a DOM node. Does NOT support taking an
- // ID string for speed reasons.
- // example:
- // | dojo.getComputedStyle(dojo.byId('foo')).borderWidth;
- //
- // example:
- // Reusing the returned object, avoiding multiple lookups:
- // | var cs = dojo.getComputedStyle(dojo.byId("someNode"));
- // | var w = cs.width, h = cs.height;
- return; // CSS2Properties
- };
- =====*/
- var toPixel;
- if(!has("ie")){
- toPixel = function(element, value){
- // style values can be floats, client code may want
- // to round for integer pixels.
- return parseFloat(value) || 0;
- };
- }else{
- toPixel = function(element, avalue){
- if(!avalue){ return 0; }
- // on IE7, medium is usually 4 pixels
- if(avalue == "medium"){ return 4; }
- // style values can be floats, client code may
- // want to round this value for integer pixels.
- if(avalue.slice && avalue.slice(-2) == 'px'){ return parseFloat(avalue); }
- var s = element.style, rs = element.runtimeStyle, cs = element.currentStyle,
- sLeft = s.left, rsLeft = rs.left;
- rs.left = cs.left;
- try{
- // 'avalue' may be incompatible with style.left, which can cause IE to throw
- // this has been observed for border widths using "thin", "medium", "thick" constants
- // those particular constants could be trapped by a lookup
- // but perhaps there are more
- s.left = avalue;
- avalue = s.pixelLeft;
- }catch(e){
- avalue = 0;
- }
- s.left = sLeft;
- rs.left = rsLeft;
- return avalue;
- };
- }
- style.toPixelValue = toPixel;
- /*=====
- style.toPixelValue = function(node, value){
- // summary:
- // converts style value to pixels on IE or return a numeric value.
- // node: DOMNode
- // value: String
- // returns: Number
- };
- =====*/
- // FIXME: there opacity quirks on FF that we haven't ported over. Hrm.
- var astr = "DXImageTransform.Microsoft.Alpha";
- var af = function(n, f){
- try{
- return n.filters.item(astr);
- }catch(e){
- return f ? {} : null;
- }
- };
- var _getOpacity =
- has("ie") < 9 || (has("ie") && has("quirks")) ? function(node){
- try{
- return af(node).Opacity / 100; // Number
- }catch(e){
- return 1; // Number
- }
- } :
- function(node){
- return getComputedStyle(node).opacity;
- };
- var _setOpacity =
- has("ie") < 9 || (has("ie") && has("quirks")) ? function(/*DomNode*/ node, /*Number*/ opacity){
- var ov = opacity * 100, opaque = opacity == 1;
- node.style.zoom = opaque ? "" : 1;
- if(!af(node)){
- if(opaque){
- return opacity;
- }
- node.style.filter += " progid:" + astr + "(Opacity=" + ov + ")";
- }else{
- af(node, 1).Opacity = ov;
- }
- // on IE7 Alpha(Filter opacity=100) makes text look fuzzy so disable it altogether (bug #2661),
- //but still update the opacity value so we can get a correct reading if it is read later.
- af(node, 1).Enabled = !opaque;
- if(node.tagName.toLowerCase() == "tr"){
- for(var td = node.firstChild; td; td = td.nextSibling){
- if(td.tagName.toLowerCase() == "td"){
- _setOpacity(td, opacity);
- }
- }
- }
- return opacity;
- } :
- function(node, opacity){
- return node.style.opacity = opacity;
- };
- var _pixelNamesCache = {
- left: true, top: true
- };
- var _pixelRegExp = /margin|padding|width|height|max|min|offset/; // |border
- function _toStyleValue(node, type, value){
- //TODO: should we really be doing string case conversion here? Should we cache it? Need to profile!
- type = type.toLowerCase();
- if(has("ie")){
- if(value == "auto"){
- if(type == "height"){ return node.offsetHeight; }
- if(type == "width"){ return node.offsetWidth; }
- }
- if(type == "fontweight"){
- switch(value){
- case 700: return "bold";
- case 400:
- default: return "normal";
- }
- }
- }
- if(!(type in _pixelNamesCache)){
- _pixelNamesCache[type] = _pixelRegExp.test(type);
- }
- return _pixelNamesCache[type] ? toPixel(node, value) : value;
- }
- var _floatStyle = has("ie") ? "styleFloat" : "cssFloat",
- _floatAliases = {"cssFloat": _floatStyle, "styleFloat": _floatStyle, "float": _floatStyle};
- // public API
- style.get = function getStyle(/*DOMNode|String*/ node, /*String?*/ name){
- // summary:
- // Accesses styles on a node.
- // description:
- // Getting the style value uses the computed style for the node, so the value
- // will be a calculated value, not just the immediate node.style value.
- // Also when getting values, use specific style names,
- // like "borderBottomWidth" instead of "border" since compound values like
- // "border" are not necessarily reflected as expected.
- // If you want to get node dimensions, use `dojo.marginBox()`,
- // `dojo.contentBox()` or `dojo.position()`.
- // node: DOMNode|String
- // id or reference to node to get style for
- // name: String?
- // the style property to get
- // example:
- // Passing only an ID or node returns the computed style object of
- // the node:
- // | dojo.getStyle("thinger");
- // example:
- // Passing a node and a style property returns the current
- // normalized, computed value for that property:
- // | dojo.getStyle("thinger", "opacity"); // 1 by default
- var n = dom.byId(node), l = arguments.length, op = (name == "opacity");
- if(l == 2 && op){
- return _getOpacity(n);
- }
- name = _floatAliases[name] || name;
- var s = style.getComputedStyle(n);
- return (l == 1) ? s : _toStyleValue(n, name, s[name] || n.style[name]); /* CSS2Properties||String||Number */
- };
- style.set = function setStyle(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){
- // summary:
- // Sets styles on a node.
- // node: DOMNode|String
- // id or reference to node to set style for
- // name: String|Object
- // the style property to set in DOM-accessor format
- // ("borderWidth", not "border-width") or an object with key/value
- // pairs suitable for setting each property.
- // value: String?
- // If passed, sets value on the node for style, handling
- // cross-browser concerns. When setting a pixel value,
- // be sure to include "px" in the value. For instance, top: "200px".
- // Otherwise, in some cases, some browsers will not apply the style.
- //
- // example:
- // Passing a node, a style property, and a value changes the
- // current display of the node and returns the new computed value
- // | dojo.setStyle("thinger", "opacity", 0.5); // == 0.5
- //
- // example:
- // Passing a node, an object-style style property sets each of the values in turn and returns the computed style object of the node:
- // | dojo.setStyle("thinger", {
- // | "opacity": 0.5,
- // | "border": "3px solid black",
- // | "height": "300px"
- // | });
- //
- // example:
- // When the CSS style property is hyphenated, the JavaScript property is camelCased.
- // font-size becomes fontSize, and so on.
- // | dojo.setStyle("thinger",{
- // | fontSize:"14pt",
- // | letterSpacing:"1.2em"
- // | });
- //
- // example:
- // dojo/NodeList implements .style() using the same syntax, omitting the "node" parameter, calling
- // dojo.style() on every element of the list. See: `dojo.query()` and `dojo/NodeList`
- // | dojo.query(".someClassName").style("visibility","hidden");
- // | // or
- // | dojo.query("#baz > div").style({
- // | opacity:0.75,
- // | fontSize:"13pt"
- // | });
- var n = dom.byId(node), l = arguments.length, op = (name == "opacity");
- name = _floatAliases[name] || name;
- if(l == 3){
- return op ? _setOpacity(n, value) : n.style[name] = value; // Number
- }
- for(var x in name){
- style.set(node, x, name[x]);
- }
- return style.getComputedStyle(n);
- };
- return style;
- });
- },
- 'dojo/dom-geometry':function(){
- define(["./sniff", "./_base/window","./dom", "./dom-style"],
- function(has, win, dom, style){
- // module:
- // dojo/dom-geometry
- // the result object
- var geom = {
- // summary:
- // This module defines the core dojo DOM geometry API.
- };
- // Box functions will assume this model.
- // On IE/Opera, BORDER_BOX will be set if the primary document is in quirks mode.
- // Can be set to change behavior of box setters.
- // can be either:
- // "border-box"
- // "content-box" (default)
- geom.boxModel = "content-box";
- // We punt per-node box mode testing completely.
- // If anybody cares, we can provide an additional (optional) unit
- // that overrides existing code to include per-node box sensitivity.
- // Opera documentation claims that Opera 9 uses border-box in BackCompat mode.
- // but experiments (Opera 9.10.8679 on Windows Vista) indicate that it actually continues to use content-box.
- // IIRC, earlier versions of Opera did in fact use border-box.
- // Opera guys, this is really confusing. Opera being broken in quirks mode is not our fault.
- if(has("ie") /*|| has("opera")*/){
- // client code may have to adjust if compatMode varies across iframes
- geom.boxModel = document.compatMode == "BackCompat" ? "border-box" : "content-box";
- }
- geom.getPadExtents = function getPadExtents(/*DomNode*/ node, /*Object*/ computedStyle){
- // summary:
- // Returns object with special values specifically useful for node
- // fitting.
- // description:
- // Returns an object with `w`, `h`, `l`, `t` properties:
- // | l/t/r/b = left/top/right/bottom padding (respectively)
- // | w = the total of the left and right padding
- // | h = the total of the top and bottom padding
- // If 'node' has position, l/t forms the origin for child nodes.
- // The w/h are used for calculating boxes.
- // Normally application code will not need to invoke this
- // directly, and will use the ...box... functions instead.
- // node: DOMNode
- // computedStyle: Object?
- // This parameter accepts computed styles object.
- // If this parameter is omitted, the functions will call
- // dojo.getComputedStyle to get one. It is a better way, calling
- // dojo.computedStyle once, and then pass the reference to this
- // computedStyle parameter. Wherever possible, reuse the returned
- // object of dojo/dom-style.getComputedStyle().
- node = dom.byId(node);
- var s = computedStyle || style.getComputedStyle(node), px = style.toPixelValue,
- l = px(node, s.paddingLeft), t = px(node, s.paddingTop), r = px(node, s.paddingRight), b = px(node, s.paddingBottom);
- return {l: l, t: t, r: r, b: b, w: l + r, h: t + b};
- };
- var none = "none";
- geom.getBorderExtents = function getBorderExtents(/*DomNode*/ node, /*Object*/ computedStyle){
- // summary:
- // returns an object with properties useful for noting the border
- // dimensions.
- // description:
- // - l/t/r/b = the sum of left/top/right/bottom border (respectively)
- // - w = the sum of the left and right border
- // - h = the sum of the top and bottom border
- //
- // The w/h are used for calculating boxes.
- // Normally application code will not need to invoke this
- // directly, and will use the ...box... functions instead.
- // node: DOMNode
- // computedStyle: Object?
- // This parameter accepts computed styles object.
- // If this parameter is omitted, the functions will call
- // dojo.getComputedStyle to get one. It is a better way, calling
- // dojo.computedStyle once, and then pass the reference to this
- // computedStyle parameter. Wherever possible, reuse the returned
- // object of dojo/dom-style.getComputedStyle().
- node = dom.byId(node);
- var px = style.toPixelValue, s = computedStyle || style.getComputedStyle(node),
- l = s.borderLeftStyle != none ? px(node, s.borderLeftWidth) : 0,
- t = s.borderTopStyle != none ? px(node, s.borderTopWidth) : 0,
- r = s.borderRightStyle != none ? px(node, s.borderRightWidth) : 0,
- b = s.borderBottomStyle != none ? px(node, s.borderBottomWidth) : 0;
- return {l: l, t: t, r: r, b: b, w: l + r, h: t + b};
- };
- geom.getPadBorderExtents = function getPadBorderExtents(/*DomNode*/ node, /*Object*/ computedStyle){
- // summary:
- // Returns object with properties useful for box fitting with
- // regards to padding.
- // description:
- // - l/t/r/b = the sum of left/top/right/bottom padding and left/top/right/bottom border (respectively)
- // - w = the sum of the left and right padding and border
- // - h = the sum of the top and bottom padding and border
- //
- // The w/h are used for calculating boxes.
- // Normally application code will not need to invoke this
- // directly, and will use the ...box... functions instead.
- // node: DOMNode
- // computedStyle: Object?
- // This parameter accepts computed styles object.
- // If this parameter is omitted, the functions will call
- // dojo.getComputedStyle to get one. It is a better way, calling
- // dojo.computedStyle once, and then pass the reference to this
- // computedStyle parameter. Wherever possible, reuse the returned
- // object of dojo/dom-style.getComputedStyle().
- node = dom.byId(node);
- var s = computedStyle || style.getComputedStyle(node),
- p = geom.getPadExtents(node, s),
- b = geom.getBorderExtents(node, s);
- return {
- l: p.l + b.l,
- t: p.t + b.t,
- r: p.r + b.r,
- b: p.b + b.b,
- w: p.w + b.w,
- h: p.h + b.h
- };
- };
- geom.getMarginExtents = function getMarginExtents(node, computedStyle){
- // summary:
- // returns object with properties useful for box fitting with
- // regards to box margins (i.e., the outer-box).
- //
- // - l/t = marginLeft, marginTop, respectively
- // - w = total width, margin inclusive
- // - h = total height, margin inclusive
- //
- // The w/h are used for calculating boxes.
- // Normally application code will not need to invoke this
- // directly, and will use the ...box... functions instead.
- // node: DOMNode
- // computedStyle: Object?
- // This parameter accepts computed styles object.
- // If this parameter is omitted, the functions will call
- // dojo.getComputedStyle to get one. It is a better way, calling
- // dojo.computedStyle once, and then pass the reference to this
- // computedStyle parameter. Wherever possible, reuse the returned
- // object of dojo/dom-style.getComputedStyle().
- node = dom.byId(node);
- var s = computedStyle || style.getComputedStyle(node), px = style.toPixelValue,
- l = px(node, s.marginLeft), t = px(node, s.marginTop), r = px(node, s.marginRight), b = px(node, s.marginBottom);
- return {l: l, t: t, r: r, b: b, w: l + r, h: t + b};
- };
- // Box getters work in any box context because offsetWidth/clientWidth
- // are invariant wrt box context
- //
- // They do *not* work for display: inline objects that have padding styles
- // because the user agent ignores padding (it's bogus styling in any case)
- //
- // Be careful with IMGs because they are inline or block depending on
- // browser and browser mode.
- // Although it would be easier to read, there are not separate versions of
- // _getMarginBox for each browser because:
- // 1. the branching is not expensive
- // 2. factoring the shared code wastes cycles (function call overhead)
- // 3. duplicating the shared code wastes bytes
- geom.getMarginBox = function getMarginBox(/*DomNode*/ node, /*Object*/ computedStyle){
- // summary:
- // returns an object that encodes the width, height, left and top
- // positions of the node's margin box.
- // node: DOMNode
- // computedStyle: Object?
- // This parameter accepts computed styles object.
- // If this parameter is omitted, the functions will call
- // dojo.getComputedStyle to get one. It is a better way, calling
- // dojo.computedStyle once, and then pass the reference to this
- // computedStyle parameter. Wherever possible, reuse the returned
- // object of dojo/dom-style.getComputedStyle().
- node = dom.byId(node);
- var s = computedStyle || style.getComputedStyle(node), me = geom.getMarginExtents(node, s),
- l = node.offsetLeft - me.l, t = node.offsetTop - me.t, p = node.parentNode, px = style.toPixelValue, pcs;
- if(has("mozilla")){
- // Mozilla:
- // If offsetParent has a computed overflow != visible, the offsetLeft is decreased
- // by the parent's border.
- // We don't want to compute the parent's style, so instead we examine node's
- // computed left/top which is more stable.
- var sl = parseFloat(s.left), st = parseFloat(s.top);
- if(!isNaN(sl) && !isNaN(st)){
- l = sl;
- t = st;
- }else{
- // If child's computed left/top are not parseable as a number (e.g. "auto"), we
- // have no choice but to examine the parent's computed style.
- if(p && p.style){
- pcs = style.getComputedStyle(p);
- if(pcs.overflow != "visible"){
- l += pcs.borderLeftStyle != none ? px(node, pcs.borderLeftWidth) : 0;
- t += pcs.borderTopStyle != none ? px(node, pcs.borderTopWidth) : 0;
- }
- }
- }
- }else if(has("opera") || (has("ie") == 8 && !has("quirks"))){
- // On Opera and IE 8, offsetLeft/Top includes the parent's border
- if(p){
- pcs = style.getComputedStyle(p);
- l -= pcs.borderLeftStyle != none ? px(node, pcs.borderLeftWidth) : 0;
- t -= pcs.borderTopStyle != none ? px(node, pcs.borderTopWidth) : 0;
- }
- }
- return {l: l, t: t, w: node.offsetWidth + me.w, h: node.offsetHeight + me.h};
- };
- geom.getContentBox = function getContentBox(node, computedStyle){
- // summary:
- // Returns an object that encodes the width, height, left and top
- // positions of the node's content box, irrespective of the
- // current box model.
- // node: DOMNode
- // computedStyle: Object?
- // This parameter accepts computed styles object.
- // If this parameter is omitted, the functions will call
- // dojo.getComputedStyle to get one. It is a better way, calling
- // dojo.computedStyle once, and then pass the reference to this
- // computedStyle parameter. Wherever possible, reuse the returned
- // object of dojo/dom-style.getComputedStyle().
- // clientWidth/Height are important since the automatically account for scrollbars
- // fallback to offsetWidth/Height for special cases (see #3378)
- node = dom.byId(node);
- var s = computedStyle || style.getComputedStyle(node), w = node.clientWidth, h,
- pe = geom.getPadExtents(node, s), be = geom.getBorderExtents(node, s);
- if(!w){
- w = node.offsetWidth;
- h = node.offsetHeight;
- }else{
- h = node.clientHeight;
- be.w = be.h = 0;
- }
- // On Opera, offsetLeft includes the parent's border
- if(has("opera")){
- pe.l += be.l;
- pe.t += be.t;
- }
- return {l: pe.l, t: pe.t, w: w - pe.w - be.w, h: h - pe.h - be.h};
- };
- // Box setters depend on box context because interpretation of width/height styles
- // vary wrt box context.
- //
- // The value of boxModel is used to determine box context.
- // boxModel can be set directly to change behavior.
- //
- // Beware of display: inline objects that have padding styles
- // because the user agent ignores padding (it's a bogus setup anyway)
- //
- // Be careful with IMGs because they are inline or block depending on
- // browser and browser mode.
- //
- // Elements other than DIV may have special quirks, like built-in
- // margins or padding, or values not detectable via computedStyle.
- // In particular, margins on TABLE do not seems to appear
- // at all in computedStyle on Mozilla.
- function setBox(/*DomNode*/ node, /*Number?*/ l, /*Number?*/ t, /*Number?*/ w, /*Number?*/ h, /*String?*/ u){
- // summary:
- // sets width/height/left/top in the current (native) box-model
- // dimensions. Uses the unit passed in u.
- // node:
- // DOM Node reference. Id string not supported for performance
- // reasons.
- // l:
- // left offset from parent.
- // t:
- // top offset from parent.
- // w:
- // width in current box model.
- // h:
- // width in current box model.
- // u:
- // unit measure to use for other measures. Defaults to "px".
- u = u || "px";
- var s = node.style;
- if(!isNaN(l)){
- s.left = l + u;
- }
- if(!isNaN(t)){
- s.top = t + u;
- }
- if(w >= 0){
- s.width = w + u;
- }
- if(h >= 0){
- s.height = h + u;
- }
- }
- function isButtonTag(/*DomNode*/ node){
- // summary:
- // True if the node is BUTTON or INPUT.type="button".
- return node.tagName.toLowerCase() == "button" ||
- node.tagName.toLowerCase() == "input" && (node.getAttribute("type") || "").toLowerCase() == "button"; // boolean
- }
- function usesBorderBox(/*DomNode*/ node){
- // summary:
- // True if the node uses border-box layout.
- // We could test the computed style of node to see if a particular box
- // has been specified, but there are details and we choose not to bother.
- // TABLE and BUTTON (and INPUT type=button) are always border-box by default.
- // If you have assigned a different box to either one via CSS then
- // box functions will break.
- return geom.boxModel == "border-box" || node.tagName.toLowerCase() == "table" || isButtonTag(node); // boolean
- }
- geom.setContentSize = function setContentSize(/*DomNode*/ node, /*Object*/ box, /*Object*/ computedStyle){
- // summary:
- // Sets the size of the node's contents, irrespective of margins,
- // padding, or borders.
- // node: DOMNode
- // box: Object
- // hash with optional "w", and "h" properties for "width", and "height"
- // respectively. All specified properties should have numeric values in whole pixels.
- // computedStyle: Object?
- // This parameter accepts computed styles object.
- // If this parameter is omitted, the functions will call
- // dojo.getComputedStyle to get one. It is a better way, calling
- // dojo.computedStyle once, and then pass the reference to this
- // computedStyle parameter. Wherever possible, reuse the returned
- // object of dojo/dom-style.getComputedStyle().
- node = dom.byId(node);
- var w = box.w, h = box.h;
- if(usesBorderBox(node)){
- var pb = geom.getPadBorderExtents(node, computedStyle);
- if(w >= 0){
- w += pb.w;
- }
- if(h >= 0){
- h += pb.h;
- }
- }
- setBox(node, NaN, NaN, w, h);
- };
- var nilExtents = {l: 0, t: 0, w: 0, h: 0};
- geom.setMarginBox = function setMarginBox(/*DomNode*/ node, /*Object*/ box, /*Object*/ computedStyle){
- // summary:
- // sets the size of the node's margin box and placement
- // (left/top), irrespective of box model. Think of it as a
- // passthrough to setBox that handles box-model vagaries for
- // you.
- // node: DOMNode
- // box: Object
- // hash with optional "l", "t", "w", and "h" properties for "left", "right", "width", and "height"
- // respectively. All specified properties should have numeric values in whole pixels.
- // computedStyle: Object?
- // This parameter accepts computed styles object.
- // If this parameter is omitted, the functions will call
- // dojo.getComputedStyle to get one. It is a better way, calling
- // dojo.computedStyle once, and then pass the reference to this
- // computedStyle parameter. Wherever possible, reuse the returned
- // object of dojo/dom-style.getComputedStyle().
- node = dom.byId(node);
- var s = computedStyle || style.getComputedStyle(node), w = box.w, h = box.h,
- // Some elements have special padding, margin, and box-model settings.
- // To use box functions you may need to set padding, margin explicitly.
- // Controlling box-model is harder, in a pinch you might set dojo/dom-geometry.boxModel.
- pb = usesBorderBox(node) ? nilExtents : geom.getPadBorderExtents(node, s),
- mb = geom.getMarginExtents(node, s);
- if(has("webkit")){
- // on Safari (3.1.2), button nodes with no explicit size have a default margin
- // setting an explicit size eliminates the margin.
- // We have to swizzle the width to get correct margin reading.
- if(isButtonTag(node)){
- var ns = node.style;
- if(w >= 0 && !ns.width){
- ns.width = "4px";
- }
- if(h >= 0 && !ns.height){
- ns.height = "4px";
- }
- }
- }
- if(w >= 0){
- w = Math.max(w - pb.w - mb.w, 0);
- }
- if(h >= 0){
- h = Math.max(h - pb.h - mb.h, 0);
- }
- setBox(node, box.l, box.t, w, h);
- };
- // =============================
- // Positioning
- // =============================
- geom.isBodyLtr = function isBodyLtr(/*Document?*/ doc){
- // summary:
- // Returns true if the current language is left-to-right, and false otherwise.
- // doc: Document?
- // Optional document to query. If unspecified, use win.doc.
- // returns: Boolean
- doc = doc || win.doc;
- return (win.body(doc).dir || doc.documentElement.dir || "ltr").toLowerCase() == "ltr"; // Boolean
- };
- geom.docScroll = function docScroll(/*Document?*/ doc){
- // summary:
- // Returns an object with {node, x, y} with corresponding offsets.
- // doc: Document?
- // Optional document to query. If unspecified, use win.doc.
- // returns: Object
- doc = doc || win.doc;
- var node = win.doc.parentWindow || win.doc.defaultView; // use UI window, not dojo.global window. TODO: use dojo/window::get() except for circular dependency problem
- return "pageXOffset" in node ? {x: node.pageXOffset, y: node.pageYOffset } :
- (node = has("quirks") ? win.body(doc) : doc.documentElement) &&
- {x: geom.fixIeBiDiScrollLeft(node.scrollLeft || 0, doc), y: node.scrollTop || 0 };
- };
- if(has("ie")){
- geom.getIeDocumentElementOffset = function getIeDocumentElementOffset(/*Document?*/ doc){
- // summary:
- // returns the offset in x and y from the document body to the
- // visual edge of the page for IE
- // doc: Document?
- // Optional document to query. If unspecified, use win.doc.
- // description:
- // The following values in IE contain an offset:
- // | event.clientX
- // | event.clientY
- // | node.getBoundingClientRect().left
- // | node.getBoundingClientRect().top
- // But other position related values do not contain this offset,
- // such as node.offsetLeft, node.offsetTop, node.style.left and
- // node.style.top. The offset is always (2, 2) in LTR direction.
- // When the body is in RTL direction, the offset counts the width
- // of left scroll bar's width. This function computes the actual
- // offset.
- //NOTE: assumes we're being called in an IE browser
- doc = doc || win.doc;
- var de = doc.documentElement; // only deal with HTML element here, position() handles body/quirks
- if(has("ie") < 8){
- var r = de.getBoundingClientRect(), // works well for IE6+
- l = r.left, t = r.top;
- if(has("ie") < 7){
- l += de.clientLeft; // scrollbar size in strict/RTL, or,
- t += de.clientTop; // HTML border size in strict
- }
- return {
- x: l < 0 ? 0 : l, // FRAME element border size can lead to inaccurate negative values
- y: t < 0 ? 0 : t
- };
- }else{
- return {
- x: 0,
- y: 0
- };
- }
- };
- }
- geom.fixIeBiDiScrollLeft = function fixIeBiDiScrollLeft(/*Integer*/ scrollLeft, /*Document?*/ doc){
- // summary:
- // In RTL direction, scrollLeft should be a negative value, but IE
- // returns a positive one. All codes using documentElement.scrollLeft
- // must call this function to fix this error, otherwise the position
- // will offset to right when there is a horizontal scrollbar.
- // scrollLeft: Number
- // doc: Document?
- // Optional document to query. If unspecified, use win.doc.
- // returns: Number
- // In RTL direction, scrollLeft should be a negative value, but IE
- // returns a positive one. All codes using documentElement.scrollLeft
- // must call this function to fix this error, otherwise the position
- // will offset to right when there is a horizontal scrollbar.
- doc = doc || win.doc;
- var ie = has("ie");
- if(ie && !geom.isBodyLtr(doc)){
- var qk = has("quirks"),
- de = qk ? win.body(doc) : doc.documentElement,
- pwin = win.global; // TODO: use winUtils.get(doc) after resolving circular dependency b/w dom-geometry.js and dojo/window.js
- if(ie == 6 && !qk && pwin.frameElement && de.scrollHeight > de.clientHeight){
- scrollLeft += de.clientLeft; // workaround ie6+strict+rtl+iframe+vertical-scrollbar bug where clientWidth is too small by clientLeft pixels
- }
- return (ie < 8 || qk) ? (scrollLeft + de.clientWidth - de.scrollWidth) : -scrollLeft; // Integer
- }
- return scrollLeft; // Integer
- };
- geom.position = function(/*DomNode*/ node, /*Boolean?*/ includeScroll){
- // summary:
- // Gets the position and size of the passed element relative to
- // the viewport (if includeScroll==false), or relative to the
- // document root (if includeScroll==true).
- //
- // description:
- // Returns an object of the form:
- // `{ x: 100, y: 300, w: 20, h: 15 }`.
- // If includeScroll==true, the x and y values will include any
- // document offsets that may affect the position relative to the
- // viewport.
- // Uses the border-box model (inclusive of border and padding but
- // not margin). Does not act as a setter.
- // node: DOMNode|String
- // includeScroll: Boolean?
- // returns: Object
- node = dom.byId(node);
- var db = win.body(node.ownerDocument),
- ret = node.getBoundingClientRect();
- ret = {x: ret.left, y: ret.top, w: ret.right - ret.left, h: ret.bottom - ret.top};
- if(has("ie")){
- // On IE there's a 2px offset that we need to adjust for, see dojo.getIeDocumentElementOffset()
- var offset = geom.getIeDocumentElementOffset(node.ownerDocument);
- // fixes the position in IE, quirks mode
- ret.x -= offset.x + (has("quirks") ? db.clientLeft + db.offsetLeft : 0);
- ret.y -= offset.y + (has("quirks") ? db.clientTop + db.offsetTop : 0);
- }
- // account for document scrolling
- // if offsetParent is used, ret value already includes scroll position
- // so we may have to actually remove that value if !includeScroll
- if(includeScroll){
- var scroll = geom.docScroll(node.ownerDocument);
- ret.x += scroll.x;
- ret.y += scroll.y;
- }
- return ret; // Object
- };
- // random "private" functions wildly used throughout the toolkit
- geom.getMarginSize = function getMarginSize(/*DomNode*/ node, /*Object*/ computedStyle){
- // summary:
- // returns an object that encodes the width and height of
- // the node's margin box
- // node: DOMNode|String
- // computedStyle: Object?
- // This parameter accepts computed styles object.
- // If this parameter is omitted, the functions will call
- // dojo.getComputedStyle to get one. It is a better way, calling
- // dojo.computedStyle once, and then pass the reference to this
- // computedStyle parameter. Wherever possible, reuse the returned
- // object of dojo/dom-style.getComputedStyle().
- node = dom.byId(node);
- var me = geom.getMarginExtents(node, computedStyle || style.getComputedStyle(node));
- var size = node.getBoundingClientRect();
- return {
- w: (size.right - size.left) + me.w,
- h: (size.bottom - size.top) + me.h
- };
- };
- geom.normalizeEvent = function(event){
- // summary:
- // Normalizes the geometry of a DOM event, normalizing the pageX, pageY,
- // offsetX, offsetY, layerX, and layerX properties
- // event: Object
- if(!("layerX" in event)){
- event.layerX = event.offsetX;
- event.layerY = event.offsetY;
- }
- if(!has("dom-addeventlistener")){
- // old IE version
- // FIXME: scroll position query is duped from dojo.html to
- // avoid dependency on that entire module. Now that HTML is in
- // Base, we should convert back to something similar there.
- var se = event.target;
- var doc = (se && se.ownerDocument) || document;
- // DO NOT replace the following to use dojo.body(), in IE, document.documentElement should be used
- // here rather than document.body
- var docBody = has("quirks") ? doc.body : doc.documentElement;
- var offset = geom.getIeDocumentElementOffset(doc);
- event.pageX = event.clientX + geom.fixIeBiDiScrollLeft(docBody.scrollLeft || 0, doc) - offset.x;
- event.pageY = event.clientY + (docBody.scrollTop || 0) - offset.y;
- }
- };
- // TODO: evaluate separate getters/setters for position and sizes?
- return geom;
- });
- },
- 'dojo/dom-prop':function(){
- define(["exports", "./_base/kernel", "./sniff", "./_base/lang", "./dom", "./dom-style", "./dom-construct", "./_base/connect"],
- function(exports, dojo, has, lang, dom, style, ctr, conn){
- // module:
- // dojo/dom-prop
- // summary:
- // This module defines the core dojo DOM properties API.
- // Indirectly depends on dojo.empty() and dojo.toDom().
- // TODOC: summary not showing up in output, see https://github.com/csnover/js-doc-parse/issues/42
- // =============================
- // Element properties Functions
- // =============================
- // helper to connect events
- var _evtHdlrMap = {}, _ctr = 0, _attrId = dojo._scopeName + "attrid";
- exports.names = {
- // properties renamed to avoid clashes with reserved words
- "class": "className",
- "for": "htmlFor",
- // properties written as camelCase
- tabindex: "tabIndex",
- readonly: "readOnly",
- colspan: "colSpan",
- frameborder: "frameBorder",
- rowspan: "rowSpan",
- valuetype: "valueType"
- };
- exports.get = function getProp(/*DOMNode|String*/ node, /*String*/ name){
- // summary:
- // Gets a property on an HTML element.
- // description:
- // Handles normalized getting of properties on DOM nodes.
- //
- // node: DOMNode|String
- // id or reference to the element to get the property on
- // name: String
- // the name of the property to get.
- // returns:
- // the value of the requested property or its default value
- //
- // example:
- // | // get the current value of the "foo" property on a node
- // | dojo.getProp(dojo.byId("nodeId"), "foo");
- // | // or we can just pass the id:
- // | dojo.getProp("nodeId", "foo");
- node = dom.byId(node);
- var lc = name.toLowerCase(), propName = exports.names[lc] || name;
- return node[propName]; // Anything
- };
- exports.set = function setProp(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){
- // summary:
- // Sets a property on an HTML element.
- // description:
- // Handles normalized setting of properties on DOM nodes.
- //
- // When passing functions as values, note that they will not be
- // directly assigned to slots on the node, but rather the default
- // behavior will be removed and the new behavior will be added
- // using `dojo.connect()`, meaning that event handler properties
- // will be normalized and that some caveats with regards to
- // non-standard behaviors for onsubmit apply. Namely that you
- // should cancel form submission using `dojo.stopEvent()` on the
- // passed event object instead of returning a boolean value from
- // the handler itself.
- // node: DOMNode|String
- // id or reference to the element to set the property on
- // name: String|Object
- // the name of the property to set, or a hash object to set
- // multiple properties at once.
- // value: String?
- // The value to set for the property
- // returns:
- // the DOM node
- //
- // example:
- // | // use prop() to set the tab index
- // | dojo.setProp("nodeId", "tabIndex", 3);
- // |
- //
- // example:
- // Set multiple values at once, including event handlers:
- // | dojo.setProp("formId", {
- // | "foo": "bar",
- // | "tabIndex": -1,
- // | "method": "POST",
- // | "onsubmit": function(e){
- // | // stop submitting the form. Note that the IE behavior
- // | // of returning true or false will have no effect here
- // | // since our handler is connect()ed to the built-in
- // | // onsubmit behavior and so we need to use
- // | // dojo.stopEvent() to ensure that the submission
- // | // doesn't proceed.
- // | dojo.stopEvent(e);
- // |
- // | // submit the form with Ajax
- // | dojo.xhrPost({ form: "formId" });
- // | }
- // | });
- //
- // example:
- // Style is s special case: Only set with an object hash of styles
- // | dojo.setProp("someNode",{
- // | id:"bar",
- // | style:{
- // | width:"200px", height:"100px", color:"#000"
- // | }
- // | });
- //
- // example:
- // Again, only set style as an object hash of styles:
- // | var obj = { color:"#fff", backgroundColor:"#000" };
- // | dojo.setProp("someNode", "style", obj);
- // |
- // | // though shorter to use `dojo.style()` in this case:
- // | dojo.style("someNode", obj);
- node = dom.byId(node);
- var l = arguments.length;
- if(l == 2 && typeof name != "string"){ // inline'd type check
- // the object form of setter: the 2nd argument is a dictionary
- for(var x in name){
- exports.set(node, x, name[x]);
- }
- return node; // DomNode
- }
- var lc = name.toLowerCase(), propName = exports.names[lc] || name;
- if(propName == "style" && typeof value != "string"){ // inline'd type check
- // special case: setting a style
- style.set(node, value);
- return node; // DomNode
- }
- if(propName == "innerHTML"){
- // special case: assigning HTML
- // the hash lists elements with read-only innerHTML on IE
- if(has("ie") && node.tagName.toLowerCase() in {col: 1, colgroup: 1,
- table: 1, tbody: 1, tfoot: 1, thead: 1, tr: 1, title: 1}){
- ctr.empty(node);
- node.appendChild(ctr.toDom(value, node.ownerDocument));
- }else{
- node[propName] = value;
- }
- return node; // DomNode
- }
- if(lang.isFunction(value)){
- // special case: assigning an event handler
- // clobber if we can
- var attrId = node[_attrId];
- if(!attrId){
- attrId = _ctr++;
- node[_attrId] = attrId;
- }
- if(!_evtHdlrMap[attrId]){
- _evtHdlrMap[attrId] = {};
- }
- var h = _evtHdlrMap[attrId][propName];
- if(h){
- //h.remove();
- conn.disconnect(h);
- }else{
- try{
- delete node[propName];
- }catch(e){}
- }
- // ensure that event objects are normalized, etc.
- if(value){
- //_evtHdlrMap[attrId][propName] = on(node, propName, value);
- _evtHdlrMap[attrId][propName] = conn.connect(node, propName, value);
- }else{
- node[propName] = null;
- }
- return node; // DomNode
- }
- node[propName] = value;
- return node; // DomNode
- };
- });
- },
- 'dojo/when':function(){
- define([
- "./Deferred",
- "./promise/Promise"
- ], function(Deferred, Promise){
- "use strict";
- // module:
- // dojo/when
- return function when(valueOrPromise, callback, errback, progback){
- // summary:
- // Transparently applies callbacks to values and/or promises.
- // description:
- // Accepts promises but also transparently handles non-promises. If no
- // callbacks are provided returns a promise, regardless of the initial
- // value. Foreign promises are converted.
- //
- // If callbacks are provided and the initial value is not a promise,
- // the callback is executed immediately with no error handling. Returns
- // a promise if the initial value is a promise, or the result of the
- // callback otherwise.
- // valueOrPromise:
- // Either a regular value or an object with a `then()` method that
- // follows the Promises/A specification.
- // callback: Function?
- // Callback to be invoked when the promise is resolved, or a non-promise
- // is received.
- // errback: Function?
- // Callback to be invoked when the promise is rejected.
- // progback: Function?
- // Callback to be invoked when the promise emits a progress update.
- // returns: dojo/promise/Promise
- // Promise, or if a callback is provided, the result of the callback.
- var receivedPromise = valueOrPromise && typeof valueOrPromise.then === "function";
- var nativePromise = receivedPromise && valueOrPromise instanceof Promise;
- if(!receivedPromise){
- if(callback){
- return callback(valueOrPromise);
- }else{
- return new Deferred().resolve(valueOrPromise);
- }
- }else if(!nativePromise){
- var deferred = new Deferred(valueOrPromise.cancel);
- valueOrPromise.then(deferred.resolve, deferred.reject, deferred.progress);
- valueOrPromise = deferred.promise;
- }
- if(callback || errback || progback){
- return valueOrPromise.then(callback, errback, progback);
- }
- return valueOrPromise;
- };
- });
- },
- 'dojo/dom-attr':function(){
- define(["exports", "./sniff", "./_base/lang", "./dom", "./dom-style", "./dom-prop"],
- function(exports, has, lang, dom, style, prop){
- // module:
- // dojo/dom-attr
- // summary:
- // This module defines the core dojo DOM attributes API.
- // TODOC: summary not showing up in output see https://github.com/csnover/js-doc-parse/issues/42
- // =============================
- // Element attribute Functions
- // =============================
- // This module will be obsolete soon. Use dojo/prop instead.
- // dojo.attr() should conform to http://www.w3.org/TR/DOM-Level-2-Core/
- // attribute-related functions (to be obsolete soon)
- var forcePropNames = {
- innerHTML: 1,
- className: 1,
- htmlFor: has("ie"),
- value: 1
- },
- attrNames = {
- // original attribute names
- classname: "class",
- htmlfor: "for",
- // for IE
- tabindex: "tabIndex",
- readonly: "readOnly"
- };
- function _hasAttr(node, name){
- var attr = node.getAttributeNode && node.getAttributeNode(name);
- return attr && attr.specified; // Boolean
- }
- // There is a difference in the presence of certain properties and their default values
- // between browsers. For example, on IE "disabled" is present on all elements,
- // but it is value is "false"; "tabIndex" of <div> returns 0 by default on IE, yet other browsers
- // can return -1.
- exports.has = function hasAttr(/*DOMNode|String*/ node, /*String*/ name){
- // summary:
- // Returns true if the requested attribute is specified on the
- // given element, and false otherwise.
- // node: DOMNode|String
- // id or reference to the element to check
- // name: String
- // the name of the attribute
- // returns: Boolean
- // true if the requested attribute is specified on the
- // given element, and false otherwise
- var lc = name.toLowerCase();
- return forcePropNames[prop.names[lc] || name] || _hasAttr(dom.byId(node), attrNames[lc] || name); // Boolean
- };
- exports.get = function getAttr(/*DOMNode|String*/ node, /*String*/ name){
- // summary:
- // Gets an attribute on an HTML element.
- // description:
- // Handles normalized getting of attributes on DOM Nodes.
- // node: DOMNode|String
- // id or reference to the element to get the attribute on
- // name: String
- // the name of the attribute to get.
- // returns:
- // the value of the requested attribute or null if that attribute does not have a specified or
- // default value;
- //
- // example:
- // | // get the current value of the "foo" attribute on a node
- // | dojo.getAttr(dojo.byId("nodeId"), "foo");
- // | // or we can just pass the id:
- // | dojo.getAttr("nodeId", "foo");
- node = dom.byId(node);
- var lc = name.toLowerCase(),
- propName = prop.names[lc] || name,
- forceProp = forcePropNames[propName],
- value = node[propName]; // should we access this attribute via a property or via getAttribute()?
- if(forceProp && typeof value != "undefined"){
- // node's property
- return value; // Anything
- }
- if(propName != "href" && (typeof value == "boolean" || lang.isFunction(value))){
- // node's property
- return value; // Anything
- }
- // node's attribute
- // we need _hasAttr() here to guard against IE returning a default value
- var attrName = attrNames[lc] || name;
- return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything
- };
- exports.set = function setAttr(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){
- // summary:
- // Sets an attribute on an HTML element.
- // description:
- // Handles normalized setting of attributes on DOM Nodes.
- //
- // When passing functions as values, note that they will not be
- // directly assigned to slots on the node, but rather the default
- // behavior will be removed and the new behavior will be added
- // using `dojo.connect()`, meaning that event handler properties
- // will be normalized and that some caveats with regards to
- // non-standard behaviors for onsubmit apply. Namely that you
- // should cancel form submission using `dojo.stopEvent()` on the
- // passed event object instead of returning a boolean value from
- // the handler itself.
- // node: DOMNode|String
- // id or reference to the element to set the attribute on
- // name: String|Object
- // the name of the attribute to set, or a hash of key-value pairs to set.
- // value: String?
- // the value to set for the attribute, if the name is a string.
- // returns:
- // the DOM node
- //
- // example:
- // | // use attr() to set the tab index
- // | dojo.setAttr("nodeId", "tabIndex", 3);
- //
- // example:
- // Set multiple values at once, including event handlers:
- // | dojo.setAttr("formId", {
- // | "foo": "bar",
- // | "tabIndex": -1,
- // | "method": "POST",
- // | "onsubmit": function(e){
- // | // stop submitting the form. Note that the IE behavior
- // | // of returning true or false will have no effect here
- // | // since our handler is connect()ed to the built-in
- // | // onsubmit behavior and so we need to use
- // | // dojo.stopEvent() to ensure that the submission
- // | // doesn't proceed.
- // | dojo.stopEvent(e);
- // |
- // | // submit the form with Ajax
- // | dojo.xhrPost({ form: "formId" });
- // | }
- // | });
- //
- // example:
- // Style is s special case: Only set with an object hash of styles
- // | dojo.setAttr("someNode",{
- // | id:"bar",
- // | style:{
- // | width:"200px", height:"100px", color:"#000"
- // | }
- // | });
- //
- // example:
- // Again, only set style as an object hash of styles:
- // | var obj = { color:"#fff", backgroundColor:"#000" };
- // | dojo.setAttr("someNode", "style", obj);
- // |
- // | // though shorter to use `dojo.style()` in this case:
- // | dojo.setStyle("someNode", obj);
- node = dom.byId(node);
- if(arguments.length == 2){ // inline'd type check
- // the object form of setter: the 2nd argument is a dictionary
- for(var x in name){
- exports.set(node, x, name[x]);
- }
- return node; // DomNode
- }
- var lc = name.toLowerCase(),
- propName = prop.names[lc] || name,
- forceProp = forcePropNames[propName];
- if(propName == "style" && typeof value != "string"){ // inline'd type check
- // special case: setting a style
- style.set(node, value);
- return node; // DomNode
- }
- if(forceProp || typeof value == "boolean" || lang.isFunction(value)){
- return prop.set(node, name, value);
- }
- // node's attribute
- node.setAttribute(attrNames[lc] || name, value);
- return node; // DomNode
- };
- exports.remove = function removeAttr(/*DOMNode|String*/ node, /*String*/ name){
- // summary:
- // Removes an attribute from an HTML element.
- // node: DOMNode|String
- // id or reference to the element to remove the attribute from
- // name: String
- // the name of the attribute to remove
- dom.byId(node).removeAttribute(attrNames[name.toLowerCase()] || name);
- };
- exports.getNodeProp = function getNodeProp(/*DomNode|String*/ node, /*String*/ name){
- // summary:
- // Returns an effective value of a property or an attribute.
- // node: DOMNode|String
- // id or reference to the element to remove the attribute from
- // name: String
- // the name of the attribute
- // returns:
- // the value of the attribute
- node = dom.byId(node);
- var lc = name.toLowerCase(), propName = prop.names[lc] || name;
- if((propName in node) && propName != "href"){
- // node's property
- return node[propName]; // Anything
- }
- // node's attribute
- var attrName = attrNames[lc] || name;
- return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything
- };
- });
- },
- 'dojo/dom-construct':function(){
- define(["exports", "./_base/kernel", "./sniff", "./_base/window", "./dom", "./dom-attr", "./on"],
- function(exports, dojo, has, win, dom, attr, on){
- // module:
- // dojo/dom-construct
- // summary:
- // This module defines the core dojo DOM construction API.
- // TODOC: summary not showing up in output, see https://github.com/csnover/js-doc-parse/issues/42
- // support stuff for toDom()
- var tagWrap = {
- option: ["select"],
- tbody: ["table"],
- thead: ["table"],
- tfoot: ["table"],
- tr: ["table", "tbody"],
- td: ["table", "tbody", "tr"],
- th: ["table", "thead", "tr"],
- legend: ["fieldset"],
- caption: ["table"],
- colgroup: ["table"],
- col: ["table", "colgroup"],
- li: ["ul"]
- },
- reTag = /<\s*([\w\:]+)/,
- masterNode = {}, masterNum = 0,
- masterName = "__" + dojo._scopeName + "ToDomId";
- // generate start/end tag strings to use
- // for the injection for each special tag wrap case.
- for(var param in tagWrap){
- if(tagWrap.hasOwnProperty(param)){
- var tw = tagWrap[param];
- tw.pre = param == "option" ? '<select multiple="multiple">' : "<" + tw.join("><") + ">";
- tw.post = "</" + tw.reverse().join("></") + ">";
- // the last line is destructive: it reverses the array,
- // but we don't care at this point
- }
- }
- function _insertBefore(/*DomNode*/ node, /*DomNode*/ ref){
- var parent = ref.parentNode;
- if(parent){
- parent.insertBefore(node, ref);
- }
- }
- function _insertAfter(/*DomNode*/ node, /*DomNode*/ ref){
- // summary:
- // Try to insert node after ref
- var parent = ref.parentNode;
- if(parent){
- if(parent.lastChild == ref){
- parent.appendChild(node);
- }else{
- parent.insertBefore(node, ref.nextSibling);
- }
- }
- }
- var _destroyContainer = null,
- _destroyDoc;
- on(window, "unload", function(){
- _destroyContainer = null; //prevent IE leak
- });
- exports.toDom = function toDom(frag, doc){
- // summary:
- // instantiates an HTML fragment returning the corresponding DOM.
- // frag: String
- // the HTML fragment
- // doc: DocumentNode?
- // optional document to use when creating DOM nodes, defaults to
- // dojo.doc if not specified.
- // returns:
- // Document fragment, unless it's a single node in which case it returns the node itself
- // example:
- // Create a table row:
- // | var tr = dojo.toDom("<tr><td>First!</td></tr>");
- doc = doc || win.doc;
- var masterId = doc[masterName];
- if(!masterId){
- doc[masterName] = masterId = ++masterNum + "";
- masterNode[masterId] = doc.createElement("div");
- }
- // make sure the frag is a string.
- frag += "";
- // find the starting tag, and get node wrapper
- var match = frag.match(reTag),
- tag = match ? match[1].toLowerCase() : "",
- master = masterNode[masterId],
- wrap, i, fc, df;
- if(match && tagWrap[tag]){
- wrap = tagWrap[tag];
- master.innerHTML = wrap.pre + frag + wrap.post;
- for(i = wrap.length; i; --i){
- master = master.firstChild;
- }
- }else{
- master.innerHTML = frag;
- }
- // one node shortcut => return the node itself
- if(master.childNodes.length == 1){
- return master.removeChild(master.firstChild); // DOMNode
- }
- // return multiple nodes as a document fragment
- df = doc.createDocumentFragment();
- while(fc = master.firstChild){ // intentional assignment
- df.appendChild(fc);
- }
- return df; // DocumentFragment
- };
- exports.place = function place(/*DOMNode|String*/ node, /*DOMNode|String*/ refNode, /*String|Number?*/ position){
- // summary:
- // Attempt to insert node into the DOM, choosing from various positioning options.
- // Returns the first argument resolved to a DOM node.
- // node: DOMNode|String
- // id or node reference, or HTML fragment starting with "<" to place relative to refNode
- // refNode: DOMNode|String
- // id or node reference to use as basis for placement
- // position: String|Number?
- // string noting the position of node relative to refNode or a
- // number indicating the location in the childNodes collection of refNode.
- // Accepted string values are:
- //
- // - before
- // - after
- // - replace
- // - only
- // - first
- // - last
- //
- // "first" and "last" indicate positions as children of refNode, "replace" replaces refNode,
- // "only" replaces all children. position defaults to "last" if not specified
- // returns: DOMNode
- // Returned values is the first argument resolved to a DOM node.
- //
- // .place() is also a method of `dojo/NodeList`, allowing `dojo.query` node lookups.
- // example:
- // Place a node by string id as the last child of another node by string id:
- // | dojo.place("someNode", "anotherNode");
- // example:
- // Place a node by string id before another node by string id
- // | dojo.place("someNode", "anotherNode", "before");
- // example:
- // Create a Node, and place it in the body element (last child):
- // | dojo.place("<div></div>", dojo.body());
- // example:
- // Put a new LI as the first child of a list by id:
- // | dojo.place("<li></li>", "someUl", "first");
- refNode = dom.byId(refNode);
- if(typeof node == "string"){ // inline'd type check
- node = /^\s*</.test(node) ? exports.toDom(node, refNode.ownerDocument) : dom.byId(node);
- }
- if(typeof position == "number"){ // inline'd type check
- var cn = refNode.childNodes;
- if(!cn.length || cn.length <= position){
- refNode.appendChild(node);
- }else{
- _insertBefore(node, cn[position < 0 ? 0 : position]);
- }
- }else{
- switch(position){
- case "before":
- _insertBefore(node, refNode);
- break;
- case "after":
- _insertAfter(node, refNode);
- break;
- case "replace":
- refNode.parentNode.replaceChild(node, refNode);
- break;
- case "only":
- exports.empty(refNode);
- refNode.appendChild(node);
- break;
- case "first":
- if(refNode.firstChild){
- _insertBefore(node, refNode.firstChild);
- break;
- }
- // else fallthrough...
- default: // aka: last
- refNode.appendChild(node);
- }
- }
- return node; // DomNode
- };
- exports.create = function create(/*DOMNode|String*/ tag, /*Object*/ attrs, /*DOMNode|String?*/ refNode, /*String?*/ pos){
- // summary:
- // Create an element, allowing for optional attribute decoration
- // and placement.
- // description:
- // A DOM Element creation function. A shorthand method for creating a node or
- // a fragment, and allowing for a convenient optional attribute setting step,
- // as well as an optional DOM placement reference.
- //
- // Attributes are set by passing the optional object through `dojo.setAttr`.
- // See `dojo.setAttr` for noted caveats and nuances, and API if applicable.
- //
- // Placement is done via `dojo.place`, assuming the new node to be the action
- // node, passing along the optional reference node and position.
- // tag: DOMNode|String
- // A string of the element to create (eg: "div", "a", "p", "li", "script", "br"),
- // or an existing DOM node to process.
- // attrs: Object
- // An object-hash of attributes to set on the newly created node.
- // Can be null, if you don't want to set any attributes/styles.
- // See: `dojo.setAttr` for a description of available attributes.
- // refNode: DOMNode|String?
- // Optional reference node. Used by `dojo.place` to place the newly created
- // node somewhere in the dom relative to refNode. Can be a DomNode reference
- // or String ID of a node.
- // pos: String?
- // Optional positional reference. Defaults to "last" by way of `dojo.place`,
- // though can be set to "first","after","before","last", "replace" or "only"
- // to further control the placement of the new node relative to the refNode.
- // 'refNode' is required if a 'pos' is specified.
- // example:
- // Create a DIV:
- // | var n = dojo.create("div");
- //
- // example:
- // Create a DIV with content:
- // | var n = dojo.create("div", { innerHTML:"<p>hi</p>" });
- //
- // example:
- // Place a new DIV in the BODY, with no attributes set
- // | var n = dojo.create("div", null, dojo.body());
- //
- // example:
- // Create an UL, and populate it with LI's. Place the list as the first-child of a
- // node with id="someId":
- // | var ul = dojo.create("ul", null, "someId", "first");
- // | var items = ["one", "two", "three", "four"];
- // | dojo.forEach(items, function(data){
- // | dojo.create("li", { innerHTML: data }, ul);
- // | });
- //
- // example:
- // Create an anchor, with an href. Place in BODY:
- // | dojo.create("a", { href:"foo.html", title:"Goto FOO!" }, dojo.body());
- //
- // example:
- // Create a `dojo/NodeList()` from a new element (for syntactic sugar):
- // | dojo.query(dojo.create('div'))
- // | .addClass("newDiv")
- // | .onclick(function(e){ console.log('clicked', e.target) })
- // | .place("#someNode"); // redundant, but cleaner.
- var doc = win.doc;
- if(refNode){
- refNode = dom.byId(refNode);
- doc = refNode.ownerDocument;
- }
- if(typeof tag == "string"){ // inline'd type check
- tag = doc.createElement(tag);
- }
- if(attrs){ attr.set(tag, attrs); }
- if(refNode){ exports.place(tag, refNode, pos); }
- return tag; // DomNode
- };
- exports.empty =
- has("ie") ? function(node){
- node = dom.byId(node);
- for(var c; c = node.lastChild;){ // intentional assignment
- exports.destroy(c);
- }
- } :
- function(node){
- dom.byId(node).innerHTML = "";
- };
- /*=====
- exports.empty = function(node){
- // summary:
- // safely removes all children of the node.
- // node: DOMNode|String
- // a reference to a DOM node or an id.
- // example:
- // Destroy node's children byId:
- // | dojo.empty("someId");
- //
- // example:
- // Destroy all nodes' children in a list by reference:
- // | dojo.query(".someNode").forEach(dojo.empty);
- };
- =====*/
- exports.destroy = function destroy(/*DOMNode|String*/ node){
- // summary:
- // Removes a node from its parent, clobbering it and all of its
- // children.
- //
- // description:
- // Removes a node from its parent, clobbering it and all of its
- // children. Function only works with DomNodes, and returns nothing.
- //
- // node: DOMNode|String
- // A String ID or DomNode reference of the element to be destroyed
- //
- // example:
- // Destroy a node byId:
- // | dojo.destroy("someId");
- //
- // example:
- // Destroy all nodes in a list by reference:
- // | dojo.query(".someNode").forEach(dojo.destroy);
- node = dom.byId(node);
- try{
- var doc = node.ownerDocument;
- // cannot use _destroyContainer.ownerDocument since this can throw an exception on IE
- if(!_destroyContainer || _destroyDoc != doc){
- _destroyContainer = doc.createElement("div");
- _destroyDoc = doc;
- }
- _destroyContainer.appendChild(node.parentNode ? node.parentNode.removeChild(node) : node);
- // NOTE: see http://trac.dojotoolkit.org/ticket/2931. This may be a bug and not a feature
- _destroyContainer.innerHTML = "";
- }catch(e){
- /* squelch */
- }
- };
- });
- },
- 'dojo/request/xhr':function(){
- define("dojo/request/xhr", [
- '../errors/RequestError',
- './watch',
- './handlers',
- './util',
- '../has'/*=====,
- '../request',
- '../_base/declare' =====*/
- ], function(RequestError, watch, handlers, util, has/*=====, request, declare =====*/){
- has.add('native-xhr', function(){
- // if true, the environment has a native XHR implementation
- return typeof XMLHttpRequest !== 'undefined';
- });
- has.add('dojo-force-activex-xhr', function(){
- return has('activex') && !document.addEventListener && window.location.protocol === 'file:';
- });
- has.add('native-xhr2', function(){
- if(!has('native-xhr')){ return; }
- var x = new XMLHttpRequest();
- return typeof x['addEventListener'] !== 'undefined' &&
- (typeof opera === 'undefined' || typeof x['upload'] !== 'undefined');
- });
- has.add('native-formdata', function(){
- // if true, the environment has a native FormData implementation
- return typeof FormData === 'function';
- });
- function handleResponse(response, error){
- var _xhr = response.xhr;
- response.status = response.xhr.status;
- response.text = _xhr.responseText;
- if(response.options.handleAs === 'xml'){
- response.data = _xhr.responseXML;
- }
- if(!error){
- try{
- handlers(response);
- }catch(e){
- error = e;
- }
- }
- if(error){
- this.reject(error);
- }else if(util.checkStatus(_xhr.status)){
- this.resolve(response);
- }else{
- error = new RequestError('Unable to load ' + response.url + ' status: ' + _xhr.status, response);
- this.reject(error);
- }
- }
- var isValid, isReady, addListeners, cancel;
- if(has('native-xhr2')){
- // Any platform with XHR2 will only use the watch mechanism for timeout.
- isValid = function(response){
- // summary:
- // Check to see if the request should be taken out of the watch queue
- return !this.isFulfilled();
- };
- cancel = function(dfd, response){
- // summary:
- // Canceler for deferred
- response.xhr.abort();
- };
- addListeners = function(_xhr, dfd, response){
- // summary:
- // Adds event listeners to the XMLHttpRequest object
- function onLoad(evt){
- dfd.handleResponse(response);
- }
- function onError(evt){
- var _xhr = evt.target;
- var error = new RequestError('Unable to load ' + response.url + ' status: ' + _xhr.status, response);
- dfd.handleResponse(response, error);
- }
- function onProgress(evt){
- if(evt.lengthComputable){
- response.loaded = evt.loaded;
- response.total = evt.total;
- dfd.progress(response);
- }
- }
- _xhr.addEventListener('load', onLoad, false);
- _xhr.addEventListener('error', onError, false);
- _xhr.addEventListener('progress', onProgress, false);
- return function(){
- _xhr.removeEventListener('load', onLoad, false);
- _xhr.removeEventListener('error', onError, false);
- _xhr.removeEventListener('progress', onProgress, false);
- };
- };
- }else{
- isValid = function(response){
- return response.xhr.readyState; //boolean
- };
- isReady = function(response){
- return 4 === response.xhr.readyState; //boolean
- };
- cancel = function(dfd, response){
- // summary:
- // canceller function for util.deferred call.
- var xhr = response.xhr;
- var _at = typeof xhr.abort;
- if(_at === 'function' || _at === 'object' || _at === 'unknown'){
- xhr.abort();
- }
- };
- }
- var undefined,
- defaultOptions = {
- data: null,
- query: null,
- sync: false,
- method: 'GET',
- headers: {
- 'Content-Type': 'application/x-www-form-urlencoded'
- }
- };
- function xhr(url, options, returnDeferred){
- var response = util.parseArgs(
- url,
- util.deepCreate(defaultOptions, options),
- has('native-formdata') && options && options.data && options.data instanceof FormData
- );
- url = response.url;
- options = response.options;
- var remover,
- last = function(){
- remover && remover();
- };
- //Make the Deferred object for this xhr request.
- var dfd = util.deferred(
- response,
- cancel,
- isValid,
- isReady,
- handleResponse,
- last
- );
- var _xhr = response.xhr = xhr._create();
- if(!_xhr){
- // If XHR factory somehow returns nothings,
- // cancel the deferred.
- dfd.cancel(new RequestError('XHR was not created'));
- return returnDeferred ? dfd : dfd.promise;
- }
- response.getHeader = function(headerName){
- return this.xhr.getResponseHeader(headerName);
- };
- if(addListeners){
- remover = addListeners(_xhr, dfd, response);
- }
- var data = options.data,
- async = !options.sync,
- method = options.method;
- try{
- // IE6 won't let you call apply() on the native function.
- _xhr.open(method, url, async, options.user || undefined, options.password || undefined);
- if(options.withCredentials){
- _xhr.withCredentials = options.withCredentials;
- }
- var headers = options.headers,
- contentType;
- if(headers){
- for(var hdr in headers){
- if(hdr.toLowerCase() === 'content-type'){
- contentType = headers[hdr];
- }else if(headers[hdr]){
- //Only add header if it has a value. This allows for instance, skipping
- //insertion of X-Requested-With by specifying empty value.
- _xhr.setRequestHeader(hdr, headers[hdr]);
- }
- }
- }
- if(contentType && contentType !== false){
- _xhr.setRequestHeader('Content-Type', contentType);
- }
- if(!headers || !('X-Requested-With' in headers)){
- _xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
- }
- if(util.notify){
- util.notify.emit('send', response, dfd.promise.cancel);
- }
- _xhr.send(data);
- }catch(e){
- dfd.reject(e);
- }
- watch(dfd);
- _xhr = null;
- return returnDeferred ? dfd : dfd.promise;
- }
- /*=====
- xhr = function(url, options){
- // summary:
- // Sends a request using XMLHttpRequest with the given URL and options.
- // url: String
- // URL to request
- // options: dojo/request/xhr.__Options?
- // Options for the request.
- // returns: dojo/request.__Promise
- };
- xhr.__BaseOptions = declare(request.__BaseOptions, {
- // sync: Boolean?
- // Whether to make a synchronous request or not. Default
- // is `false` (asynchronous).
- // data: String|Object|FormData?
- // Data to transfer. This is ignored for GET and DELETE
- // requests.
- // headers: Object?
- // Headers to use for the request.
- // user: String?
- // Username to use during the request.
- // password: String?
- // Password to use during the request.
- // withCredentials: Boolean?
- // For cross-site requests, whether to send credentials
- // or not.
- });
- xhr.__MethodOptions = declare(null, {
- // method: String?
- // The HTTP method to use to make the request. Must be
- // uppercase. Default is `"GET"`.
- });
- xhr.__Options = declare([xhr.__BaseOptions, xhr.__MethodOptions]);
- xhr.get = function(url, options){
- // summary:
- // Send an HTTP GET request using XMLHttpRequest with the given URL and options.
- // url: String
- // URL to request
- // options: dojo/request/xhr.__BaseOptions?
- // Options for the request.
- // returns: dojo/request.__Promise
- };
- xhr.post = function(url, options){
- // summary:
- // Send an HTTP POST request using XMLHttpRequest with the given URL and options.
- // url: String
- // URL to request
- // options: dojo/request/xhr.__BaseOptions?
- // Options for the request.
- // returns: dojo/request.__Promise
- };
- xhr.put = function(url, options){
- // summary:
- // Send an HTTP PUT request using XMLHttpRequest with the given URL and options.
- // url: String
- // URL to request
- // options: dojo/request/xhr.__BaseOptions?
- // Options for the request.
- // returns: dojo/request.__Promise
- };
- xhr.del = function(url, options){
- // summary:
- // Send an HTTP DELETE request using XMLHttpRequest with the given URL and options.
- // url: String
- // URL to request
- // options: dojo/request/xhr.__BaseOptions?
- // Options for the request.
- // returns: dojo/request.__Promise
- };
- =====*/
- xhr._create = function(){
- // summary:
- // does the work of portably generating a new XMLHTTPRequest object.
- throw new Error('XMLHTTP not available');
- };
- if(has('native-xhr') && !has('dojo-force-activex-xhr')){
- xhr._create = function(){
- return new XMLHttpRequest();
- };
- }else if(has('activex')){
- try{
- new ActiveXObject('Msxml2.XMLHTTP');
- xhr._create = function(){
- return new ActiveXObject('Msxml2.XMLHTTP');
- };
- }catch(e){
- try{
- new ActiveXObject('Microsoft.XMLHTTP');
- xhr._create = function(){
- return new ActiveXObject('Microsoft.XMLHTTP');
- };
- }catch(e){}
- }
- }
- util.addCommonMethods(xhr);
- return xhr;
- });
- },
- 'dojo/text':function(){
- define(["./_base/kernel", "require", "./has", "./_base/xhr"], function(dojo, require, has, xhr){
- // module:
- // dojo/text
- var getText;
- if( 1 ){
- getText= function(url, sync, load){
- xhr("GET", {url: url, sync:!!sync, load: load, headers: dojo.config.textPluginHeaders || {}});
- };
- }else{
- // TODOC: only works for dojo AMD loader
- if(require.getText){
- getText= require.getText;
- }else{
- console.error("dojo/text plugin failed to load because loader does not support getText");
- }
- }
- var
- theCache = {},
- strip= function(text){
- //Strips <?xml ...?> declarations so that external SVG and XML
- //documents can be added to a document without worry. Also, if the string
- //is an HTML document, only the part inside the body tag is returned.
- if(text){
- text= text.replace(/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im, "");
- var matches= text.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);
- if(matches){
- text= matches[1];
- }
- }else{
- text = "";
- }
- return text;
- },
- notFound = {},
- pending = {};
- dojo.cache = function(/*String||Object*/module, /*String*/url, /*String||Object?*/value){
- // summary:
- // A getter and setter for storing the string content associated with the
- // module and url arguments.
- // description:
- // If module is a string that contains slashes, then it is interpretted as a fully
- // resolved path (typically a result returned by require.toUrl), and url should not be
- // provided. This is the preferred signature. If module is a string that does not
- // contain slashes, then url must also be provided and module and url are used to
- // call `dojo.moduleUrl()` to generate a module URL. This signature is deprecated.
- // If value is specified, the cache value for the moduleUrl will be set to
- // that value. Otherwise, dojo.cache will fetch the moduleUrl and store it
- // in its internal cache and return that cached value for the URL. To clear
- // a cache value pass null for value. Since XMLHttpRequest (XHR) is used to fetch the
- // the URL contents, only modules on the same domain of the page can use this capability.
- // The build system can inline the cache values though, to allow for xdomain hosting.
- // module: String||Object
- // If a String with slashes, a fully resolved path; if a String without slashes, the
- // module name to use for the base part of the URL, similar to module argument
- // to `dojo.moduleUrl`. If an Object, something that has a .toString() method that
- // generates a valid path for the cache item. For example, a dojo._Url object.
- // url: String
- // The rest of the path to append to the path derived from the module argument. If
- // module is an object, then this second argument should be the "value" argument instead.
- // value: String||Object?
- // If a String, the value to use in the cache for the module/url combination.
- // If an Object, it can have two properties: value and sanitize. The value property
- // should be the value to use in the cache, and sanitize can be set to true or false,
- // to indicate if XML declarations should be removed from the value and if the HTML
- // inside a body tag in the value should be extracted as the real value. The value argument
- // or the value property on the value argument are usually only used by the build system
- // as it inlines cache content.
- // example:
- // To ask dojo.cache to fetch content and store it in the cache (the dojo["cache"] style
- // of call is used to avoid an issue with the build system erroneously trying to intern
- // this example. To get the build system to intern your dojo.cache calls, use the
- // "dojo.cache" style of call):
- // | //If template.html contains "<h1>Hello</h1>" that will be
- // | //the value for the text variable.
- // | var text = dojo["cache"]("my.module", "template.html");
- // example:
- // To ask dojo.cache to fetch content and store it in the cache, and sanitize the input
- // (the dojo["cache"] style of call is used to avoid an issue with the build system
- // erroneously trying to intern this example. To get the build system to intern your
- // dojo.cache calls, use the "dojo.cache" style of call):
- // | //If template.html contains "<html><body><h1>Hello</h1></body></html>", the
- // | //text variable will contain just "<h1>Hello</h1>".
- // | var text = dojo["cache"]("my.module", "template.html", {sanitize: true});
- // example:
- // Same example as previous, but demonstrates how an object can be passed in as
- // the first argument, then the value argument can then be the second argument.
- // | //If template.html contains "<html><body><h1>Hello</h1></body></html>", the
- // | //text variable will contain just "<h1>Hello</h1>".
- // | var text = dojo["cache"](new dojo._Url("my/module/template.html"), {sanitize: true});
- // * (string string [value]) => (module, url, value)
- // * (object [value]) => (module, value), url defaults to ""
- //
- // * if module is an object, then it must be convertable to a string
- // * (module, url) module + (url ? ("/" + url) : "") must be a legal argument to require.toUrl
- // * value may be a string or an object; if an object then may have the properties "value" and/or "sanitize"
- var key;
- if(typeof module=="string"){
- if(/\//.test(module)){
- // module is a version 1.7+ resolved path
- key = module;
- value = url;
- }else{
- // module is a version 1.6- argument to dojo.moduleUrl
- key = require.toUrl(module.replace(/\./g, "/") + (url ? ("/" + url) : ""));
- }
- }else{
- key = module + "";
- value = url;
- }
- var
- val = (value != undefined && typeof value != "string") ? value.value : value,
- sanitize = value && value.sanitize;
- if(typeof val == "string"){
- //We have a string, set cache value
- theCache[key] = val;
- return sanitize ? strip(val) : val;
- }else if(val === null){
- //Remove cached value
- delete theCache[key];
- return null;
- }else{
- //Allow cache values to be empty strings. If key property does
- //not exist, fetch it.
- if(!(key in theCache)){
- getText(key, true, function(text){
- theCache[key]= text;
- });
- }
- return sanitize ? strip(theCache[key]) : theCache[key];
- }
- };
- return {
- // summary:
- // This module implements the dojo/text! plugin and the dojo.cache API.
- // description:
- // We choose to include our own plugin to leverage functionality already contained in dojo
- // and thereby reduce the size of the plugin compared to various foreign loader implementations.
- // Also, this allows foreign AMD loaders to be used without their plugins.
- //
- // CAUTION: this module is designed to optionally function synchronously to support the dojo v1.x synchronous
- // loader. This feature is outside the scope of the CommonJS plugins specification.
- // the dojo/text caches it's own resources because of dojo.cache
- dynamic: true,
- normalize: function(id, toAbsMid){
- // id is something like (path may be relative):
- //
- // "path/to/text.html"
- // "path/to/text.html!strip"
- var parts= id.split("!"),
- url= parts[0];
- return (/^\./.test(url) ? toAbsMid(url) : url) + (parts[1] ? "!" + parts[1] : "");
- },
- load: function(id, require, load){
- // id: String
- // Path to the resource.
- // require: Function
- // Object that include the function toUrl with given id returns a valid URL from which to load the text.
- // load: Function
- // Callback function which will be called, when the loading finished.
- // id is something like (path is always absolute):
- //
- // "path/to/text.html"
- // "path/to/text.html!strip"
- var
- parts= id.split("!"),
- stripFlag= parts.length>1,
- absMid= parts[0],
- url = require.toUrl(parts[0]),
- requireCacheUrl = "url:" + url,
- text = notFound,
- finish = function(text){
- load(stripFlag ? strip(text) : text);
- };
- if(absMid in theCache){
- text = theCache[absMid];
- }else if(requireCacheUrl in require.cache){
- text = require.cache[requireCacheUrl];
- }else if(url in theCache){
- text = theCache[url];
- }
- if(text===notFound){
- if(pending[url]){
- pending[url].push(finish);
- }else{
- var pendingList = pending[url] = [finish];
- getText(url, !require.async, function(text){
- theCache[absMid]= theCache[url]= text;
- for(var i = 0; i<pendingList.length;){
- pendingList[i++](text);
- }
- delete pending[url];
- });
- }
- }else{
- finish(text);
- }
- }
- };
- });
- },
- 'dojo/keys':function(){
- define("dojo/keys", ["./_base/kernel", "./sniff"], function(dojo, has){
- // module:
- // dojo/keys
- return dojo.keys = {
- // summary:
- // Definitions for common key values. Client code should test keyCode against these named constants,
- // as the actual codes can vary by browser.
- BACKSPACE: 8,
- TAB: 9,
- CLEAR: 12,
- ENTER: 13,
- SHIFT: 16,
- CTRL: 17,
- ALT: 18,
- META: has("webkit") ? 91 : 224, // the apple key on macs
- PAUSE: 19,
- CAPS_LOCK: 20,
- ESCAPE: 27,
- SPACE: 32,
- PAGE_UP: 33,
- PAGE_DOWN: 34,
- END: 35,
- HOME: 36,
- LEFT_ARROW: 37,
- UP_ARROW: 38,
- RIGHT_ARROW: 39,
- DOWN_ARROW: 40,
- INSERT: 45,
- DELETE: 46,
- HELP: 47,
- LEFT_WINDOW: 91,
- RIGHT_WINDOW: 92,
- SELECT: 93,
- NUMPAD_0: 96,
- NUMPAD_1: 97,
- NUMPAD_2: 98,
- NUMPAD_3: 99,
- NUMPAD_4: 100,
- NUMPAD_5: 101,
- NUMPAD_6: 102,
- NUMPAD_7: 103,
- NUMPAD_8: 104,
- NUMPAD_9: 105,
- NUMPAD_MULTIPLY: 106,
- NUMPAD_PLUS: 107,
- NUMPAD_ENTER: 108,
- NUMPAD_MINUS: 109,
- NUMPAD_PERIOD: 110,
- NUMPAD_DIVIDE: 111,
- F1: 112,
- F2: 113,
- F3: 114,
- F4: 115,
- F5: 116,
- F6: 117,
- F7: 118,
- F8: 119,
- F9: 120,
- F10: 121,
- F11: 122,
- F12: 123,
- F13: 124,
- F14: 125,
- F15: 126,
- NUM_LOCK: 144,
- SCROLL_LOCK: 145,
- UP_DPAD: 175,
- DOWN_DPAD: 176,
- LEFT_DPAD: 177,
- RIGHT_DPAD: 178,
- // virtual key mapping
- copyKey: has("mac") && !has("air") ? (has("safari") ? 91 : 224 ) : 17
- };
- });
- },
- 'dojo/domReady':function(){
- define(['./has'], function(has){
- var global = this,
- doc = document,
- readyStates = { 'loaded': 1, 'complete': 1 },
- fixReadyState = typeof doc.readyState != "string",
- ready = !!readyStates[doc.readyState];
- // For FF <= 3.5
- if(fixReadyState){ doc.readyState = "loading"; }
- if(!ready){
- var readyQ = [], tests = [],
- detectReady = function(evt){
- evt = evt || global.event;
- if(ready || (evt.type == "readystatechange" && !readyStates[doc.readyState])){ return; }
- ready = 1;
- // For FF <= 3.5
- if(fixReadyState){ doc.readyState = "complete"; }
- while(readyQ.length){
- (readyQ.shift())(doc);
- }
- },
- on = function(node, event){
- node.addEventListener(event, detectReady, false);
- readyQ.push(function(){ node.removeEventListener(event, detectReady, false); });
- };
- if(!has("dom-addeventlistener")){
- on = function(node, event){
- event = "on" + event;
- node.attachEvent(event, detectReady);
- readyQ.push(function(){ node.detachEvent(event, detectReady); });
- };
- var div = doc.createElement("div");
- try{
- if(div.doScroll && global.frameElement === null){
- // the doScroll test is only useful if we're in the top-most frame
- tests.push(function(){
- // Derived with permission from Diego Perini's IEContentLoaded
- // http://javascript.nwbox.com/IEContentLoaded/
- try{
- div.doScroll("left");
- return 1;
- }catch(e){}
- });
- }
- }catch(e){}
- }
- on(doc, "DOMContentLoaded");
- on(global, "load");
- if("onreadystatechange" in doc){
- on(doc, "readystatechange");
- }else if(!fixReadyState){
- // if the ready state property exists and there's
- // no readystatechange event, poll for the state
- // to change
- tests.push(function(){
- return readyStates[doc.readyState];
- });
- }
- if(tests.length){
- var poller = function(){
- if(ready){ return; }
- var i = tests.length;
- while(i--){
- if(tests[i]()){
- detectReady("poller");
- return;
- }
- }
- setTimeout(poller, 30);
- };
- poller();
- }
- }
- function domReady(callback){
- // summary:
- // Plugin to delay require()/define() callback from firing until the DOM has finished loading.
- if(ready){
- callback(doc);
- }else{
- readyQ.push(callback);
- }
- }
- domReady.load = function(id, req, load){
- domReady(load);
- };
- return domReady;
- });
- },
- 'dojo/_base/lang':function(){
- define("dojo/_base/lang", ["./kernel", "../has", "../sniff"], function(dojo, has){
- // module:
- // dojo/_base/lang
- has.add("bug-for-in-skips-shadowed", function(){
- // if true, the for-in iterator skips object properties that exist in Object's prototype (IE 6 - ?)
- for(var i in {toString: 1}){
- return 0;
- }
- return 1;
- });
- // Helper methods
- var _extraNames =
- has("bug-for-in-skips-shadowed") ?
- "hasOwnProperty.valueOf.isPrototypeOf.propertyIsEnumerable.toLocaleString.toString.constructor".split(".") : [],
- _extraLen = _extraNames.length,
- getProp = function(/*Array*/parts, /*Boolean*/create, /*Object*/context){
- var p, i = 0, dojoGlobal = dojo.global;
- if(!context){
- if(!parts.length){
- return dojoGlobal;
- }else{
- p = parts[i++];
- try{
- context = dojo.scopeMap[p] && dojo.scopeMap[p][1];
- }catch(e){}
- context = context || (p in dojoGlobal ? dojoGlobal[p] : (create ? dojoGlobal[p] = {} : undefined));
- }
- }
- while(context && (p = parts[i++])){
- context = (p in context ? context[p] : (create ? context[p] = {} : undefined));
- }
- return context; // mixed
- },
- opts = Object.prototype.toString,
- efficient = function(obj, offset, startWith){
- return (startWith||[]).concat(Array.prototype.slice.call(obj, offset||0));
- },
- _pattern = /\{([^\}]+)\}/g;
- // Module export
- var lang = {
- // summary:
- // This module defines Javascript language extensions.
- // _extraNames: String[]
- // Lists property names that must be explicitly processed during for-in iteration
- // in environments that have has("bug-for-in-skips-shadowed") true.
- _extraNames:_extraNames,
- _mixin: function(dest, source, copyFunc){
- // summary:
- // Copies/adds all properties of source to dest; returns dest.
- // dest: Object
- // The object to which to copy/add all properties contained in source.
- // source: Object
- // The object from which to draw all properties to copy into dest.
- // copyFunc: Function?
- // The process used to copy/add a property in source; defaults to the Javascript assignment operator.
- // returns:
- // dest, as modified
- // description:
- // All properties, including functions (sometimes termed "methods"), excluding any non-standard extensions
- // found in Object.prototype, are copied/added to dest. Copying/adding each particular property is
- // delegated to copyFunc (if any); copyFunc defaults to the Javascript assignment operator if not provided.
- // Notice that by default, _mixin executes a so-called "shallow copy" and aggregate types are copied/added by reference.
- var name, s, i, empty = {};
- for(name in source){
- // the (!(name in empty) || empty[name] !== s) condition avoids copying properties in "source"
- // inherited from Object.prototype. For example, if dest has a custom toString() method,
- // don't overwrite it with the toString() method that source inherited from Object.prototype
- s = source[name];
- if(!(name in dest) || (dest[name] !== s && (!(name in empty) || empty[name] !== s))){
- dest[name] = copyFunc ? copyFunc(s) : s;
- }
- }
- if(has("bug-for-in-skips-shadowed")){
- if(source){
- for(i = 0; i < _extraLen; ++i){
- name = _extraNames[i];
- s = source[name];
- if(!(name in dest) || (dest[name] !== s && (!(name in empty) || empty[name] !== s))){
- dest[name] = copyFunc ? copyFunc(s) : s;
- }
- }
- }
- }
- return dest; // Object
- },
- mixin: function(dest, sources){
- // summary:
- // Copies/adds all properties of one or more sources to dest; returns dest.
- // dest: Object
- // The object to which to copy/add all properties contained in source. If dest is falsy, then
- // a new object is manufactured before copying/adding properties begins.
- // sources: Object...
- // One of more objects from which to draw all properties to copy into dest. sources are processed
- // left-to-right and if more than one of these objects contain the same property name, the right-most
- // value "wins".
- // returns: Object
- // dest, as modified
- // description:
- // All properties, including functions (sometimes termed "methods"), excluding any non-standard extensions
- // found in Object.prototype, are copied/added from sources to dest. sources are processed left to right.
- // The Javascript assignment operator is used to copy/add each property; therefore, by default, mixin
- // executes a so-called "shallow copy" and aggregate types are copied/added by reference.
- // example:
- // make a shallow copy of an object
- // | var copy = lang.mixin({}, source);
- // example:
- // many class constructors often take an object which specifies
- // values to be configured on the object. In this case, it is
- // often simplest to call `lang.mixin` on the `this` object:
- // | declare("acme.Base", null, {
- // | constructor: function(properties){
- // | // property configuration:
- // | lang.mixin(this, properties);
- // |
- // | console.log(this.quip);
- // | // ...
- // | },
- // | quip: "I wasn't born yesterday, you know - I've seen movies.",
- // | // ...
- // | });
- // |
- // | // create an instance of the class and configure it
- // | var b = new acme.Base({quip: "That's what it does!" });
- // example:
- // copy in properties from multiple objects
- // | var flattened = lang.mixin(
- // | {
- // | name: "Frylock",
- // | braces: true
- // | },
- // | {
- // | name: "Carl Brutanananadilewski"
- // | }
- // | );
- // |
- // | // will print "Carl Brutanananadilewski"
- // | console.log(flattened.name);
- // | // will print "true"
- // | console.log(flattened.braces);
- if(!dest){ dest = {}; }
- for(var i = 1, l = arguments.length; i < l; i++){
- lang._mixin(dest, arguments[i]);
- }
- return dest; // Object
- },
- setObject: function(name, value, context){
- // summary:
- // Set a property from a dot-separated string, such as "A.B.C"
- // description:
- // Useful for longer api chains where you have to test each object in
- // the chain, or when you have an object reference in string format.
- // Objects are created as needed along `path`. Returns the passed
- // value if setting is successful or `undefined` if not.
- // name: String
- // Path to a property, in the form "A.B.C".
- // value: anything
- // value or object to place at location given by name
- // context: Object?
- // Optional. Object to use as root of path. Defaults to
- // `dojo.global`.
- // example:
- // set the value of `foo.bar.baz`, regardless of whether
- // intermediate objects already exist:
- // | lang.setObject("foo.bar.baz", value);
- // example:
- // without `lang.setObject`, we often see code like this:
- // | // ensure that intermediate objects are available
- // | if(!obj["parent"]){ obj.parent = {}; }
- // | if(!obj.parent["child"]){ obj.parent.child = {}; }
- // | // now we can safely set the property
- // | obj.parent.child.prop = "some value";
- // whereas with `lang.setObject`, we can shorten that to:
- // | lang.setObject("parent.child.prop", "some value", obj);
- var parts = name.split("."), p = parts.pop(), obj = getProp(parts, true, context);
- return obj && p ? (obj[p] = value) : undefined; // Object
- },
- getObject: function(name, create, context){
- // summary:
- // Get a property from a dot-separated string, such as "A.B.C"
- // description:
- // Useful for longer api chains where you have to test each object in
- // the chain, or when you have an object reference in string format.
- // name: String
- // Path to an property, in the form "A.B.C".
- // create: Boolean?
- // Optional. Defaults to `false`. If `true`, Objects will be
- // created at any point along the 'path' that is undefined.
- // context: Object?
- // Optional. Object to use as root of path. Defaults to
- // 'dojo.global'. Null may be passed.
- return getProp(name.split("."), create, context); // Object
- },
- exists: function(name, obj){
- // summary:
- // determine if an object supports a given method
- // description:
- // useful for longer api chains where you have to test each object in
- // the chain. Useful for object and method detection.
- // name: String
- // Path to an object, in the form "A.B.C".
- // obj: Object?
- // Object to use as root of path. Defaults to
- // 'dojo.global'. Null may be passed.
- // example:
- // | // define an object
- // | var foo = {
- // | bar: { }
- // | };
- // |
- // | // search the global scope
- // | lang.exists("foo.bar"); // true
- // | lang.exists("foo.bar.baz"); // false
- // |
- // | // search from a particular scope
- // | lang.exists("bar", foo); // true
- // | lang.exists("bar.baz", foo); // false
- return lang.getObject(name, false, obj) !== undefined; // Boolean
- },
- // Crockford (ish) functions
- isString: function(it){
- // summary:
- // Return true if it is a String
- // it: anything
- // Item to test.
- return (typeof it == "string" || it instanceof String); // Boolean
- },
- isArray: function(it){
- // summary:
- // Return true if it is an Array.
- // Does not work on Arrays created in other windows.
- // it: anything
- // Item to test.
- return it && (it instanceof Array || typeof it == "array"); // Boolean
- },
- isFunction: function(it){
- // summary:
- // Return true if it is a Function
- // it: anything
- // Item to test.
- return opts.call(it) === "[object Function]";
- },
- isObject: function(it){
- // summary:
- // Returns true if it is a JavaScript object (or an Array, a Function
- // or null)
- // it: anything
- // Item to test.
- return it !== undefined &&
- (it === null || typeof it == "object" || lang.isArray(it) || lang.isFunction(it)); // Boolean
- },
- isArrayLike: function(it){
- // summary:
- // similar to isArray() but more permissive
- // it: anything
- // Item to test.
- // returns:
- // If it walks like a duck and quacks like a duck, return `true`
- // description:
- // Doesn't strongly test for "arrayness". Instead, settles for "isn't
- // a string or number and has a length property". Arguments objects
- // and DOM collections will return true when passed to
- // isArrayLike(), but will return false when passed to
- // isArray().
- return it && it !== undefined && // Boolean
- // keep out built-in constructors (Number, String, ...) which have length
- // properties
- !lang.isString(it) && !lang.isFunction(it) &&
- !(it.tagName && it.tagName.toLowerCase() == 'form') &&
- (lang.isArray(it) || isFinite(it.length));
- },
- isAlien: function(it){
- // summary:
- // Returns true if it is a built-in function or some other kind of
- // oddball that *should* report as a function but doesn't
- return it && !lang.isFunction(it) && /\{\s*\[native code\]\s*\}/.test(String(it)); // Boolean
- },
- extend: function(ctor, props){
- // summary:
- // Adds all properties and methods of props to constructor's
- // prototype, making them available to all instances created with
- // constructor.
- // ctor: Object
- // Target constructor to extend.
- // props: Object
- // One or more objects to mix into ctor.prototype
- for(var i=1, l=arguments.length; i<l; i++){
- lang._mixin(ctor.prototype, arguments[i]);
- }
- return ctor; // Object
- },
- _hitchArgs: function(scope, method){
- var pre = lang._toArray(arguments, 2);
- var named = lang.isString(method);
- return function(){
- // arrayify arguments
- var args = lang._toArray(arguments);
- // locate our method
- var f = named ? (scope||dojo.global)[method] : method;
- // invoke with collected args
- return f && f.apply(scope || this, pre.concat(args)); // mixed
- }; // Function
- },
- hitch: function(scope, method){
- // summary:
- // Returns a function that will only ever execute in the a given scope.
- // This allows for easy use of object member functions
- // in callbacks and other places in which the "this" keyword may
- // otherwise not reference the expected scope.
- // Any number of default positional arguments may be passed as parameters
- // beyond "method".
- // Each of these values will be used to "placehold" (similar to curry)
- // for the hitched function.
- // scope: Object
- // The scope to use when method executes. If method is a string,
- // scope is also the object containing method.
- // method: Function|String...
- // A function to be hitched to scope, or the name of the method in
- // scope to be hitched.
- // example:
- // | lang.hitch(foo, "bar")();
- // runs foo.bar() in the scope of foo
- // example:
- // | lang.hitch(foo, myFunction);
- // returns a function that runs myFunction in the scope of foo
- // example:
- // Expansion on the default positional arguments passed along from
- // hitch. Passed args are mixed first, additional args after.
- // | var foo = { bar: function(a, b, c){ console.log(a, b, c); } };
- // | var fn = lang.hitch(foo, "bar", 1, 2);
- // | fn(3); // logs "1, 2, 3"
- // example:
- // | var foo = { bar: 2 };
- // | lang.hitch(foo, function(){ this.bar = 10; })();
- // execute an anonymous function in scope of foo
- if(arguments.length > 2){
- return lang._hitchArgs.apply(dojo, arguments); // Function
- }
- if(!method){
- method = scope;
- scope = null;
- }
- if(lang.isString(method)){
- scope = scope || dojo.global;
- if(!scope[method]){ throw(['lang.hitch: scope["', method, '"] is null (scope="', scope, '")'].join('')); }
- return function(){ return scope[method].apply(scope, arguments || []); }; // Function
- }
- return !scope ? method : function(){ return method.apply(scope, arguments || []); }; // Function
- },
- delegate: (function(){
- // boodman/crockford delegation w/ cornford optimization
- function TMP(){}
- return function(obj, props){
- TMP.prototype = obj;
- var tmp = new TMP();
- TMP.prototype = null;
- if(props){
- lang._mixin(tmp, props);
- }
- return tmp; // Object
- };
- })(),
- /*=====
- delegate: function(obj, props){
- // summary:
- // Returns a new object which "looks" to obj for properties which it
- // does not have a value for. Optionally takes a bag of properties to
- // seed the returned object with initially.
- // description:
- // This is a small implementation of the Boodman/Crockford delegation
- // pattern in JavaScript. An intermediate object constructor mediates
- // the prototype chain for the returned object, using it to delegate
- // down to obj for property lookup when object-local lookup fails.
- // This can be thought of similarly to ES4's "wrap", save that it does
- // not act on types but rather on pure objects.
- // obj: Object
- // The object to delegate to for properties not found directly on the
- // return object or in props.
- // props: Object...
- // an object containing properties to assign to the returned object
- // returns:
- // an Object of anonymous type
- // example:
- // | var foo = { bar: "baz" };
- // | var thinger = lang.delegate(foo, { thud: "xyzzy"});
- // | thinger.bar == "baz"; // delegated to foo
- // | foo.thud == undefined; // by definition
- // | thinger.thud == "xyzzy"; // mixed in from props
- // | foo.bar = "thonk";
- // | thinger.bar == "thonk"; // still delegated to foo's bar
- },
- =====*/
- _toArray: has("ie") ?
- (function(){
- function slow(obj, offset, startWith){
- var arr = startWith||[];
- for(var x = offset || 0; x < obj.length; x++){
- arr.push(obj[x]);
- }
- return arr;
- }
- return function(obj){
- return ((obj.item) ? slow : efficient).apply(this, arguments);
- };
- })() : efficient,
- /*=====
- _toArray: function(obj, offset, startWith){
- // summary:
- // Converts an array-like object (i.e. arguments, DOMCollection) to an
- // array. Returns a new Array with the elements of obj.
- // obj: Object
- // the object to "arrayify". We expect the object to have, at a
- // minimum, a length property which corresponds to integer-indexed
- // properties.
- // offset: Number?
- // the location in obj to start iterating from. Defaults to 0.
- // Optional.
- // startWith: Array?
- // An array to pack with the properties of obj. If provided,
- // properties in obj are appended at the end of startWith and
- // startWith is the returned array.
- },
- =====*/
- partial: function(/*Function|String*/ method /*, ...*/){
- // summary:
- // similar to hitch() except that the scope object is left to be
- // whatever the execution context eventually becomes.
- // description:
- // Calling lang.partial is the functional equivalent of calling:
- // | lang.hitch(null, funcName, ...);
- // method:
- // The function to "wrap"
- var arr = [ null ];
- return lang.hitch.apply(dojo, arr.concat(lang._toArray(arguments))); // Function
- },
- clone: function(/*anything*/ src){
- // summary:
- // Clones objects (including DOM nodes) and all children.
- // Warning: do not clone cyclic structures.
- // src:
- // The object to clone
- if(!src || typeof src != "object" || lang.isFunction(src)){
- // null, undefined, any non-object, or function
- return src; // anything
- }
- if(src.nodeType && "cloneNode" in src){
- // DOM Node
- return src.cloneNode(true); // Node
- }
- if(src instanceof Date){
- // Date
- return new Date(src.getTime()); // Date
- }
- if(src instanceof RegExp){
- // RegExp
- return new RegExp(src); // RegExp
- }
- var r, i, l;
- if(lang.isArray(src)){
- // array
- r = [];
- for(i = 0, l = src.length; i < l; ++i){
- if(i in src){
- r.push(lang.clone(src[i]));
- }
- }
- // we don't clone functions for performance reasons
- // }else if(d.isFunction(src)){
- // // function
- // r = function(){ return src.apply(this, arguments); };
- }else{
- // generic objects
- r = src.constructor ? new src.constructor() : {};
- }
- return lang._mixin(r, src, lang.clone);
- },
- trim: String.prototype.trim ?
- function(str){ return str.trim(); } :
- function(str){ return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); },
- /*=====
- trim: function(str){
- // summary:
- // Trims whitespace from both sides of the string
- // str: String
- // String to be trimmed
- // returns: String
- // Returns the trimmed string
- // description:
- // This version of trim() was selected for inclusion into the base due
- // to its compact size and relatively good performance
- // (see [Steven Levithan's blog](http://blog.stevenlevithan.com/archives/faster-trim-javascript)
- // Uses String.prototype.trim instead, if available.
- // The fastest but longest version of this function is located at
- // lang.string.trim()
- },
- =====*/
- replace: function(tmpl, map, pattern){
- // summary:
- // Performs parameterized substitutions on a string. Throws an
- // exception if any parameter is unmatched.
- // tmpl: String
- // String to be used as a template.
- // map: Object|Function
- // If an object, it is used as a dictionary to look up substitutions.
- // If a function, it is called for every substitution with following parameters:
- // a whole match, a name, an offset, and the whole template
- // string (see https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/String/replace
- // for more details).
- // pattern: RegEx?
- // Optional regular expression objects that overrides the default pattern.
- // Must be global and match one item. The default is: /\{([^\}]+)\}/g,
- // which matches patterns like that: "{xxx}", where "xxx" is any sequence
- // of characters, which doesn't include "}".
- // returns: String
- // Returns the substituted string.
- // example:
- // | // uses a dictionary for substitutions:
- // | lang.replace("Hello, {name.first} {name.last} AKA {nick}!",
- // | {
- // | nick: "Bob",
- // | name: {
- // | first: "Robert",
- // | middle: "X",
- // | last: "Cringely"
- // | }
- // | });
- // | // returns: Hello, Robert Cringely AKA Bob!
- // example:
- // | // uses an array for substitutions:
- // | lang.replace("Hello, {0} {2}!",
- // | ["Robert", "X", "Cringely"]);
- // | // returns: Hello, Robert Cringely!
- // example:
- // | // uses a function for substitutions:
- // | function sum(a){
- // | var t = 0;
- // | arrayforEach(a, function(x){ t += x; });
- // | return t;
- // | }
- // | lang.replace(
- // | "{count} payments averaging {avg} USD per payment.",
- // | lang.hitch(
- // | { payments: [11, 16, 12] },
- // | function(_, key){
- // | switch(key){
- // | case "count": return this.payments.length;
- // | case "min": return Math.min.apply(Math, this.payments);
- // | case "max": return Math.max.apply(Math, this.payments);
- // | case "sum": return sum(this.payments);
- // | case "avg": return sum(this.payments) / this.payments.length;
- // | }
- // | }
- // | )
- // | );
- // | // prints: 3 payments averaging 13 USD per payment.
- // example:
- // | // uses an alternative PHP-like pattern for substitutions:
- // | lang.replace("Hello, ${0} ${2}!",
- // | ["Robert", "X", "Cringely"], /\$\{([^\}]+)\}/g);
- // | // returns: Hello, Robert Cringely!
- return tmpl.replace(pattern || _pattern, lang.isFunction(map) ?
- map : function(_, k){ return lang.getObject(k, false, map); });
- }
- };
- 1 && lang.mixin(dojo, lang);
- return lang;
- });
- },
- 'dojo/request/util':function(){
- define("dojo/request/util", [
- 'exports',
- '../errors/RequestError',
- '../errors/CancelError',
- '../Deferred',
- '../io-query',
- '../_base/array',
- '../_base/lang'
- ], function(exports, RequestError, CancelError, Deferred, ioQuery, array, lang){
- exports.deepCopy = function deepCopy(target, source){
- for(var name in source){
- var tval = target[name],
- sval = source[name];
- if(tval !== sval){
- if(tval && typeof tval === 'object' && sval && typeof sval === 'object'){
- exports.deepCopy(tval, sval);
- }else{
- target[name] = sval;
- }
- }
- }
- return target;
- };
- exports.deepCreate = function deepCreate(source, properties){
- properties = properties || {};
- var target = lang.delegate(source),
- name, value;
- for(name in source){
- value = source[name];
- if(value && typeof value === 'object'){
- target[name] = exports.deepCreate(value, properties[name]);
- }
- }
- return exports.deepCopy(target, properties);
- };
- var freeze = Object.freeze || function(obj){ return obj; };
- function okHandler(response){
- return freeze(response);
- }
- exports.deferred = function deferred(response, cancel, isValid, isReady, handleResponse, last){
- var def = new Deferred(function(reason){
- cancel && cancel(def, response);
- if(!reason || !(reason instanceof RequestError) && !(reason instanceof CancelError)){
- return new CancelError('Request canceled', response);
- }
- return reason;
- });
- def.response = response;
- def.isValid = isValid;
- def.isReady = isReady;
- def.handleResponse = handleResponse;
- function errHandler(error){
- error.response = response;
- throw error;
- }
- var responsePromise = def.then(okHandler).otherwise(errHandler);
- if(exports.notify){
- responsePromise.then(
- lang.hitch(exports.notify, 'emit', 'load'),
- lang.hitch(exports.notify, 'emit', 'error')
- );
- }
- var dataPromise = responsePromise.then(function(response){
- return response.data || response.text;
- });
- var promise = freeze(lang.delegate(dataPromise, {
- response: responsePromise
- }));
- if(last){
- def.then(function(response){
- last.call(def, response);
- }, function(error){
- last.call(def, response, error);
- });
- }
- def.promise = promise;
- def.then = promise.then;
- return def;
- };
- exports.addCommonMethods = function addCommonMethods(provider, methods){
- array.forEach(methods||['GET', 'POST', 'PUT', 'DELETE'], function(method){
- provider[(method === 'DELETE' ? 'DEL' : method).toLowerCase()] = function(url, options){
- options = lang.delegate(options||{});
- options.method = method;
- return provider(url, options);
- };
- });
- };
- exports.parseArgs = function parseArgs(url, options, skipData){
- var data = options.data,
- query = options.query;
-
- if(data && !skipData){
- if(typeof data === 'object'){
- options.data = ioQuery.objectToQuery(data);
- }
- }
- if(query){
- if(typeof query === 'object'){
- query = ioQuery.objectToQuery(query);
- }
- if(options.preventCache){
- query += (query ? '&' : '') + 'request.preventCache=' + (+(new Date));
- }
- }else if(options.preventCache){
- query = 'request.preventCache=' + (+(new Date));
- }
- if(url && query){
- url += (~url.indexOf('?') ? '&' : '?') + query;
- }
- return {
- url: url,
- options: options,
- getHeader: function(headerName){ return null; }
- };
- };
- exports.checkStatus = function(stat){
- stat = stat || 0;
- return (stat >= 200 && stat < 300) || // allow any 2XX response code
- stat === 304 || // or, get it out of the cache
- stat === 1223 || // or, Internet Explorer mangled the status code
- !stat; // or, we're Titanium/browser chrome/chrome extension requesting a local file
- };
- });
- },
- 'dojo/Evented':function(){
- define("dojo/Evented", ["./aspect", "./on"], function(aspect, on){
- // module:
- // dojo/Evented
- "use strict";
- var after = aspect.after;
- function Evented(){
- // summary:
- // A class that can be used as a mixin or base class,
- // to add on() and emit() methods to a class
- // for listening for events and emitting events:
- //
- // | define(["dojo/Evented"], function(Evented){
- // | var EventedWidget = dojo.declare([Evented, dijit._Widget], {...});
- // | widget = new EventedWidget();
- // | widget.on("open", function(event){
- // | ... do something with event
- // | });
- // |
- // | widget.emit("open", {name:"some event", ...});
- }
- Evented.prototype = {
- on: function(type, listener){
- return on.parse(this, type, listener, function(target, type){
- return after(target, 'on' + type, listener, true);
- });
- },
- emit: function(type, event){
- var args = [this];
- args.push.apply(args, arguments);
- return on.emit.apply(on, args);
- }
- };
- return Evented;
- });
- },
- 'dojo/mouse':function(){
- define("dojo/mouse", ["./_base/kernel", "./on", "./has", "./dom", "./_base/window"], function(dojo, on, has, dom, win){
- // module:
- // dojo/mouse
- has.add("dom-quirks", win.doc && win.doc.compatMode == "BackCompat");
- has.add("events-mouseenter", win.doc && "onmouseenter" in win.doc.createElement("div"));
- has.add("events-mousewheel", win.doc && 'onmousewheel' in win.doc);
- var mouseButtons;
- if((has("dom-quirks") && has("ie")) || !has("dom-addeventlistener")){
- mouseButtons = {
- LEFT: 1,
- MIDDLE: 4,
- RIGHT: 2,
- // helper functions
- isButton: function(e, button){ return e.button & button; },
- isLeft: function(e){ return e.button & 1; },
- isMiddle: function(e){ return e.button & 4; },
- isRight: function(e){ return e.button & 2; }
- };
- }else{
- mouseButtons = {
- LEFT: 0,
- MIDDLE: 1,
- RIGHT: 2,
- // helper functions
- isButton: function(e, button){ return e.button == button; },
- isLeft: function(e){ return e.button == 0; },
- isMiddle: function(e){ return e.button == 1; },
- isRight: function(e){ return e.button == 2; }
- };
- }
- dojo.mouseButtons = mouseButtons;
- /*=====
- dojo.mouseButtons = {
- // LEFT: Number
- // Numeric value of the left mouse button for the platform.
- LEFT: 0,
- // MIDDLE: Number
- // Numeric value of the middle mouse button for the platform.
- MIDDLE: 1,
- // RIGHT: Number
- // Numeric value of the right mouse button for the platform.
- RIGHT: 2,
- isButton: function(e, button){
- // summary:
- // Checks an event object for a pressed button
- // e: Event
- // Event object to examine
- // button: Number
- // The button value (example: dojo.mouseButton.LEFT)
- return e.button == button; // Boolean
- },
- isLeft: function(e){
- // summary:
- // Checks an event object for the pressed left button
- // e: Event
- // Event object to examine
- return e.button == 0; // Boolean
- },
- isMiddle: function(e){
- // summary:
- // Checks an event object for the pressed middle button
- // e: Event
- // Event object to examine
- return e.button == 1; // Boolean
- },
- isRight: function(e){
- // summary:
- // Checks an event object for the pressed right button
- // e: Event
- // Event object to examine
- return e.button == 2; // Boolean
- }
- };
- =====*/
- function eventHandler(type, selectHandler){
- // emulation of mouseenter/leave with mouseover/out using descendant checking
- var handler = function(node, listener){
- return on(node, type, function(evt){
- if(selectHandler){
- return selectHandler(evt, listener);
- }
- if(!dom.isDescendant(evt.relatedTarget, node)){
- return listener.call(this, evt);
- }
- });
- };
- handler.bubble = function(select){
- return eventHandler(type, function(evt, listener){
- // using a selector, use the select function to determine if the mouse moved inside the selector and was previously outside the selector
- var target = select(evt.target);
- var relatedTarget = evt.relatedTarget;
- if(target && (target != (relatedTarget && relatedTarget.nodeType == 1 && select(relatedTarget)))){
- return listener.call(target, evt);
- }
- });
- };
- return handler;
- }
- var wheel;
- if(has("events-mousewheel")){
- wheel = 'mousewheel';
- }else{ //firefox
- wheel = function(node, listener){
- return on(node, 'DOMMouseScroll', function(evt){
- evt.wheelDelta = -evt.detail;
- listener.call(this, evt);
- });
- };
- }
- return {
- // summary:
- // This module provide mouse event handling utility functions and exports
- // mouseenter and mouseleave event emulation.
- // example:
- // To use these events, you register a mouseenter like this:
- // | define(["dojo/on", dojo/mouse"], function(on, mouse){
- // | on(targetNode, mouse.enter, function(event){
- // | dojo.addClass(targetNode, "highlighted");
- // | });
- // | on(targetNode, mouse.leave, function(event){
- // | dojo.removeClass(targetNode, "highlighted");
- // | });
- _eventHandler: eventHandler, // for dojo/touch
- // enter: Synthetic Event
- // This is an extension event for the mouseenter that IE provides, emulating the
- // behavior on other browsers.
- enter: eventHandler("mouseover"),
- // leave: Synthetic Event
- // This is an extension event for the mouseleave that IE provides, emulating the
- // behavior on other browsers.
- leave: eventHandler("mouseout"),
- // wheel: Normalized Mouse Wheel Event
- // This is an extension event for the mousewheel that non-Mozilla browsers provide,
- // emulating the behavior on Mozilla based browsers.
- wheel: wheel,
- isLeft: mouseButtons.isLeft,
- /*=====
- isLeft: function(){
- // summary:
- // Test an event object (from a mousedown event) to see if the left button was pressed.
- },
- =====*/
- isMiddle: mouseButtons.isMiddle,
- /*=====
- isMiddle: function(){
- // summary:
- // Test an event object (from a mousedown event) to see if the middle button was pressed.
- },
- =====*/
- isRight: mouseButtons.isRight
- /*=====
- , isRight: function(){
- // summary:
- // Test an event object (from a mousedown event) to see if the right button was pressed.
- }
- =====*/
- };
- });
- },
- 'dojo/topic':function(){
- define("dojo/topic", ["./Evented"], function(Evented){
- // module:
- // dojo/topic
- var hub = new Evented;
- return {
- // summary:
- // Pubsub hub.
- // example:
- // | topic.subscribe("some/topic", function(event){
- // | ... do something with event
- // | });
- // | topic.publish("some/topic", {name:"some event", ...});
- publish: function(topic, event){
- // summary:
- // Publishes a message to a topic on the pub/sub hub. All arguments after
- // the first will be passed to the subscribers, so any number of arguments
- // can be provided (not just event).
- // topic: String
- // The name of the topic to publish to
- // event: Object
- // An event to distribute to the topic listeners
- return hub.emit.apply(hub, arguments);
- },
- subscribe: function(topic, listener){
- // summary:
- // Subscribes to a topic on the pub/sub hub
- // topic: String
- // The topic to subscribe to
- // listener: Function
- // A function to call when a message is published to the given topic
- return hub.on.apply(hub, arguments);
- }
- };
- });
- },
- 'dojo/_base/xhr':function(){
- define("dojo/_base/xhr", [
- "./kernel",
- "./sniff",
- "require",
- "../io-query",
- /*===== "./declare", =====*/
- "../dom",
- "../dom-form",
- "./Deferred",
- "./config",
- "./json",
- "./lang",
- "./array",
- "../on",
- "../aspect",
- "../request/watch",
- "../request/xhr",
- "../request/util"
- ], function(dojo, has, require, ioq, /*===== declare, =====*/ dom, domForm, Deferred, config, json, lang, array, on, aspect, watch, _xhr, util){
- // module:
- // dojo/_base/xhr
- /*=====
- dojo._xhrObj = function(){
- // summary:
- // does the work of portably generating a new XMLHTTPRequest object.
- };
- =====*/
- dojo._xhrObj = _xhr._create;
- var cfg = dojo.config;
- // mix in io-query and dom-form
- dojo.objectToQuery = ioq.objectToQuery;
- dojo.queryToObject = ioq.queryToObject;
- dojo.fieldToObject = domForm.fieldToObject;
- dojo.formToObject = domForm.toObject;
- dojo.formToQuery = domForm.toQuery;
- dojo.formToJson = domForm.toJson;
- // need to block async callbacks from snatching this thread as the result
- // of an async callback might call another sync XHR, this hangs khtml forever
- // must checked by watchInFlight()
- dojo._blockAsync = false;
- // MOW: remove dojo._contentHandlers alias in 2.0
- var handlers = dojo._contentHandlers = dojo.contentHandlers = {
- // summary:
- // A map of available XHR transport handle types. Name matches the
- // `handleAs` attribute passed to XHR calls.
- // description:
- // A map of available XHR transport handle types. Name matches the
- // `handleAs` attribute passed to XHR calls. Each contentHandler is
- // called, passing the xhr object for manipulation. The return value
- // from the contentHandler will be passed to the `load` or `handle`
- // functions defined in the original xhr call.
- // example:
- // Creating a custom content-handler:
- // | xhr.contentHandlers.makeCaps = function(xhr){
- // | return xhr.responseText.toUpperCase();
- // | }
- // | // and later:
- // | dojo.xhrGet({
- // | url:"foo.txt",
- // | handleAs:"makeCaps",
- // | load: function(data){ /* data is a toUpper version of foo.txt */ }
- // | });
- "text": function(xhr){
- // summary:
- // A contentHandler which simply returns the plaintext response data
- return xhr.responseText;
- },
- "json": function(xhr){
- // summary:
- // A contentHandler which returns a JavaScript object created from the response data
- return json.fromJson(xhr.responseText || null);
- },
- "json-comment-filtered": function(xhr){
- // summary:
- // A contentHandler which expects comment-filtered JSON.
- // description:
- // A contentHandler which expects comment-filtered JSON.
- // the json-comment-filtered option was implemented to prevent
- // "JavaScript Hijacking", but it is less secure than standard JSON. Use
- // standard JSON instead. JSON prefixing can be used to subvert hijacking.
- //
- // Will throw a notice suggesting to use application/json mimetype, as
- // json-commenting can introduce security issues. To decrease the chances of hijacking,
- // use the standard `json` contentHandler, and prefix your "JSON" with: {}&&
- //
- // use djConfig.useCommentedJson = true to turn off the notice
- if(!config.useCommentedJson){
- console.warn("Consider using the standard mimetype:application/json."
- + " json-commenting can introduce security issues. To"
- + " decrease the chances of hijacking, use the standard the 'json' handler and"
- + " prefix your json with: {}&&\n"
- + "Use djConfig.useCommentedJson=true to turn off this message.");
- }
- var value = xhr.responseText;
- var cStartIdx = value.indexOf("\/*");
- var cEndIdx = value.lastIndexOf("*\/");
- if(cStartIdx == -1 || cEndIdx == -1){
- throw new Error("JSON was not comment filtered");
- }
- return json.fromJson(value.substring(cStartIdx+2, cEndIdx));
- },
- "javascript": function(xhr){
- // summary:
- // A contentHandler which evaluates the response data, expecting it to be valid JavaScript
- // FIXME: try Moz and IE specific eval variants?
- return dojo.eval(xhr.responseText);
- },
- "xml": function(xhr){
- // summary:
- // A contentHandler returning an XML Document parsed from the response data
- var result = xhr.responseXML;
- if(has("ie")){
- if((!result || !result.documentElement)){
- //WARNING: this branch used by the xml handling in dojo.io.iframe,
- //so be sure to test dojo.io.iframe if making changes below.
- var ms = function(n){ return "MSXML" + n + ".DOMDocument"; };
- var dp = ["Microsoft.XMLDOM", ms(6), ms(4), ms(3), ms(2)];
- array.some(dp, function(p){
- try{
- var dom = new ActiveXObject(p);
- dom.async = false;
- dom.loadXML(xhr.responseText);
- result = dom;
- }catch(e){ return false; }
- return true;
- });
- }
- }
- return result; // DOMDocument
- },
- "json-comment-optional": function(xhr){
- // summary:
- // A contentHandler which checks the presence of comment-filtered JSON and
- // alternates between the `json` and `json-comment-filtered` contentHandlers.
- if(xhr.responseText && /^[^{\[]*\/\*/.test(xhr.responseText)){
- return handlers["json-comment-filtered"](xhr);
- }else{
- return handlers["json"](xhr);
- }
- }
- };
- /*=====
- // kwargs function parameter definitions. Assigning to dojo namespace rather than making them local variables
- // because they are used by dojo/io modules too
- dojo.__IoArgs = declare(null, {
- // url: String
- // URL to server endpoint.
- // content: Object?
- // Contains properties with string values. These
- // properties will be serialized as name1=value2 and
- // passed in the request.
- // timeout: Integer?
- // Milliseconds to wait for the response. If this time
- // passes, the then error callbacks are called.
- // form: DOMNode?
- // DOM node for a form. Used to extract the form values
- // and send to the server.
- // preventCache: Boolean?
- // Default is false. If true, then a
- // "dojo.preventCache" parameter is sent in the request
- // with a value that changes with each request
- // (timestamp). Useful only with GET-type requests.
- // handleAs: String?
- // Acceptable values depend on the type of IO
- // transport (see specific IO calls for more information).
- // rawBody: String?
- // Sets the raw body for an HTTP request. If this is used, then the content
- // property is ignored. This is mostly useful for HTTP methods that have
- // a body to their requests, like PUT or POST. This property can be used instead
- // of postData and putData for dojo/_base/xhr.rawXhrPost and dojo/_base/xhr.rawXhrPut respectively.
- // ioPublish: Boolean?
- // Set this explicitly to false to prevent publishing of topics related to
- // IO operations. Otherwise, if djConfig.ioPublish is set to true, topics
- // will be published via dojo/topic.publish() for different phases of an IO operation.
- // See dojo/main.__IoPublish for a list of topics that are published.
- load: function(response, ioArgs){
- // summary:
- // This function will be
- // called on a successful HTTP response code.
- // ioArgs: dojo/main.__IoCallbackArgs
- // Provides additional information about the request.
- // response: Object
- // The response in the format as defined with handleAs.
- },
- error: function(response, ioArgs){
- // summary:
- // This function will
- // be called when the request fails due to a network or server error, the url
- // is invalid, etc. It will also be called if the load or handle callback throws an
- // exception, unless djConfig.debugAtAllCosts is true. This allows deployed applications
- // to continue to run even when a logic error happens in the callback, while making
- // it easier to troubleshoot while in debug mode.
- // ioArgs: dojo/main.__IoCallbackArgs
- // Provides additional information about the request.
- // response: Object
- // The response in the format as defined with handleAs.
- },
- handle: function(loadOrError, response, ioArgs){
- // summary:
- // This function will
- // be called at the end of every request, whether or not an error occurs.
- // loadOrError: String
- // Provides a string that tells you whether this function
- // was called because of success (load) or failure (error).
- // response: Object
- // The response in the format as defined with handleAs.
- // ioArgs: dojo/main.__IoCallbackArgs
- // Provides additional information about the request.
- }
- });
- dojo.__IoCallbackArgs = declare(null, {
- // args: Object
- // the original object argument to the IO call.
- // xhr: XMLHttpRequest
- // For XMLHttpRequest calls only, the
- // XMLHttpRequest object that was used for the
- // request.
- // url: String
- // The final URL used for the call. Many times it
- // will be different than the original args.url
- // value.
- // query: String
- // For non-GET requests, the
- // name1=value1&name2=value2 parameters sent up in
- // the request.
- // handleAs: String
- // The final indicator on how the response will be
- // handled.
- // id: String
- // For dojo/io/script calls only, the internal
- // script ID used for the request.
- // canDelete: Boolean
- // For dojo/io/script calls only, indicates
- // whether the script tag that represents the
- // request can be deleted after callbacks have
- // been called. Used internally to know when
- // cleanup can happen on JSONP-type requests.
- // json: Object
- // For dojo/io/script calls only: holds the JSON
- // response for JSONP-type requests. Used
- // internally to hold on to the JSON responses.
- // You should not need to access it directly --
- // the same object should be passed to the success
- // callbacks directly.
- });
- dojo.__IoPublish = declare(null, {
- // summary:
- // This is a list of IO topics that can be published
- // if djConfig.ioPublish is set to true. IO topics can be
- // published for any Input/Output, network operation. So,
- // dojo.xhr, dojo.io.script and dojo.io.iframe can all
- // trigger these topics to be published.
- // start: String
- // "/dojo/io/start" is sent when there are no outstanding IO
- // requests, and a new IO request is started. No arguments
- // are passed with this topic.
- // send: String
- // "/dojo/io/send" is sent whenever a new IO request is started.
- // It passes the dojo.Deferred for the request with the topic.
- // load: String
- // "/dojo/io/load" is sent whenever an IO request has loaded
- // successfully. It passes the response and the dojo.Deferred
- // for the request with the topic.
- // error: String
- // "/dojo/io/error" is sent whenever an IO request has errored.
- // It passes the error and the dojo.Deferred
- // for the request with the topic.
- // done: String
- // "/dojo/io/done" is sent whenever an IO request has completed,
- // either by loading or by erroring. It passes the error and
- // the dojo.Deferred for the request with the topic.
- // stop: String
- // "/dojo/io/stop" is sent when all outstanding IO requests have
- // finished. No arguments are passed with this topic.
- });
- =====*/
- dojo._ioSetArgs = function(/*dojo/main.__IoArgs*/args,
- /*Function*/canceller,
- /*Function*/okHandler,
- /*Function*/errHandler){
- // summary:
- // sets up the Deferred and ioArgs property on the Deferred so it
- // can be used in an io call.
- // args:
- // The args object passed into the public io call. Recognized properties on
- // the args object are:
- // canceller:
- // The canceller function used for the Deferred object. The function
- // will receive one argument, the Deferred object that is related to the
- // canceller.
- // okHandler:
- // The first OK callback to be registered with Deferred. It has the opportunity
- // to transform the OK response. It will receive one argument -- the Deferred
- // object returned from this function.
- // errHandler:
- // The first error callback to be registered with Deferred. It has the opportunity
- // to do cleanup on an error. It will receive two arguments: error (the
- // Error object) and dfd, the Deferred object returned from this function.
- var ioArgs = {args: args, url: args.url};
- //Get values from form if requested.
- var formObject = null;
- if(args.form){
- var form = dom.byId(args.form);
- //IE requires going through getAttributeNode instead of just getAttribute in some form cases,
- //so use it for all. See #2844
- var actnNode = form.getAttributeNode("action");
- ioArgs.url = ioArgs.url || (actnNode ? actnNode.value : null);
- formObject = domForm.toObject(form);
- }
- // set up the query params
- var miArgs = [{}];
- if(formObject){
- // potentially over-ride url-provided params w/ form values
- miArgs.push(formObject);
- }
- if(args.content){
- // stuff in content over-rides what's set by form
- miArgs.push(args.content);
- }
- if(args.preventCache){
- miArgs.push({"dojo.preventCache": new Date().valueOf()});
- }
- ioArgs.query = ioq.objectToQuery(lang.mixin.apply(null, miArgs));
- // .. and the real work of getting the deferred in order, etc.
- ioArgs.handleAs = args.handleAs || "text";
- var d = new Deferred(function(dfd){
- dfd.canceled = true;
- canceller && canceller(dfd);
- var err = dfd.ioArgs.error;
- if(!err){
- err = new Error("request cancelled");
- err.dojoType="cancel";
- dfd.ioArgs.error = err;
- }
- return err;
- });
- d.addCallback(okHandler);
- //Support specifying load, error and handle callback functions from the args.
- //For those callbacks, the "this" object will be the args object.
- //The callbacks will get the deferred result value as the
- //first argument and the ioArgs object as the second argument.
- var ld = args.load;
- if(ld && lang.isFunction(ld)){
- d.addCallback(function(value){
- return ld.call(args, value, ioArgs);
- });
- }
- var err = args.error;
- if(err && lang.isFunction(err)){
- d.addErrback(function(value){
- return err.call(args, value, ioArgs);
- });
- }
- var handle = args.handle;
- if(handle && lang.isFunction(handle)){
- d.addBoth(function(value){
- return handle.call(args, value, ioArgs);
- });
- }
- // Attach error handler last (not including topic publishing)
- // to catch any errors that may have been generated from load
- // or handle functions.
- d.addErrback(function(error){
- return errHandler(error, d);
- });
- //Plug in topic publishing, if dojo.publish is loaded.
- if(cfg.ioPublish && dojo.publish && ioArgs.args.ioPublish !== false){
- d.addCallbacks(
- function(res){
- dojo.publish("/dojo/io/load", [d, res]);
- return res;
- },
- function(res){
- dojo.publish("/dojo/io/error", [d, res]);
- return res;
- }
- );
- d.addBoth(function(res){
- dojo.publish("/dojo/io/done", [d, res]);
- return res;
- });
- }
- d.ioArgs = ioArgs;
- // FIXME: need to wire up the xhr object's abort method to something
- // analogous in the Deferred
- return d;
- };
- var _deferredOk = function(/*Deferred*/dfd){
- // summary:
- // okHandler function for dojo._ioSetArgs call.
- var ret = handlers[dfd.ioArgs.handleAs](dfd.ioArgs.xhr);
- return ret === undefined ? null : ret;
- };
- var _deferError = function(/*Error*/error, /*Deferred*/dfd){
- // summary:
- // errHandler function for dojo._ioSetArgs call.
- if(!dfd.ioArgs.args.failOk){
- console.error(error);
- }
- return error;
- };
- //Use a separate count for knowing if we are starting/stopping io calls.
- var _checkPubCount = function(dfd){
- if(_pubCount <= 0){
- _pubCount = 0;
- if(cfg.ioPublish && dojo.publish && (!dfd || dfd && dfd.ioArgs.args.ioPublish !== false)){
- dojo.publish("/dojo/io/stop");
- }
- }
- };
- var _pubCount = 0;
- aspect.after(watch, "_onAction", function(){
- _pubCount -= 1;
- });
- aspect.after(watch, "_onInFlight", _checkPubCount);
- dojo._ioCancelAll = watch.cancelAll;
- /*=====
- dojo._ioCancelAll = function(){
- // summary:
- // Cancels all pending IO requests, regardless of IO type
- // (xhr, script, iframe).
- };
- =====*/
- dojo._ioNotifyStart = function(/*Deferred*/dfd){
- // summary:
- // If dojo.publish is available, publish topics
- // about the start of a request queue and/or the
- // the beginning of request.
- //
- // Used by IO transports. An IO transport should
- // call this method before making the network connection.
- if(cfg.ioPublish && dojo.publish && dfd.ioArgs.args.ioPublish !== false){
- if(!_pubCount){
- dojo.publish("/dojo/io/start");
- }
- _pubCount += 1;
- dojo.publish("/dojo/io/send", [dfd]);
- }
- };
- dojo._ioWatch = function(dfd, validCheck, ioCheck, resHandle){
- // summary:
- // Watches the io request represented by dfd to see if it completes.
- // dfd: Deferred
- // The Deferred object to watch.
- // validCheck: Function
- // Function used to check if the IO request is still valid. Gets the dfd
- // object as its only argument.
- // ioCheck: Function
- // Function used to check if basic IO call worked. Gets the dfd
- // object as its only argument.
- // resHandle: Function
- // Function used to process response. Gets the dfd
- // object as its only argument.
- var args = dfd.ioArgs.options = dfd.ioArgs.args;
- lang.mixin(dfd, {
- response: dfd.ioArgs,
- isValid: function(response){
- return validCheck(dfd);
- },
- isReady: function(response){
- return ioCheck(dfd);
- },
- handleResponse: function(response){
- return resHandle(dfd);
- }
- });
- watch(dfd);
- _checkPubCount(dfd);
- };
- var _defaultContentType = "application/x-www-form-urlencoded";
- dojo._ioAddQueryToUrl = function(/*dojo.__IoCallbackArgs*/ioArgs){
- // summary:
- // Adds query params discovered by the io deferred construction to the URL.
- // Only use this for operations which are fundamentally GET-type operations.
- if(ioArgs.query.length){
- ioArgs.url += (ioArgs.url.indexOf("?") == -1 ? "?" : "&") + ioArgs.query;
- ioArgs.query = null;
- }
- };
- /*=====
- dojo.__XhrArgs = declare(dojo.__IoArgs, {
- // summary:
- // In addition to the properties listed for the dojo._IoArgs type,
- // the following properties are allowed for dojo.xhr* methods.
- // handleAs: String?
- // Acceptable values are: text (default), json, json-comment-optional,
- // json-comment-filtered, javascript, xml. See `dojo/_base/xhr.contentHandlers`
- // sync: Boolean?
- // false is default. Indicates whether the request should
- // be a synchronous (blocking) request.
- // headers: Object?
- // Additional HTTP headers to send in the request.
- // failOk: Boolean?
- // false is default. Indicates whether a request should be
- // allowed to fail (and therefore no console error message in
- // the event of a failure)
- // contentType: String|Boolean
- // "application/x-www-form-urlencoded" is default. Set to false to
- // prevent a Content-Type header from being sent, or to a string
- // to send a different Content-Type.
- });
- =====*/
- dojo.xhr = function(/*String*/ method, /*dojo.__XhrArgs*/ args, /*Boolean?*/ hasBody){
- // summary:
- // Deprecated. Use dojo/request instead.
- // description:
- // Sends an HTTP request with the given method.
- // See also dojo.xhrGet(), xhrPost(), xhrPut() and dojo.xhrDelete() for shortcuts
- // for those HTTP methods. There are also methods for "raw" PUT and POST methods
- // via dojo.rawXhrPut() and dojo.rawXhrPost() respectively.
- // method:
- // HTTP method to be used, such as GET, POST, PUT, DELETE. Should be uppercase.
- // hasBody:
- // If the request has an HTTP body, then pass true for hasBody.
- var rDfd;
- //Make the Deferred object for this xhr request.
- var dfd = dojo._ioSetArgs(args, function(dfd){
- rDfd && rDfd.cancel();
- }, _deferredOk, _deferError);
- var ioArgs = dfd.ioArgs;
- //Allow for specifying the HTTP body completely.
- if("postData" in args){
- ioArgs.query = args.postData;
- }else if("putData" in args){
- ioArgs.query = args.putData;
- }else if("rawBody" in args){
- ioArgs.query = args.rawBody;
- }else if((arguments.length > 2 && !hasBody) || "POST|PUT".indexOf(method.toUpperCase()) === -1){
- //Check for hasBody being passed. If no hasBody,
- //then only append query string if not a POST or PUT request.
- dojo._ioAddQueryToUrl(ioArgs);
- }
- var options = {
- method: method,
- handleAs: "text",
- timeout: args.timeout,
- withCredentials: args.withCredentials,
- ioArgs: ioArgs
- };
- if(typeof args.headers !== 'undefined'){
- options.headers = args.headers;
- }
- if(typeof args.contentType !== 'undefined'){
- if(!options.headers){
- options.headers = {};
- }
- options.headers['Content-Type'] = args.contentType;
- }
- if(typeof ioArgs.query !== 'undefined'){
- options.data = ioArgs.query;
- }
- if(typeof args.sync !== 'undefined'){
- options.sync = args.sync;
- }
- dojo._ioNotifyStart(dfd);
- try{
- rDfd = _xhr(ioArgs.url, options, true);
- }catch(e){
- // If XHR creation fails, dojo/request/xhr throws
- // When this happens, cancel the deferred
- dfd.cancel();
- return dfd;
- }
- // sync ioArgs
- dfd.ioArgs.xhr = rDfd.response.xhr;
- rDfd.then(function(){
- dfd.resolve(dfd);
- }).otherwise(function(error){
- ioArgs.error = error;
- if(error.response){
- error.status = error.response.status;
- error.responseText = error.response.text;
- error.xhr = error.response.xhr;
- }
- dfd.reject(error);
- });
- return dfd; // dojo/_base/Deferred
- };
- dojo.xhrGet = function(/*dojo.__XhrArgs*/ args){
- // summary:
- // Sends an HTTP GET request to the server.
- return dojo.xhr("GET", args); // dojo/_base/Deferred
- };
- dojo.rawXhrPost = dojo.xhrPost = function(/*dojo.__XhrArgs*/ args){
- // summary:
- // Sends an HTTP POST request to the server. In addition to the properties
- // listed for the dojo.__XhrArgs type, the following property is allowed:
- // postData:
- // String. Send raw data in the body of the POST request.
- return dojo.xhr("POST", args, true); // dojo/_base/Deferred
- };
- dojo.rawXhrPut = dojo.xhrPut = function(/*dojo.__XhrArgs*/ args){
- // summary:
- // Sends an HTTP PUT request to the server. In addition to the properties
- // listed for the dojo.__XhrArgs type, the following property is allowed:
- // putData:
- // String. Send raw data in the body of the PUT request.
- return dojo.xhr("PUT", args, true); // dojo/_base/Deferred
- };
- dojo.xhrDelete = function(/*dojo.__XhrArgs*/ args){
- // summary:
- // Sends an HTTP DELETE request to the server.
- return dojo.xhr("DELETE", args); // dojo/_base/Deferred
- };
- /*
- dojo.wrapForm = function(formNode){
- // summary:
- // A replacement for FormBind, but not implemented yet.
- // FIXME: need to think harder about what extensions to this we might
- // want. What should we allow folks to do w/ this? What events to
- // set/send?
- throw new Error("dojo.wrapForm not yet implemented");
- }
- */
- dojo._isDocumentOk = function(x){
- return util.checkStatus(x.status);
- };
- dojo._getText = function(url){
- var result;
- dojo.xhrGet({url:url, sync:true, load:function(text){
- result = text;
- }});
- return result;
- };
- // Add aliases for static functions to dojo.xhr since dojo.xhr is what's returned from this module
- lang.mixin(dojo.xhr, {
- _xhrObj: dojo._xhrObj,
- fieldToObject: domForm.fieldToObject,
- formToObject: domForm.toObject,
- objectToQuery: ioq.objectToQuery,
- formToQuery: domForm.toQuery,
- formToJson: domForm.toJson,
- queryToObject: ioq.queryToObject,
- contentHandlers: handlers,
- _ioSetArgs: dojo._ioSetArgs,
- _ioCancelAll: dojo._ioCancelAll,
- _ioNotifyStart: dojo._ioNotifyStart,
- _ioWatch: dojo._ioWatch,
- _ioAddQueryToUrl: dojo._ioAddQueryToUrl,
- _isDocumentOk: dojo._isDocumentOk,
- _getText: dojo._getText,
- get: dojo.xhrGet,
- post: dojo.xhrPost,
- put: dojo.xhrPut,
- del: dojo.xhrDelete // because "delete" is a reserved word
- });
- return dojo.xhr;
- });
- },
- 'dojo/loadInit':function(){
- define("dojo/loadInit", ["./_base/loader"], function(loader){
- return {
- dynamic:0,
- normalize:function(id){return id;},
- load:loader.loadInit
- };
- });
- },
- 'dojo/_base/unload':function(){
- define(["./kernel", "./lang", "../on"], function(dojo, lang, on){
- // module:
- // dojo/unload
- var win = window;
- var unload = {
- // summary:
- // This module contains the document and window unload detection API.
- addOnWindowUnload: function(/*Object|Function?*/ obj, /*String|Function?*/ functionName){
- // summary:
- // registers a function to be triggered when window.onunload
- // fires.
- // description:
- // The first time that addOnWindowUnload is called Dojo
- // will register a page listener to trigger your unload
- // handler with. Note that registering these handlers may
- // destroy "fastback" page caching in browsers that support
- // it. Be careful trying to modify the DOM or access
- // JavaScript properties during this phase of page unloading:
- // they may not always be available. Consider
- // addOnUnload() if you need to modify the DOM or do
- // heavy JavaScript work since it fires at the equivalent of
- // the page's "onbeforeunload" event.
- // example:
- // | unload.addOnWindowUnload(functionPointer)
- // | unload.addOnWindowUnload(object, "functionName");
- // | unload.addOnWindowUnload(object, function(){ /* ... */});
- if (!dojo.windowUnloaded){
- on(win, "unload", (dojo.windowUnloaded = function(){
- // summary:
- // signal fired by impending window destruction. You may use
- // dojo.addOnWindowUnload() to register a listener for this
- // event. NOTE: if you wish to dojo.connect() to this method
- // to perform page/application cleanup, be aware that this
- // event WILL NOT fire if no handler has been registered with
- // addOnWindowUnload(). This behavior started in Dojo 1.3.
- // Previous versions always triggered windowUnloaded(). See
- // addOnWindowUnload for more info.
- }));
- }
- on(win, "unload", lang.hitch(obj, functionName));
- },
- addOnUnload: function(/*Object?|Function?*/ obj, /*String|Function?*/ functionName){
- // summary:
- // registers a function to be triggered when the page unloads.
- // description:
- // The first time that addOnUnload is called Dojo will
- // register a page listener to trigger your unload handler
- // with.
- //
- // In a browser environment, the functions will be triggered
- // during the window.onbeforeunload event. Be careful of doing
- // too much work in an unload handler. onbeforeunload can be
- // triggered if a link to download a file is clicked, or if
- // the link is a javascript: link. In these cases, the
- // onbeforeunload event fires, but the document is not
- // actually destroyed. So be careful about doing destructive
- // operations in a dojo.addOnUnload callback.
- //
- // Further note that calling dojo.addOnUnload will prevent
- // browsers from using a "fast back" cache to make page
- // loading via back button instantaneous.
- // example:
- // | dojo.addOnUnload(functionPointer)
- // | dojo.addOnUnload(object, "functionName")
- // | dojo.addOnUnload(object, function(){ /* ... */});
- on(win, "beforeunload", lang.hitch(obj, functionName));
- }
- };
- dojo.addOnWindowUnload = unload.addOnWindowUnload;
- dojo.addOnUnload = unload.addOnUnload;
- return unload;
- });
- },
- 'dojo/Deferred':function(){
- define([
- "./has",
- "./_base/lang",
- "./errors/CancelError",
- "./promise/Promise",
- "./promise/instrumentation"
- ], function(has, lang, CancelError, Promise, instrumentation){
- "use strict";
- // module:
- // dojo/Deferred
- var PROGRESS = 0,
- RESOLVED = 1,
- REJECTED = 2;
- var FULFILLED_ERROR_MESSAGE = "This deferred has already been fulfilled.";
- var freezeObject = Object.freeze || function(){};
- var signalWaiting = function(waiting, type, result, rejection, deferred){
- if( 1 ){
- if(type === REJECTED && Deferred.instrumentRejected && waiting.length === 0){
- Deferred.instrumentRejected(result, false, rejection, deferred);
- }
- }
- for(var i = 0; i < waiting.length; i++){
- signalListener(waiting[i], type, result, rejection);
- }
- };
- var signalListener = function(listener, type, result, rejection){
- var func = listener[type];
- var deferred = listener.deferred;
- if(func){
- try{
- var newResult = func(result);
- if(type === PROGRESS){
- if(typeof newResult !== "undefined"){
- signalDeferred(deferred, type, newResult);
- }
- }else{
- if(newResult && typeof newResult.then === "function"){
- listener.cancel = newResult.cancel;
- newResult.then(
- // Only make resolvers if they're actually going to be used
- makeDeferredSignaler(deferred, RESOLVED),
- makeDeferredSignaler(deferred, REJECTED),
- makeDeferredSignaler(deferred, PROGRESS));
- return;
- }
- signalDeferred(deferred, RESOLVED, newResult);
- }
- }catch(error){
- signalDeferred(deferred, REJECTED, error);
- }
- }else{
- signalDeferred(deferred, type, result);
- }
- if( 1 ){
- if(type === REJECTED && Deferred.instrumentRejected){
- Deferred.instrumentRejected(result, !!func, rejection, deferred.promise);
- }
- }
- };
- var makeDeferredSignaler = function(deferred, type){
- return function(value){
- signalDeferred(deferred, type, value);
- };
- };
- var signalDeferred = function(deferred, type, result){
- if(!deferred.isCanceled()){
- switch(type){
- case PROGRESS:
- deferred.progress(result);
- break;
- case RESOLVED:
- deferred.resolve(result);
- break;
- case REJECTED:
- deferred.reject(result);
- break;
- }
- }
- };
- var Deferred = function(canceler){
- // summary:
- // Creates a new deferred. This API is preferred over
- // `dojo/_base/Deferred`.
- // description:
- // Creates a new deferred, as an abstraction over (primarily)
- // asynchronous operations. The deferred is the private interface
- // that should not be returned to calling code. That's what the
- // `promise` is for. See `dojo/promise/Promise`.
- // canceler: Function?
- // Will be invoked if the deferred is canceled. The canceler
- // receives the reason the deferred was canceled as its argument.
- // The deferred is rejected with its return value, or a new
- // `dojo/errors/CancelError` instance.
- // promise: dojo/promise/Promise
- // The public promise object that clients can add callbacks to.
- var promise = this.promise = new Promise();
- var deferred = this;
- var fulfilled, result, rejection;
- var canceled = false;
- var waiting = [];
- if( 1 && Error.captureStackTrace){
- Error.captureStackTrace(deferred, Deferred);
- Error.captureStackTrace(promise, Deferred);
- }
- this.isResolved = promise.isResolved = function(){
- // summary:
- // Checks whether the deferred has been resolved.
- // returns: Boolean
- return fulfilled === RESOLVED;
- };
- this.isRejected = promise.isRejected = function(){
- // summary:
- // Checks whether the deferred has been rejected.
- // returns: Boolean
- return fulfilled === REJECTED;
- };
- this.isFulfilled = promise.isFulfilled = function(){
- // summary:
- // Checks whether the deferred has been resolved or rejected.
- // returns: Boolean
- return !!fulfilled;
- };
- this.isCanceled = promise.isCanceled = function(){
- // summary:
- // Checks whether the deferred has been canceled.
- // returns: Boolean
- return canceled;
- };
- this.progress = function(update, strict){
- // summary:
- // Emit a progress update on the deferred.
- // description:
- // Emit a progress update on the deferred. Progress updates
- // can be used to communicate updates about the asynchronous
- // operation before it has finished.
- // update: any
- // The progress update. Passed to progbacks.
- // strict: Boolean?
- // If strict, will throw an error if the deferred has already
- // been fulfilled and consequently no progress can be emitted.
- // returns: dojo/promise/Promise
- // Returns the original promise for the deferred.
- if(!fulfilled){
- signalWaiting(waiting, PROGRESS, update, null, deferred);
- return promise;
- }else if(strict === true){
- throw new Error(FULFILLED_ERROR_MESSAGE);
- }else{
- return promise;
- }
- };
- this.resolve = function(value, strict){
- // summary:
- // Resolve the deferred.
- // description:
- // Resolve the deferred, putting it in a success state.
- // value: any
- // The result of the deferred. Passed to callbacks.
- // strict: Boolean?
- // If strict, will throw an error if the deferred has already
- // been fulfilled and consequently cannot be resolved.
- // returns: dojo/promise/Promise
- // Returns the original promise for the deferred.
- if(!fulfilled){
- // Set fulfilled, store value. After signaling waiting listeners unset
- // waiting.
- signalWaiting(waiting, fulfilled = RESOLVED, result = value, null, deferred);
- waiting = null;
- return promise;
- }else if(strict === true){
- throw new Error(FULFILLED_ERROR_MESSAGE);
- }else{
- return promise;
- }
- };
- var reject = this.reject = function(error, strict){
- // summary:
- // Reject the deferred.
- // description:
- // Reject the deferred, putting it in an error state.
- // error: any
- // The error result of the deferred. Passed to errbacks.
- // strict: Boolean?
- // If strict, will throw an error if the deferred has already
- // been fulfilled and consequently cannot be rejected.
- // returns: dojo/promise/Promise
- // Returns the original promise for the deferred.
- if(!fulfilled){
- if( 1 && Error.captureStackTrace){
- Error.captureStackTrace(rejection = {}, reject);
- }
- signalWaiting(waiting, fulfilled = REJECTED, result = error, rejection, deferred);
- waiting = null;
- return promise;
- }else if(strict === true){
- throw new Error(FULFILLED_ERROR_MESSAGE);
- }else{
- return promise;
- }
- };
- this.then = promise.then = function(callback, errback, progback){
- // summary:
- // Add new callbacks to the deferred.
- // description:
- // Add new callbacks to the deferred. Callbacks can be added
- // before or after the deferred is fulfilled.
- // callback: Function?
- // Callback to be invoked when the promise is resolved.
- // Receives the resolution value.
- // errback: Function?
- // Callback to be invoked when the promise is rejected.
- // Receives the rejection error.
- // progback: Function?
- // Callback to be invoked when the promise emits a progress
- // update. Receives the progress update.
- // returns: dojo/promise/Promise
- // Returns a new promise for the result of the callback(s).
- // This can be used for chaining many asynchronous operations.
- var listener = [progback, callback, errback];
- // Ensure we cancel the promise we're waiting for, or if callback/errback
- // have returned a promise, cancel that one.
- listener.cancel = promise.cancel;
- listener.deferred = new Deferred(function(reason){
- // Check whether cancel is really available, returned promises are not
- // required to expose `cancel`
- return listener.cancel && listener.cancel(reason);
- });
- if(fulfilled && !waiting){
- signalListener(listener, fulfilled, result, rejection);
- }else{
- waiting.push(listener);
- }
- return listener.deferred.promise;
- };
- this.cancel = promise.cancel = function(reason, strict){
- // summary:
- // Inform the deferred it may cancel its asynchronous operation.
- // description:
- // Inform the deferred it may cancel its asynchronous operation.
- // The deferred's (optional) canceler is invoked and the
- // deferred will be left in a rejected state. Can affect other
- // promises that originate with the same deferred.
- // reason: any
- // A message that may be sent to the deferred's canceler,
- // explaining why it's being canceled.
- // strict: Boolean?
- // If strict, will throw an error if the deferred has already
- // been fulfilled and consequently cannot be canceled.
- // returns: any
- // Returns the rejection reason if the deferred was canceled
- // normally.
- if(!fulfilled){
- // Cancel can be called even after the deferred is fulfilled
- if(canceler){
- var returnedReason = canceler(reason);
- reason = typeof returnedReason === "undefined" ? reason : returnedReason;
- }
- canceled = true;
- if(!fulfilled){
- // Allow canceler to provide its own reason, but fall back to a CancelError
- if(typeof reason === "undefined"){
- reason = new CancelError();
- }
- reject(reason);
- return reason;
- }else if(fulfilled === REJECTED && result === reason){
- return reason;
- }
- }else if(strict === true){
- throw new Error(FULFILLED_ERROR_MESSAGE);
- }
- };
- freezeObject(promise);
- };
- Deferred.prototype.toString = function(){
- // returns: String
- // Returns `[object Deferred]`.
- return "[object Deferred]";
- };
- if(instrumentation){
- instrumentation(Deferred);
- }
- return Deferred;
- });
- },
- 'dojo/_base/NodeList':function(){
- define("dojo/_base/NodeList", ["./kernel", "../query", "./array", "./html", "../NodeList-dom"], function(dojo, query, array){
- // module:
- // dojo/_base/NodeList
- /*=====
- return {
- // summary:
- // This module extends dojo/NodeList with the legacy connect(), coords(),
- // blur(), focus(), change(), click(), error(), keydown(), keypress(),
- // keyup(), load(), mousedown(), mouseenter(), mouseleave(), mousemove(),
- // mouseout(), mouseover(), mouseup(), and submit() methods.
- };
- =====*/
-
- var NodeList = query.NodeList,
- nlp = NodeList.prototype;
- nlp.connect = NodeList._adaptAsForEach(function(){
- // don't bind early to dojo.connect since we no longer explicitly depend on it
- return dojo.connect.apply(this, arguments);
- });
- /*=====
- nlp.connect = function(methodName, objOrFunc, funcName){
- // summary:
- // Attach event handlers to every item of the NodeList. Uses dojo.connect()
- // so event properties are normalized.
- //
- // Application must manually require() "dojo/_base/connect" before using this method.
- // methodName: String
- // the name of the method to attach to. For DOM events, this should be
- // the lower-case name of the event
- // objOrFunc: Object|Function|String
- // if 2 arguments are passed (methodName, objOrFunc), objOrFunc should
- // reference a function or be the name of the function in the global
- // namespace to attach. If 3 arguments are provided
- // (methodName, objOrFunc, funcName), objOrFunc must be the scope to
- // locate the bound function in
- // funcName: String?
- // optional. A string naming the function in objOrFunc to bind to the
- // event. May also be a function reference.
- // example:
- // add an onclick handler to every button on the page
- // | query("div:nth-child(odd)").connect("onclick", function(e){
- // | console.log("clicked!");
- // | });
- // example:
- // attach foo.bar() to every odd div's onmouseover
- // | query("div:nth-child(odd)").connect("onmouseover", foo, "bar");
- return null; // NodeList
- };
- =====*/
- nlp.coords = NodeList._adaptAsMap(dojo.coords);
- /*=====
- nlp.coords = function(){
- // summary:
- // Deprecated: Use position() for border-box x/y/w/h
- // or marginBox() for margin-box w/h/l/t.
- // Returns the box objects of all elements in a node list as
- // an Array (*not* a NodeList). Acts like `domGeom.coords`, though assumes
- // the node passed is each node in this list.
- return []; // Array
- };
- =====*/
- NodeList.events = [
- // summary:
- // list of all DOM events used in NodeList
- "blur", "focus", "change", "click", "error", "keydown", "keypress",
- "keyup", "load", "mousedown", "mouseenter", "mouseleave", "mousemove",
- "mouseout", "mouseover", "mouseup", "submit"
- ];
- // FIXME: pseudo-doc the above automatically generated on-event functions
- // syntactic sugar for DOM events
- array.forEach(NodeList.events, function(evt){
- var _oe = "on" + evt;
- nlp[_oe] = function(a, b){
- return this.connect(_oe, a, b);
- };
- // FIXME: should these events trigger publishes?
- /*
- return (a ? this.connect(_oe, a, b) :
- this.forEach(function(n){
- // FIXME:
- // listeners get buried by
- // addEventListener and can't be dug back
- // out to be triggered externally.
- // see:
- // http://developer.mozilla.org/en/docs/DOM:element
- console.log(n, evt, _oe);
- // FIXME: need synthetic event support!
- var _e = { target: n, faux: true, type: evt };
- // dojo._event_listener._synthesizeEvent({}, { target: n, faux: true, type: evt });
- try{ n[evt](_e); }catch(e){ console.log(e); }
- try{ n[_oe](_e); }catch(e){ console.log(e); }
- })
- );
- */
- }
- );
- dojo.NodeList = NodeList;
- return NodeList;
- });
- },
- 'dojo/_base/Color':function(){
- define(["./kernel", "./lang", "./array", "./config"], function(dojo, lang, ArrayUtil, config){
- var Color = dojo.Color = function(/*Array|String|Object*/ color){
- // summary:
- // Takes a named string, hex string, array of rgb or rgba values,
- // an object with r, g, b, and a properties, or another `Color` object
- // and creates a new Color instance to work from.
- //
- // example:
- // Work with a Color instance:
- // | var c = new Color();
- // | c.setColor([0,0,0]); // black
- // | var hex = c.toHex(); // #000000
- //
- // example:
- // Work with a node's color:
- // | var color = dojo.style("someNode", "backgroundColor");
- // | var n = new Color(color);
- // | // adjust the color some
- // | n.r *= .5;
- // | console.log(n.toString()); // rgb(128, 255, 255);
- if(color){ this.setColor(color); }
- };
- // FIXME:
- // there's got to be a more space-efficient way to encode or discover
- // these!! Use hex?
- Color.named = {
- // summary:
- // Dictionary list of all CSS named colors, by name. Values are 3-item arrays with corresponding RG and B values.
- "black": [0,0,0],
- "silver": [192,192,192],
- "gray": [128,128,128],
- "white": [255,255,255],
- "maroon": [128,0,0],
- "red": [255,0,0],
- "purple": [128,0,128],
- "fuchsia":[255,0,255],
- "green": [0,128,0],
- "lime": [0,255,0],
- "olive": [128,128,0],
- "yellow": [255,255,0],
- "navy": [0,0,128],
- "blue": [0,0,255],
- "teal": [0,128,128],
- "aqua": [0,255,255],
- "transparent": config.transparentColor || [0,0,0,0]
- };
- lang.extend(Color, {
- r: 255, g: 255, b: 255, a: 1,
- _set: function(r, g, b, a){
- var t = this; t.r = r; t.g = g; t.b = b; t.a = a;
- },
- setColor: function(/*Array|String|Object*/ color){
- // summary:
- // Takes a named string, hex string, array of rgb or rgba values,
- // an object with r, g, b, and a properties, or another `Color` object
- // and sets this color instance to that value.
- //
- // example:
- // | var c = new Color(); // no color
- // | c.setColor("#ededed"); // greyish
- if(lang.isString(color)){
- Color.fromString(color, this);
- }else if(lang.isArray(color)){
- Color.fromArray(color, this);
- }else{
- this._set(color.r, color.g, color.b, color.a);
- if(!(color instanceof Color)){ this.sanitize(); }
- }
- return this; // Color
- },
- sanitize: function(){
- // summary:
- // Ensures the object has correct attributes
- // description:
- // the default implementation does nothing, include dojo.colors to
- // augment it with real checks
- return this; // Color
- },
- toRgb: function(){
- // summary:
- // Returns 3 component array of rgb values
- // example:
- // | var c = new Color("#000000");
- // | console.log(c.toRgb()); // [0,0,0]
- var t = this;
- return [t.r, t.g, t.b]; // Array
- },
- toRgba: function(){
- // summary:
- // Returns a 4 component array of rgba values from the color
- // represented by this object.
- var t = this;
- return [t.r, t.g, t.b, t.a]; // Array
- },
- toHex: function(){
- // summary:
- // Returns a CSS color string in hexadecimal representation
- // example:
- // | console.log(new Color([0,0,0]).toHex()); // #000000
- var arr = ArrayUtil.map(["r", "g", "b"], function(x){
- var s = this[x].toString(16);
- return s.length < 2 ? "0" + s : s;
- }, this);
- return "#" + arr.join(""); // String
- },
- toCss: function(/*Boolean?*/ includeAlpha){
- // summary:
- // Returns a css color string in rgb(a) representation
- // example:
- // | var c = new Color("#FFF").toCss();
- // | console.log(c); // rgb('255','255','255')
- var t = this, rgb = t.r + ", " + t.g + ", " + t.b;
- return (includeAlpha ? "rgba(" + rgb + ", " + t.a : "rgb(" + rgb) + ")"; // String
- },
- toString: function(){
- // summary:
- // Returns a visual representation of the color
- return this.toCss(true); // String
- }
- });
- Color.blendColors = dojo.blendColors = function(
- /*Color*/ start,
- /*Color*/ end,
- /*Number*/ weight,
- /*Color?*/ obj
- ){
- // summary:
- // Blend colors end and start with weight from 0 to 1, 0.5 being a 50/50 blend,
- // can reuse a previously allocated Color object for the result
- var t = obj || new Color();
- ArrayUtil.forEach(["r", "g", "b", "a"], function(x){
- t[x] = start[x] + (end[x] - start[x]) * weight;
- if(x != "a"){ t[x] = Math.round(t[x]); }
- });
- return t.sanitize(); // Color
- };
- Color.fromRgb = dojo.colorFromRgb = function(/*String*/ color, /*Color?*/ obj){
- // summary:
- // Returns a `Color` instance from a string of the form
- // "rgb(...)" or "rgba(...)". Optionally accepts a `Color`
- // object to update with the parsed value and return instead of
- // creating a new object.
- // returns:
- // A Color object. If obj is passed, it will be the return value.
- var m = color.toLowerCase().match(/^rgba?\(([\s\.,0-9]+)\)/);
- return m && Color.fromArray(m[1].split(/\s*,\s*/), obj); // Color
- };
- Color.fromHex = dojo.colorFromHex = function(/*String*/ color, /*Color?*/ obj){
- // summary:
- // Converts a hex string with a '#' prefix to a color object.
- // Supports 12-bit #rgb shorthand. Optionally accepts a
- // `Color` object to update with the parsed value.
- //
- // returns:
- // A Color object. If obj is passed, it will be the return value.
- //
- // example:
- // | var thing = dojo.colorFromHex("#ededed"); // grey, longhand
- //
- // example:
- // | var thing = dojo.colorFromHex("#000"); // black, shorthand
- var t = obj || new Color(),
- bits = (color.length == 4) ? 4 : 8,
- mask = (1 << bits) - 1;
- color = Number("0x" + color.substr(1));
- if(isNaN(color)){
- return null; // Color
- }
- ArrayUtil.forEach(["b", "g", "r"], function(x){
- var c = color & mask;
- color >>= bits;
- t[x] = bits == 4 ? 17 * c : c;
- });
- t.a = 1;
- return t; // Color
- };
- Color.fromArray = dojo.colorFromArray = function(/*Array*/ a, /*Color?*/ obj){
- // summary:
- // Builds a `Color` from a 3 or 4 element array, mapping each
- // element in sequence to the rgb(a) values of the color.
- // example:
- // | var myColor = dojo.colorFromArray([237,237,237,0.5]); // grey, 50% alpha
- // returns:
- // A Color object. If obj is passed, it will be the return value.
- var t = obj || new Color();
- t._set(Number(a[0]), Number(a[1]), Number(a[2]), Number(a[3]));
- if(isNaN(t.a)){ t.a = 1; }
- return t.sanitize(); // Color
- };
- Color.fromString = dojo.colorFromString = function(/*String*/ str, /*Color?*/ obj){
- // summary:
- // Parses `str` for a color value. Accepts hex, rgb, and rgba
- // style color values.
- // description:
- // Acceptable input values for str may include arrays of any form
- // accepted by dojo.colorFromArray, hex strings such as "#aaaaaa", or
- // rgb or rgba strings such as "rgb(133, 200, 16)" or "rgba(10, 10,
- // 10, 50)"
- // returns:
- // A Color object. If obj is passed, it will be the return value.
- var a = Color.named[str];
- return a && Color.fromArray(a, obj) || Color.fromRgb(str, obj) || Color.fromHex(str, obj); // Color
- };
- return Color;
- });
- },
- 'dojo/promise/instrumentation':function(){
- define([
- "./tracer",
- "../has",
- "../_base/lang",
- "../_base/array"
- ], function(tracer, has, lang, arrayUtil){
- function logError(error, rejection, deferred){
- var stack = "";
- if(error && error.stack){
- stack += error.stack;
- }
- if(rejection && rejection.stack){
- stack += "\n ----------------------------------------\n rejected" + rejection.stack.split("\n").slice(1).join("\n").replace(/^\s+/, " ");
- }
- if(deferred && deferred.stack){
- stack += "\n ----------------------------------------\n" + deferred.stack;
- }
- console.error(error, stack);
- }
- function reportRejections(error, handled, rejection, deferred){
- if(!handled){
- logError(error, rejection, deferred);
- }
- }
- var errors = [];
- var activeTimeout = false;
- var unhandledWait = 1000;
- function trackUnhandledRejections(error, handled, rejection, deferred){
- if(handled){
- arrayUtil.some(errors, function(obj, ix){
- if(obj.error === error){
- errors.splice(ix, 1);
- return true;
- }
- });
- }else if(!arrayUtil.some(errors, function(obj){ return obj.error === error; })){
- errors.push({
- error: error,
- rejection: rejection,
- deferred: deferred,
- timestamp: new Date().getTime()
- });
- }
- if(!activeTimeout){
- activeTimeout = setTimeout(logRejected, unhandledWait);
- }
- }
- function logRejected(){
- var now = new Date().getTime();
- var reportBefore = now - unhandledWait;
- errors = arrayUtil.filter(errors, function(obj){
- if(obj.timestamp < reportBefore){
- logError(obj.error, obj.rejection, obj.deferred);
- return false;
- }
- return true;
- });
- if(errors.length){
- activeTimeout = setTimeout(logRejected, errors[0].timestamp + unhandledWait - now);
- }
- }
- return function(Deferred){
- // summary:
- // Initialize instrumentation for the Deferred class.
- // description:
- // Initialize instrumentation for the Deferred class.
- // Done automatically by `dojo/Deferred` if the
- // `deferredInstrumentation` and `useDeferredInstrumentation`
- // config options are set.
- //
- // Sets up `dojo/promise/tracer` to log to the console.
- //
- // Sets up instrumentation of rejected deferreds so unhandled
- // errors are logged to the console.
- var usage = has("config-useDeferredInstrumentation");
- if(usage){
- tracer.on("resolved", lang.hitch(console, "log", "resolved"));
- tracer.on("rejected", lang.hitch(console, "log", "rejected"));
- tracer.on("progress", lang.hitch(console, "log", "progress"));
- var args = [];
- if(typeof usage === "string"){
- args = usage.split(",");
- usage = args.shift();
- }
- if(usage === "report-rejections"){
- Deferred.instrumentRejected = reportRejections;
- }else if(usage === "report-unhandled-rejections" || usage === true || usage === 1){
- Deferred.instrumentRejected = trackUnhandledRejections;
- unhandledWait = parseInt(args[0], 10) || unhandledWait;
- }else{
- throw new Error("Unsupported instrumentation usage <" + usage + ">");
- }
- }
- };
- });
- },
- 'dojo/selector/_loader':function(){
- define(["../has", "require"],
- function(has, require){
- "use strict";
- var testDiv = document.createElement("div");
- has.add("dom-qsa2.1", !!testDiv.querySelectorAll);
- has.add("dom-qsa3", function(){
- // test to see if we have a reasonable native selector engine available
- try{
- testDiv.innerHTML = "<p class='TEST'></p>"; // test kind of from sizzle
- // Safari can't handle uppercase or unicode characters when
- // in quirks mode, IE8 can't handle pseudos like :empty
- return testDiv.querySelectorAll(".TEST:empty").length == 1;
- }catch(e){}
- });
- var fullEngine;
- var acme = "./acme", lite = "./lite";
- return {
- // summary:
- // This module handles loading the appropriate selector engine for the given browser
- load: function(id, parentRequire, loaded, config){
- var req = require;
- // here we implement the default logic for choosing a selector engine
- id = id == "default" ? has("config-selectorEngine") || "css3" : id;
- id = id == "css2" || id == "lite" ? lite :
- id == "css2.1" ? has("dom-qsa2.1") ? lite : acme :
- id == "css3" ? has("dom-qsa3") ? lite : acme :
- id == "acme" ? acme : (req = parentRequire) && id;
- if(id.charAt(id.length-1) == '?'){
- id = id.substring(0,id.length - 1);
- var optionalLoad = true;
- }
- // the query engine is optional, only load it if a native one is not available or existing one has not been loaded
- if(optionalLoad && (has("dom-compliant-qsa") || fullEngine)){
- return loaded(fullEngine);
- }
- // load the referenced selector engine
- req([id], function(engine){
- if(id != "./lite"){
- fullEngine = engine;
- }
- loaded(engine);
- });
- }
- };
- });
- },
- 'dojo/promise/Promise':function(){
- define([
- "../_base/lang"
- ], function(lang){
- "use strict";
- // module:
- // dojo/promise/Promise
- function throwAbstract(){
- throw new TypeError("abstract");
- }
- return lang.extend(function Promise(){
- // summary:
- // The public interface to a deferred.
- // description:
- // The public interface to a deferred. All promises in Dojo are
- // instances of this class.
- }, {
- then: function(callback, errback, progback){
- // summary:
- // Add new callbacks to the promise.
- // description:
- // Add new callbacks to the deferred. Callbacks can be added
- // before or after the deferred is fulfilled.
- // callback: Function?
- // Callback to be invoked when the promise is resolved.
- // Receives the resolution value.
- // errback: Function?
- // Callback to be invoked when the promise is rejected.
- // Receives the rejection error.
- // progback: Function?
- // Callback to be invoked when the promise emits a progress
- // update. Receives the progress update.
- // returns: dojo/promise/Promise
- // Returns a new promise for the result of the callback(s).
- // This can be used for chaining many asynchronous operations.
- throwAbstract();
- },
- cancel: function(reason, strict){
- // summary:
- // Inform the deferred it may cancel its asynchronous operation.
- // description:
- // Inform the deferred it may cancel its asynchronous operation.
- // The deferred's (optional) canceler is invoked and the
- // deferred will be left in a rejected state. Can affect other
- // promises that originate with the same deferred.
- // reason: any
- // A message that may be sent to the deferred's canceler,
- // explaining why it's being canceled.
- // strict: Boolean?
- // If strict, will throw an error if the deferred has already
- // been fulfilled and consequently cannot be canceled.
- // returns: any
- // Returns the rejection reason if the deferred was canceled
- // normally.
- throwAbstract();
- },
- isResolved: function(){
- // summary:
- // Checks whether the promise has been resolved.
- // returns: Boolean
- throwAbstract();
- },
- isRejected: function(){
- // summary:
- // Checks whether the promise has been rejected.
- // returns: Boolean
- throwAbstract();
- },
- isFulfilled: function(){
- // summary:
- // Checks whether the promise has been resolved or rejected.
- // returns: Boolean
- throwAbstract();
- },
- isCanceled: function(){
- // summary:
- // Checks whether the promise has been canceled.
- // returns: Boolean
- throwAbstract();
- },
- always: function(callbackOrErrback){
- // summary:
- // Add a callback to be invoked when the promise is resolved
- // or rejected.
- // callbackOrErrback: Function?
- // A function that is used both as a callback and errback.
- // returns: dojo/promise/Promise
- // Returns a new promise for the result of the callback/errback.
- return this.then(callbackOrErrback, callbackOrErrback);
- },
- otherwise: function(errback){
- // summary:
- // Add new errbacks to the promise.
- // errback: Function?
- // Callback to be invoked when the promise is rejected.
- // returns: dojo/promise/Promise
- // Returns a new promise for the result of the errback.
- return this.then(null, errback);
- },
- trace: function(){
- return this;
- },
- traceRejected: function(){
- return this;
- },
- toString: function(){
- // returns: string
- // Returns `[object Promise]`.
- return "[object Promise]";
- }
- });
- });
- },
- 'dojo/request/watch':function(){
- define([
- './util',
- '../errors/RequestTimeoutError',
- '../errors/CancelError',
- '../_base/array',
- '../_base/window',
- '../has!host-browser?dom-addeventlistener?:../on:'
- ], function(util, RequestTimeoutError, CancelError, array, win, on){
- // avoid setting a timer per request. It degrades performance on IE
- // something fierece if we don't use unified loops.
- var _inFlightIntvl = null,
- _inFlight = [];
- function watchInFlight(){
- // summary:
- // internal method that checks each inflight XMLHttpRequest to see
- // if it has completed or if the timeout situation applies.
- var now = +(new Date);
- // we need manual loop because we often modify _inFlight (and therefore 'i') while iterating
- for(var i = 0, dfd; i < _inFlight.length && (dfd = _inFlight[i]); i++){
- var response = dfd.response,
- options = response.options;
- if((dfd.isCanceled && dfd.isCanceled()) || (dfd.isValid && !dfd.isValid(response))){
- _inFlight.splice(i--, 1);
- watch._onAction && watch._onAction();
- }else if(dfd.isReady && dfd.isReady(response)){
- _inFlight.splice(i--, 1);
- dfd.handleResponse(response);
- watch._onAction && watch._onAction();
- }else if(dfd.startTime){
- // did we timeout?
- if(dfd.startTime + (options.timeout || 0) < now){
- _inFlight.splice(i--, 1);
- // Cancel the request so the io module can do appropriate cleanup.
- dfd.cancel(new RequestTimeoutError('Timeout exceeded', response));
- watch._onAction && watch._onAction();
- }
- }
- }
- watch._onInFlight && watch._onInFlight(dfd);
- if(!_inFlight.length){
- clearInterval(_inFlightIntvl);
- _inFlightIntvl = null;
- }
- }
- function watch(dfd){
- // summary:
- // Watches the io request represented by dfd to see if it completes.
- // dfd: Deferred
- // The Deferred object to watch.
- // response: Object
- // The object used as the value of the request promise.
- // validCheck: Function
- // Function used to check if the IO request is still valid. Gets the dfd
- // object as its only argument.
- // ioCheck: Function
- // Function used to check if basic IO call worked. Gets the dfd
- // object as its only argument.
- // resHandle: Function
- // Function used to process response. Gets the dfd
- // object as its only argument.
- if(dfd.response.options.timeout){
- dfd.startTime = +(new Date);
- }
- if(dfd.isFulfilled()){
- // bail out if the deferred is already fulfilled
- return;
- }
- _inFlight.push(dfd);
- if(!_inFlightIntvl){
- _inFlightIntvl = setInterval(watchInFlight, 50);
- }
- // handle sync requests separately from async:
- // http://bugs.dojotoolkit.org/ticket/8467
- if(dfd.response.options.sync){
- watchInFlight();
- }
- }
- watch.cancelAll = function cancelAll(){
- // summary:
- // Cancels all pending IO requests, regardless of IO type
- try{
- array.forEach(_inFlight, function(dfd){
- try{
- dfd.cancel(new CancelError('All requests canceled.'));
- }catch(e){}
- });
- }catch(e){}
- };
- if(win && on && win.doc.attachEvent){
- // Automatically call cancel all io calls on unload in IE
- // http://bugs.dojotoolkit.org/ticket/2357
- on(win.global, 'unload', function(){
- watch.cancelAll();
- });
- }
- return watch;
- });
- },
- 'dojo/on':function(){
- define(["./has!dom-addeventlistener?:./aspect", "./_base/kernel", "./has"], function(aspect, dojo, has){
- "use strict";
- if( 1 ){ // check to make sure we are in a browser, this module should work anywhere
- var major = window.ScriptEngineMajorVersion;
- has.add("jscript", major && (major() + ScriptEngineMinorVersion() / 10));
- has.add("event-orientationchange", has("touch") && !has("android")); // TODO: how do we detect this?
- has.add("event-stopimmediatepropagation", window.Event && !!window.Event.prototype && !!window.Event.prototype.stopImmediatePropagation);
- }
- var on = function(target, type, listener, dontFix){
- // summary:
- // A function that provides core event listening functionality. With this function
- // you can provide a target, event type, and listener to be notified of
- // future matching events that are fired.
- // target: Element|Object
- // This is the target object or DOM element that to receive events from
- // type: String|Function
- // This is the name of the event to listen for or an extension event type.
- // listener: Function
- // This is the function that should be called when the event fires.
- // returns: Object
- // An object with a remove() method that can be used to stop listening for this
- // event.
- // description:
- // To listen for "click" events on a button node, we can do:
- // | define(["dojo/on"], function(listen){
- // | on(button, "click", clickHandler);
- // | ...
- // Evented JavaScript objects can also have their own events.
- // | var obj = new Evented;
- // | on(obj, "foo", fooHandler);
- // And then we could publish a "foo" event:
- // | on.emit(obj, "foo", {key: "value"});
- // We can use extension events as well. For example, you could listen for a tap gesture:
- // | define(["dojo/on", "dojo/gesture/tap", function(listen, tap){
- // | on(button, tap, tapHandler);
- // | ...
- // which would trigger fooHandler. Note that for a simple object this is equivalent to calling:
- // | obj.onfoo({key:"value"});
- // If you use on.emit on a DOM node, it will use native event dispatching when possible.
- if(typeof target.on == "function" && typeof type != "function"){
- // delegate to the target's on() method, so it can handle it's own listening if it wants
- return target.on(type, listener);
- }
- // delegate to main listener code
- return on.parse(target, type, listener, addListener, dontFix, this);
- };
- on.pausable = function(target, type, listener, dontFix){
- // summary:
- // This function acts the same as on(), but with pausable functionality. The
- // returned signal object has pause() and resume() functions. Calling the
- // pause() method will cause the listener to not be called for future events. Calling the
- // resume() method will cause the listener to again be called for future events.
- var paused;
- var signal = on(target, type, function(){
- if(!paused){
- return listener.apply(this, arguments);
- }
- }, dontFix);
- signal.pause = function(){
- paused = true;
- };
- signal.resume = function(){
- paused = false;
- };
- return signal;
- };
- on.once = function(target, type, listener, dontFix){
- // summary:
- // This function acts the same as on(), but will only call the listener once. The
- // listener will be called for the first
- // event that takes place and then listener will automatically be removed.
- var signal = on(target, type, function(){
- // remove this listener
- signal.remove();
- // proceed to call the listener
- return listener.apply(this, arguments);
- });
- return signal;
- };
- on.parse = function(target, type, listener, addListener, dontFix, matchesTarget){
- if(type.call){
- // event handler function
- // on(node, touch.press, touchListener);
- return type.call(matchesTarget, target, listener);
- }
- if(type.indexOf(",") > -1){
- // we allow comma delimited event names, so you can register for multiple events at once
- var events = type.split(/\s*,\s*/);
- var handles = [];
- var i = 0;
- var eventName;
- while(eventName = events[i++]){
- handles.push(addListener(target, eventName, listener, dontFix, matchesTarget));
- }
- handles.remove = function(){
- for(var i = 0; i < handles.length; i++){
- handles[i].remove();
- }
- };
- return handles;
- }
- return addListener(target, type, listener, dontFix, matchesTarget);
- };
- var touchEvents = /^touch/;
- function addListener(target, type, listener, dontFix, matchesTarget){
- // event delegation:
- var selector = type.match(/(.*):(.*)/);
- // if we have a selector:event, the last one is interpreted as an event, and we use event delegation
- if(selector){
- type = selector[2];
- selector = selector[1];
- // create the extension event for selectors and directly call it
- return on.selector(selector, type).call(matchesTarget, target, listener);
- }
- // test to see if it a touch event right now, so we don't have to do it every time it fires
- if(has("touch")){
- if(touchEvents.test(type)){
- // touch event, fix it
- listener = fixTouchListener(listener);
- }
- if(!has("event-orientationchange") && (type == "orientationchange")){
- //"orientationchange" not supported <= Android 2.1,
- //but works through "resize" on window
- type = "resize";
- target = window;
- listener = fixTouchListener(listener);
- }
- }
- if(addStopImmediate){
- // add stopImmediatePropagation if it doesn't exist
- listener = addStopImmediate(listener);
- }
- // normal path, the target is |this|
- if(target.addEventListener){
- // the target has addEventListener, which should be used if available (might or might not be a node, non-nodes can implement this method as well)
- // check for capture conversions
- var capture = type in captures,
- adjustedType = capture ? captures[type] : type;
- target.addEventListener(adjustedType, listener, capture);
- // create and return the signal
- return {
- remove: function(){
- target.removeEventListener(adjustedType, listener, capture);
- }
- };
- }
- type = "on" + type;
- if(fixAttach && target.attachEvent){
- return fixAttach(target, type, listener);
- }
- throw new Error("Target must be an event emitter");
- }
- on.selector = function(selector, eventType, children){
- // summary:
- // Creates a new extension event with event delegation. This is based on
- // the provided event type (can be extension event) that
- // only calls the listener when the CSS selector matches the target of the event.
- //
- // The application must require() an appropriate level of dojo/query to handle the selector.
- // selector:
- // The CSS selector to use for filter events and determine the |this| of the event listener.
- // eventType:
- // The event to listen for
- // children:
- // Indicates if children elements of the selector should be allowed. This defaults to
- // true
- // example:
- // | require(["dojo/on", "dojo/mouse", "dojo/query!css2"], function(listen, mouse){
- // | on(node, on.selector(".my-class", mouse.enter), handlerForMyHover);
- return function(target, listener){
- // if the selector is function, use it to select the node, otherwise use the matches method
- var matchesTarget = typeof selector == "function" ? {matches: selector} : this,
- bubble = eventType.bubble;
- function select(eventTarget){
- // see if we have a valid matchesTarget or default to dojo.query
- matchesTarget = matchesTarget && matchesTarget.matches ? matchesTarget : dojo.query;
- // there is a selector, so make sure it matches
- while(!matchesTarget.matches(eventTarget, selector, target)){
- if(eventTarget == target || children === false || !(eventTarget = eventTarget.parentNode) || eventTarget.nodeType != 1){ // intentional assignment
- return;
- }
- }
- return eventTarget;
- }
- if(bubble){
- // the event type doesn't naturally bubble, but has a bubbling form, use that, and give it the selector so it can perform the select itself
- return on(target, bubble(select), listener);
- }
- // standard event delegation
- return on(target, eventType, function(event){
- // call select to see if we match
- var eventTarget = select(event.target);
- // if it matches we call the listener
- return eventTarget && listener.call(eventTarget, event);
- });
- };
- };
- function syntheticPreventDefault(){
- this.cancelable = false;
- }
- function syntheticStopPropagation(){
- this.bubbles = false;
- }
- var slice = [].slice,
- syntheticDispatch = on.emit = function(target, type, event){
- // summary:
- // Fires an event on the target object.
- // target:
- // The target object to fire the event on. This can be a DOM element or a plain
- // JS object. If the target is a DOM element, native event emiting mechanisms
- // are used when possible.
- // type:
- // The event type name. You can emulate standard native events like "click" and
- // "mouseover" or create custom events like "open" or "finish".
- // event:
- // An object that provides the properties for the event. See https://developer.mozilla.org/en/DOM/event.initEvent
- // for some of the properties. These properties are copied to the event object.
- // Of particular importance are the cancelable and bubbles properties. The
- // cancelable property indicates whether or not the event has a default action
- // that can be cancelled. The event is cancelled by calling preventDefault() on
- // the event object. The bubbles property indicates whether or not the
- // event will bubble up the DOM tree. If bubbles is true, the event will be called
- // on the target and then each parent successively until the top of the tree
- // is reached or stopPropagation() is called. Both bubbles and cancelable
- // default to false.
- // returns:
- // If the event is cancelable and the event is not cancelled,
- // emit will return true. If the event is cancelable and the event is cancelled,
- // emit will return false.
- // details:
- // Note that this is designed to emit events for listeners registered through
- // dojo/on. It should actually work with any event listener except those
- // added through IE's attachEvent (IE8 and below's non-W3C event emiting
- // doesn't support custom event types). It should work with all events registered
- // through dojo/on. Also note that the emit method does do any default
- // action, it only returns a value to indicate if the default action should take
- // place. For example, emiting a keypress event would not cause a character
- // to appear in a textbox.
- // example:
- // To fire our own click event
- // | on.emit(dojo.byId("button"), "click", {
- // | cancelable: true,
- // | bubbles: true,
- // | screenX: 33,
- // | screenY: 44
- // | });
- // We can also fire our own custom events:
- // | on.emit(dojo.byId("slider"), "slide", {
- // | cancelable: true,
- // | bubbles: true,
- // | direction: "left-to-right"
- // | });
- var args = slice.call(arguments, 2);
- var method = "on" + type;
- if("parentNode" in target){
- // node (or node-like), create event controller methods
- var newEvent = args[0] = {};
- for(var i in event){
- newEvent[i] = event[i];
- }
- newEvent.preventDefault = syntheticPreventDefault;
- newEvent.stopPropagation = syntheticStopPropagation;
- newEvent.target = target;
- newEvent.type = type;
- event = newEvent;
- }
- do{
- // call any node which has a handler (note that ideally we would try/catch to simulate normal event propagation but that causes too much pain for debugging)
- target[method] && target[method].apply(target, args);
- // and then continue up the parent node chain if it is still bubbling (if started as bubbles and stopPropagation hasn't been called)
- }while(event && event.bubbles && (target = target.parentNode));
- return event && event.cancelable && event; // if it is still true (was cancelable and was cancelled), return the event to indicate default action should happen
- };
- var captures = {};
- if(!has("event-stopimmediatepropagation")){
- var stopImmediatePropagation =function(){
- this.immediatelyStopped = true;
- this.modified = true; // mark it as modified so the event will be cached in IE
- };
- var addStopImmediate = function(listener){
- return function(event){
- if(!event.immediatelyStopped){// check to make sure it hasn't been stopped immediately
- event.stopImmediatePropagation = stopImmediatePropagation;
- return listener.apply(this, arguments);
- }
- };
- }
- }
- if(has("dom-addeventlistener")){
- // normalize focusin and focusout
- captures = {
- focusin: "focus",
- focusout: "blur"
- };
- if(has("opera")){
- captures.keydown = "keypress"; // this one needs to be transformed because Opera doesn't support repeating keys on keydown (and keypress works because it incorrectly fires on all keydown events)
- }
- // emiter that works with native event handling
- on.emit = function(target, type, event){
- if(target.dispatchEvent && document.createEvent){
- // use the native event emiting mechanism if it is available on the target object
- // create a generic event
- // we could create branch into the different types of event constructors, but
- // that would be a lot of extra code, with little benefit that I can see, seems
- // best to use the generic constructor and copy properties over, making it
- // easy to have events look like the ones created with specific initializers
- var nativeEvent = target.ownerDocument.createEvent("HTMLEvents");
- nativeEvent.initEvent(type, !!event.bubbles, !!event.cancelable);
- // and copy all our properties over
- for(var i in event){
- var value = event[i];
- if(!(i in nativeEvent)){
- nativeEvent[i] = event[i];
- }
- }
- return target.dispatchEvent(nativeEvent) && nativeEvent;
- }
- return syntheticDispatch.apply(on, arguments); // emit for a non-node
- };
- }else{
- // no addEventListener, basically old IE event normalization
- on._fixEvent = function(evt, sender){
- // summary:
- // normalizes properties on the event object including event
- // bubbling methods, keystroke normalization, and x/y positions
- // evt:
- // native event object
- // sender:
- // node to treat as "currentTarget"
- if(!evt){
- var w = sender && (sender.ownerDocument || sender.document || sender).parentWindow || window;
- evt = w.event;
- }
- if(!evt){return evt;}
- if(lastEvent && evt.type == lastEvent.type){
- // should be same event, reuse event object (so it can be augmented)
- evt = lastEvent;
- }
- if(!evt.target){ // check to see if it has been fixed yet
- evt.target = evt.srcElement;
- evt.currentTarget = (sender || evt.srcElement);
- if(evt.type == "mouseover"){
- evt.relatedTarget = evt.fromElement;
- }
- if(evt.type == "mouseout"){
- evt.relatedTarget = evt.toElement;
- }
- if(!evt.stopPropagation){
- evt.stopPropagation = stopPropagation;
- evt.preventDefault = preventDefault;
- }
- switch(evt.type){
- case "keypress":
- var c = ("charCode" in evt ? evt.charCode : evt.keyCode);
- if (c==10){
- // CTRL-ENTER is CTRL-ASCII(10) on IE, but CTRL-ENTER on Mozilla
- c=0;
- evt.keyCode = 13;
- }else if(c==13||c==27){
- c=0; // Mozilla considers ENTER and ESC non-printable
- }else if(c==3){
- c=99; // Mozilla maps CTRL-BREAK to CTRL-c
- }
- // Mozilla sets keyCode to 0 when there is a charCode
- // but that stops the event on IE.
- evt.charCode = c;
- _setKeyChar(evt);
- break;
- }
- }
- return evt;
- };
- var lastEvent, IESignal = function(handle){
- this.handle = handle;
- };
- IESignal.prototype.remove = function(){
- delete _dojoIEListeners_[this.handle];
- };
- var fixListener = function(listener){
- // this is a minimal function for closing on the previous listener with as few as variables as possible
- return function(evt){
- evt = on._fixEvent(evt, this);
- var result = listener.call(this, evt);
- if(evt.modified){
- // cache the last event and reuse it if we can
- if(!lastEvent){
- setTimeout(function(){
- lastEvent = null;
- });
- }
- lastEvent = evt;
- }
- return result;
- };
- };
- var fixAttach = function(target, type, listener){
- listener = fixListener(listener);
- if(((target.ownerDocument ? target.ownerDocument.parentWindow : target.parentWindow || target.window || window) != top ||
- has("jscript") < 5.8) &&
- !has("config-_allow_leaks")){
- // IE will leak memory on certain handlers in frames (IE8 and earlier) and in unattached DOM nodes for JScript 5.7 and below.
- // Here we use global redirection to solve the memory leaks
- if(typeof _dojoIEListeners_ == "undefined"){
- _dojoIEListeners_ = [];
- }
- var emiter = target[type];
- if(!emiter || !emiter.listeners){
- var oldListener = emiter;
- emiter = Function('event', 'var callee = arguments.callee; for(var i = 0; i<callee.listeners.length; i++){var listener = _dojoIEListeners_[callee.listeners[i]]; if(listener){listener.call(this,event);}}');
- emiter.listeners = [];
- target[type] = emiter;
- emiter.global = this;
- if(oldListener){
- emiter.listeners.push(_dojoIEListeners_.push(oldListener) - 1);
- }
- }
- var handle;
- emiter.listeners.push(handle = (emiter.global._dojoIEListeners_.push(listener) - 1));
- return new IESignal(handle);
- }
- return aspect.after(target, type, listener, true);
- };
- var _setKeyChar = function(evt){
- evt.keyChar = evt.charCode ? String.fromCharCode(evt.charCode) : '';
- evt.charOrCode = evt.keyChar || evt.keyCode;
- };
- // Called in Event scope
- var stopPropagation = function(){
- this.cancelBubble = true;
- };
- var preventDefault = on._preventDefault = function(){
- // Setting keyCode to 0 is the only way to prevent certain keypresses (namely
- // ctrl-combinations that correspond to menu accelerator keys).
- // Otoh, it prevents upstream listeners from getting this information
- // Try to split the difference here by clobbering keyCode only for ctrl
- // combinations. If you still need to access the key upstream, bubbledKeyCode is
- // provided as a workaround.
- this.bubbledKeyCode = this.keyCode;
- if(this.ctrlKey){
- try{
- // squelch errors when keyCode is read-only
- // (e.g. if keyCode is ctrl or shift)
- this.keyCode = 0;
- }catch(e){
- }
- }
- this.defaultPrevented = true;
- this.returnValue = false;
- };
- }
- if(has("touch")){
- var Event = function(){};
- var windowOrientation = window.orientation;
- var fixTouchListener = function(listener){
- return function(originalEvent){
- //Event normalization(for ontouchxxx and resize):
- //1.incorrect e.pageX|pageY in iOS
- //2.there are no "e.rotation", "e.scale" and "onorientationchange" in Andriod
- //3.More TBD e.g. force | screenX | screenX | clientX | clientY | radiusX | radiusY
- // see if it has already been corrected
- var event = originalEvent.corrected;
- if(!event){
- var type = originalEvent.type;
- try{
- delete originalEvent.type; // on some JS engines (android), deleting properties make them mutable
- }catch(e){}
- if(originalEvent.type){
- // deleting properties doesn't work (older iOS), have to use delegation
- Event.prototype = originalEvent;
- var event = new Event;
- // have to delegate methods to make them work
- event.preventDefault = function(){
- originalEvent.preventDefault();
- };
- event.stopPropagation = function(){
- originalEvent.stopPropagation();
- };
- }else{
- // deletion worked, use property as is
- event = originalEvent;
- event.type = type;
- }
- originalEvent.corrected = event;
- if(type == 'resize'){
- if(windowOrientation == window.orientation){
- return null;//double tap causes an unexpected 'resize' in Andriod
- }
- windowOrientation = window.orientation;
- event.type = "orientationchange";
- return listener.call(this, event);
- }
- // We use the original event and augment, rather than doing an expensive mixin operation
- if(!("rotation" in event)){ // test to see if it has rotation
- event.rotation = 0;
- event.scale = 1;
- }
- //use event.changedTouches[0].pageX|pageY|screenX|screenY|clientX|clientY|target
- var firstChangeTouch = event.changedTouches[0];
- for(var i in firstChangeTouch){ // use for-in, we don't need to have dependency on dojo/_base/lang here
- delete event[i]; // delete it first to make it mutable
- event[i] = firstChangeTouch[i];
- }
- }
- return listener.call(this, event);
- };
- };
- }
- return on;
- });
- },
- 'dojo/_base/sniff':function(){
- define(["./kernel", "./lang", "../sniff"], function(dojo, lang, has){
- // module:
- // dojo/_base/sniff
- /*=====
- return {
- // summary:
- // Deprecated. New code should use dojo/sniff.
- // This module populates the dojo browser version sniffing properties like dojo.isIE.
- };
- =====*/
- if(! 1 ){
- return has;
- }
- // no idea what this is for, or if it's used
- dojo._name = "browser";
- lang.mixin(dojo, {
- // isBrowser: Boolean
- // True if the client is a web-browser
- isBrowser: true,
- // isFF: Number|undefined
- // Version as a Number if client is FireFox. undefined otherwise. Corresponds to
- // major detected FireFox version (1.5, 2, 3, etc.)
- isFF: has("ff"),
- // isIE: Number|undefined
- // Version as a Number if client is MSIE(PC). undefined otherwise. Corresponds to
- // major detected IE version (6, 7, 8, etc.)
- isIE: has("ie"),
- // isKhtml: Number|undefined
- // Version as a Number if client is a KHTML browser. undefined otherwise. Corresponds to major
- // detected version.
- isKhtml: has("khtml"),
- // isWebKit: Number|undefined
- // Version as a Number if client is a WebKit-derived browser (Konqueror,
- // Safari, Chrome, etc.). undefined otherwise.
- isWebKit: has("webkit"),
- // isMozilla: Number|undefined
- // Version as a Number if client is a Mozilla-based browser (Firefox,
- // SeaMonkey). undefined otherwise. Corresponds to major detected version.
- isMozilla: has("mozilla"),
- // isMoz: Number|undefined
- // Version as a Number if client is a Mozilla-based browser (Firefox,
- // SeaMonkey). undefined otherwise. Corresponds to major detected version.
- isMoz: has("mozilla"),
- // isOpera: Number|undefined
- // Version as a Number if client is Opera. undefined otherwise. Corresponds to
- // major detected version.
- isOpera: has("opera"),
- // isSafari: Number|undefined
- // Version as a Number if client is Safari or iPhone. undefined otherwise.
- isSafari: has("safari"),
- // isChrome: Number|undefined
- // Version as a Number if client is Chrome browser. undefined otherwise.
- isChrome: has("chrome"),
- // isMac: Boolean
- // True if the client runs on Mac
- isMac: has("mac"),
- // isIos: Boolean
- // True if client is iPhone, iPod, or iPad
- isIos: has("ios"),
- // isAndroid: Number|undefined
- // Version as a Number if client is android browser. undefined otherwise.
- isAndroid: has("android"),
- // isWii: Boolean
- // True if client is Wii
- isWii: has("wii"),
- // isQuirks: Boolean
- // Page is in quirks mode.
- isQuirks: has("quirks"),
- // isAir: Boolean
- // True if client is Adobe Air
- isAir: has("air")
- });
- dojo.locale = dojo.locale || (has("ie") ? navigator.userLanguage : navigator.language).toLowerCase();
- return has;
- });
- },
- 'dojo/errors/create':function(){
- define(["../_base/lang"], function(lang){
- return function(name, ctor, base, props){
- base = base || Error;
- var ErrorCtor = function(message){
- if(base === Error){
- if(Error.captureStackTrace){
- Error.captureStackTrace(this, ErrorCtor);
- }
- // Error.call() operates on the returned error
- // object rather than operating on |this|
- var err = Error.call(this, message),
- prop;
- // Copy own properties from err to |this|
- for(prop in err){
- if(err.hasOwnProperty(prop)){
- this[prop] = err[prop];
- }
- }
- // messsage is non-enumerable in ES5
- this.message = message;
- // stack is non-enumerable in at least Firefox
- this.stack = err.stack;
- }else{
- base.apply(this, arguments);
- }
- if(ctor){
- ctor.apply(this, arguments);
- }
- };
- ErrorCtor.prototype = lang.delegate(base.prototype, props);
- ErrorCtor.prototype.name = name;
- ErrorCtor.prototype.constructor = ErrorCtor;
- return ErrorCtor;
- };
- });
- },
- 'dojo/_base/array':function(){
- define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
- // module:
- // dojo/_base/array
- // our old simple function builder stuff
- var cache = {}, u;
- function buildFn(fn){
- return cache[fn] = new Function("item", "index", "array", fn); // Function
- }
- // magic snippet: if(typeof fn == "string") fn = cache[fn] || buildFn(fn);
- // every & some
- function everyOrSome(some){
- var every = !some;
- return function(a, fn, o){
- var i = 0, l = a && a.length || 0, result;
- if(l && typeof a == "string") a = a.split("");
- if(typeof fn == "string") fn = cache[fn] || buildFn(fn);
- if(o){
- for(; i < l; ++i){
- result = !fn.call(o, a[i], i, a);
- if(some ^ result){
- return !result;
- }
- }
- }else{
- for(; i < l; ++i){
- result = !fn(a[i], i, a);
- if(some ^ result){
- return !result;
- }
- }
- }
- return every; // Boolean
- };
- }
- // indexOf, lastIndexOf
- function index(up){
- var delta = 1, lOver = 0, uOver = 0;
- if(!up){
- delta = lOver = uOver = -1;
- }
- return function(a, x, from, last){
- if(last && delta > 0){
- // TODO: why do we use a non-standard signature? why do we need "last"?
- return array.lastIndexOf(a, x, from);
- }
- var l = a && a.length || 0, end = up ? l + uOver : lOver, i;
- if(from === u){
- i = up ? lOver : l + uOver;
- }else{
- if(from < 0){
- i = l + from;
- if(i < 0){
- i = lOver;
- }
- }else{
- i = from >= l ? l + uOver : from;
- }
- }
- if(l && typeof a == "string") a = a.split("");
- for(; i != end; i += delta){
- if(a[i] == x){
- return i; // Number
- }
- }
- return -1; // Number
- };
- }
- var array = {
- // summary:
- // The Javascript v1.6 array extensions.
- every: everyOrSome(false),
- /*=====
- every: function(arr, callback, thisObject){
- // summary:
- // Determines whether or not every item in arr satisfies the
- // condition implemented by callback.
- // arr: Array|String
- // the array to iterate on. If a string, operates on individual characters.
- // callback: Function|String
- // a function is invoked with three arguments: item, index,
- // and array and returns true if the condition is met.
- // thisObject: Object?
- // may be used to scope the call to callback
- // returns: Boolean
- // description:
- // This function corresponds to the JavaScript 1.6 Array.every() method, with one difference: when
- // run over sparse arrays, this implementation passes the "holes" in the sparse array to
- // the callback function with a value of undefined. JavaScript 1.6's every skips the holes in the sparse array.
- // For more details, see:
- // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/every
- // example:
- // | // returns false
- // | array.every([1, 2, 3, 4], function(item){ return item>1; });
- // example:
- // | // returns true
- // | array.every([1, 2, 3, 4], function(item){ return item>0; });
- },
- =====*/
- some: everyOrSome(true),
- /*=====
- some: function(arr, callback, thisObject){
- // summary:
- // Determines whether or not any item in arr satisfies the
- // condition implemented by callback.
- // arr: Array|String
- // the array to iterate over. If a string, operates on individual characters.
- // callback: Function|String
- // a function is invoked with three arguments: item, index,
- // and array and returns true if the condition is met.
- // thisObject: Object?
- // may be used to scope the call to callback
- // returns: Boolean
- // description:
- // This function corresponds to the JavaScript 1.6 Array.some() method, with one difference: when
- // run over sparse arrays, this implementation passes the "holes" in the sparse array to
- // the callback function with a value of undefined. JavaScript 1.6's some skips the holes in the sparse array.
- // For more details, see:
- // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/some
- // example:
- // | // is true
- // | array.some([1, 2, 3, 4], function(item){ return item>1; });
- // example:
- // | // is false
- // | array.some([1, 2, 3, 4], function(item){ return item<1; });
- },
- =====*/
- indexOf: index(true),
- /*=====
- indexOf: function(arr, value, fromIndex, findLast){
- // summary:
- // locates the first index of the provided value in the
- // passed array. If the value is not found, -1 is returned.
- // description:
- // This method corresponds to the JavaScript 1.6 Array.indexOf method, with one difference: when
- // run over sparse arrays, the Dojo function invokes the callback for every index whereas JavaScript
- // 1.6's indexOf skips the holes in the sparse array.
- // For details on this method, see:
- // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/indexOf
- // arr: Array
- // value: Object
- // fromIndex: Integer?
- // findLast: Boolean?
- // returns: Number
- },
- =====*/
- lastIndexOf: index(false),
- /*=====
- lastIndexOf: function(arr, value, fromIndex){
- // summary:
- // locates the last index of the provided value in the passed
- // array. If the value is not found, -1 is returned.
- // description:
- // This method corresponds to the JavaScript 1.6 Array.lastIndexOf method, with one difference: when
- // run over sparse arrays, the Dojo function invokes the callback for every index whereas JavaScript
- // 1.6's lastIndexOf skips the holes in the sparse array.
- // For details on this method, see:
- // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/lastIndexOf
- // arr: Array,
- // value: Object,
- // fromIndex: Integer?
- // returns: Number
- },
- =====*/
- forEach: function(arr, callback, thisObject){
- // summary:
- // for every item in arr, callback is invoked. Return values are ignored.
- // If you want to break out of the loop, consider using array.every() or array.some().
- // forEach does not allow breaking out of the loop over the items in arr.
- // arr:
- // the array to iterate over. If a string, operates on individual characters.
- // callback:
- // a function is invoked with three arguments: item, index, and array
- // thisObject:
- // may be used to scope the call to callback
- // description:
- // This function corresponds to the JavaScript 1.6 Array.forEach() method, with one difference: when
- // run over sparse arrays, this implementation passes the "holes" in the sparse array to
- // the callback function with a value of undefined. JavaScript 1.6's forEach skips the holes in the sparse array.
- // For more details, see:
- // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/forEach
- // example:
- // | // log out all members of the array:
- // | array.forEach(
- // | [ "thinger", "blah", "howdy", 10 ],
- // | function(item){
- // | console.log(item);
- // | }
- // | );
- // example:
- // | // log out the members and their indexes
- // | array.forEach(
- // | [ "thinger", "blah", "howdy", 10 ],
- // | function(item, idx, arr){
- // | console.log(item, "at index:", idx);
- // | }
- // | );
- // example:
- // | // use a scoped object member as the callback
- // |
- // | var obj = {
- // | prefix: "logged via obj.callback:",
- // | callback: function(item){
- // | console.log(this.prefix, item);
- // | }
- // | };
- // |
- // | // specifying the scope function executes the callback in that scope
- // | array.forEach(
- // | [ "thinger", "blah", "howdy", 10 ],
- // | obj.callback,
- // | obj
- // | );
- // |
- // | // alternately, we can accomplish the same thing with lang.hitch()
- // | array.forEach(
- // | [ "thinger", "blah", "howdy", 10 ],
- // | lang.hitch(obj, "callback")
- // | );
- // arr: Array|String
- // callback: Function|String
- // thisObject: Object?
- var i = 0, l = arr && arr.length || 0;
- if(l && typeof arr == "string") arr = arr.split("");
- if(typeof callback == "string") callback = cache[callback] || buildFn(callback);
- if(thisObject){
- for(; i < l; ++i){
- callback.call(thisObject, arr[i], i, arr);
- }
- }else{
- for(; i < l; ++i){
- callback(arr[i], i, arr);
- }
- }
- },
- map: function(arr, callback, thisObject, Ctr){
- // summary:
- // applies callback to each element of arr and returns
- // an Array with the results
- // arr: Array|String
- // the array to iterate on. If a string, operates on
- // individual characters.
- // callback: Function|String
- // a function is invoked with three arguments, (item, index,
- // array), and returns a value
- // thisObject: Object?
- // may be used to scope the call to callback
- // returns: Array
- // description:
- // This function corresponds to the JavaScript 1.6 Array.map() method, with one difference: when
- // run over sparse arrays, this implementation passes the "holes" in the sparse array to
- // the callback function with a value of undefined. JavaScript 1.6's map skips the holes in the sparse array.
- // For more details, see:
- // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
- // example:
- // | // returns [2, 3, 4, 5]
- // | array.map([1, 2, 3, 4], function(item){ return item+1 });
- // TODO: why do we have a non-standard signature here? do we need "Ctr"?
- var i = 0, l = arr && arr.length || 0, out = new (Ctr || Array)(l);
- if(l && typeof arr == "string") arr = arr.split("");
- if(typeof callback == "string") callback = cache[callback] || buildFn(callback);
- if(thisObject){
- for(; i < l; ++i){
- out[i] = callback.call(thisObject, arr[i], i, arr);
- }
- }else{
- for(; i < l; ++i){
- out[i] = callback(arr[i], i, arr);
- }
- }
- return out; // Array
- },
- filter: function(arr, callback, thisObject){
- // summary:
- // Returns a new Array with those items from arr that match the
- // condition implemented by callback.
- // arr: Array
- // the array to iterate over.
- // callback: Function|String
- // a function that is invoked with three arguments (item,
- // index, array). The return of this function is expected to
- // be a boolean which determines whether the passed-in item
- // will be included in the returned array.
- // thisObject: Object?
- // may be used to scope the call to callback
- // returns: Array
- // description:
- // This function corresponds to the JavaScript 1.6 Array.filter() method, with one difference: when
- // run over sparse arrays, this implementation passes the "holes" in the sparse array to
- // the callback function with a value of undefined. JavaScript 1.6's filter skips the holes in the sparse array.
- // For more details, see:
- // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
- // example:
- // | // returns [2, 3, 4]
- // | array.filter([1, 2, 3, 4], function(item){ return item>1; });
- // TODO: do we need "Ctr" here like in map()?
- var i = 0, l = arr && arr.length || 0, out = [], value;
- if(l && typeof arr == "string") arr = arr.split("");
- if(typeof callback == "string") callback = cache[callback] || buildFn(callback);
- if(thisObject){
- for(; i < l; ++i){
- value = arr[i];
- if(callback.call(thisObject, value, i, arr)){
- out.push(value);
- }
- }
- }else{
- for(; i < l; ++i){
- value = arr[i];
- if(callback(value, i, arr)){
- out.push(value);
- }
- }
- }
- return out; // Array
- },
- clearCache: function(){
- cache = {};
- }
- };
- 1 && lang.mixin(dojo, array);
- return array;
- });
- },
- 'dojo/_base/json':function(){
- define(["./kernel", "../json"], function(dojo, json){
- // module:
- // dojo/_base/json
- /*=====
- return {
- // summary:
- // This module defines the dojo JSON API.
- };
- =====*/
- dojo.fromJson = function(/*String*/ js){
- // summary:
- // Parses a JavaScript expression and returns a JavaScript value.
- // description:
- // Throws for invalid JavaScript expressions. It does not use a strict JSON parser. It
- // always delegates to eval(). The content passed to this method must therefore come
- // from a trusted source.
- // It is recommend that you use dojo/json's parse function for an
- // implementation uses the (faster) native JSON parse when available.
- // js:
- // a string literal of a JavaScript expression, for instance:
- // `'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'`
- return eval("(" + js + ")"); // Object
- };
- /*=====
- dojo._escapeString = function(){
- // summary:
- // Adds escape sequences for non-visual characters, double quote and
- // backslash and surrounds with double quotes to form a valid string
- // literal.
- };
- =====*/
- dojo._escapeString = json.stringify; // just delegate to json.stringify
- dojo.toJsonIndentStr = "\t";
- dojo.toJson = function(/*Object*/ it, /*Boolean?*/ prettyPrint){
- // summary:
- // Returns a [JSON](http://json.org) serialization of an object.
- // description:
- // Returns a [JSON](http://json.org) serialization of an object.
- // Note that this doesn't check for infinite recursion, so don't do that!
- // It is recommend that you use dojo/json's stringify function for an lighter
- // and faster implementation that matches the native JSON API and uses the
- // native JSON serializer when available.
- // it:
- // an object to be serialized. Objects may define their own
- // serialization via a special "__json__" or "json" function
- // property. If a specialized serializer has been defined, it will
- // be used as a fallback.
- // Note that in 1.6, toJson would serialize undefined, but this no longer supported
- // since it is not supported by native JSON serializer.
- // prettyPrint:
- // if true, we indent objects and arrays to make the output prettier.
- // The variable `dojo.toJsonIndentStr` is used as the indent string --
- // to use something other than the default (tab), change that variable
- // before calling dojo.toJson().
- // Note that if native JSON support is available, it will be used for serialization,
- // and native implementations vary on the exact spacing used in pretty printing.
- // returns:
- // A JSON string serialization of the passed-in object.
- // example:
- // simple serialization of a trivial object
- // | var jsonStr = dojo.toJson({ howdy: "stranger!", isStrange: true });
- // | doh.is('{"howdy":"stranger!","isStrange":true}', jsonStr);
- // example:
- // a custom serializer for an objects of a particular class:
- // | dojo.declare("Furby", null, {
- // | furbies: "are strange",
- // | furbyCount: 10,
- // | __json__: function(){
- // | },
- // | });
- // use dojo/json
- return json.stringify(it, function(key, value){
- if(value){
- var tf = value.__json__||value.json;
- if(typeof tf == "function"){
- return tf.call(value);
- }
- }
- return value;
- }, prettyPrint && dojo.toJsonIndentStr); // String
- };
- return dojo;
- });
- },
- 'dojo/_base/window':function(){
- define("dojo/_base/window", ["./kernel", "./lang", "../sniff"], function(dojo, lang, has){
- // module:
- // dojo/_base/window
- var ret = {
- // summary:
- // API to save/set/restore the global/document scope.
- global: dojo.global,
- /*=====
- global: {
- // summary:
- // Alias for the current window. 'global' can be modified
- // for temporary context shifting. See also withGlobal().
- // description:
- // Use this rather than referring to 'window' to ensure your code runs
- // correctly in managed contexts.
- },
- =====*/
- doc: this["document"] || null,
- /*=====
- doc: {
- // summary:
- // Alias for the current document. 'doc' can be modified
- // for temporary context shifting. See also withDoc().
- // description:
- // Use this rather than referring to 'window.document' to ensure your code runs
- // correctly in managed contexts.
- // example:
- // | n.appendChild(dojo.doc.createElement('div'));
- },
- =====*/
- body: function(/*Document?*/ doc){
- // summary:
- // Return the body element of the specified document or of dojo/_base/window::doc.
- // example:
- // | win.body().appendChild(dojo.doc.createElement('div'));
- // Note: document.body is not defined for a strict xhtml document
- // Would like to memoize this, but dojo.doc can change vi dojo.withDoc().
- doc = doc || dojo.doc;
- return doc.body || doc.getElementsByTagName("body")[0]; // Node
- },
- setContext: function(/*Object*/ globalObject, /*DocumentElement*/ globalDocument){
- // summary:
- // changes the behavior of many core Dojo functions that deal with
- // namespace and DOM lookup, changing them to work in a new global
- // context (e.g., an iframe). The varibles dojo.global and dojo.doc
- // are modified as a result of calling this function and the result of
- // `dojo.body()` likewise differs.
- dojo.global = ret.global = globalObject;
- dojo.doc = ret.doc = globalDocument;
- },
- withGlobal: function( /*Object*/ globalObject,
- /*Function*/ callback,
- /*Object?*/ thisObject,
- /*Array?*/ cbArguments){
- // summary:
- // Invoke callback with globalObject as dojo.global and
- // globalObject.document as dojo.doc.
- // description:
- // Invoke callback with globalObject as dojo.global and
- // globalObject.document as dojo.doc. If provided, globalObject
- // will be executed in the context of object thisObject
- // When callback() returns or throws an error, the dojo.global
- // and dojo.doc will be restored to its previous state.
- var oldGlob = dojo.global;
- try{
- dojo.global = ret.global = globalObject;
- return ret.withDoc.call(null, globalObject.document, callback, thisObject, cbArguments);
- }finally{
- dojo.global = ret.global = oldGlob;
- }
- },
- withDoc: function( /*DocumentElement*/ documentObject,
- /*Function*/ callback,
- /*Object?*/ thisObject,
- /*Array?*/ cbArguments){
- // summary:
- // Invoke callback with documentObject as dojo/_base/window::doc.
- // description:
- // Invoke callback with documentObject as dojo/_base/window::doc. If provided,
- // callback will be executed in the context of object thisObject
- // When callback() returns or throws an error, the dojo/_base/window::doc will
- // be restored to its previous state.
- var oldDoc = ret.doc,
- oldQ = has("quirks"),
- oldIE = has("ie"), isIE, mode, pwin;
- try{
- dojo.doc = ret.doc = documentObject;
- // update dojo.isQuirks and the value of the has feature "quirks".
- // remove setting dojo.isQuirks and dojo.isIE for 2.0
- dojo.isQuirks = has.add("quirks", dojo.doc.compatMode == "BackCompat", true, true); // no need to check for QuirksMode which was Opera 7 only
- if(has("ie")){
- if((pwin = documentObject.parentWindow) && pwin.navigator){
- // re-run IE detection logic and update dojo.isIE / has("ie")
- // (the only time parentWindow/navigator wouldn't exist is if we were not
- // passed an actual legitimate document object)
- isIE = parseFloat(pwin.navigator.appVersion.split("MSIE ")[1]) || undefined;
- mode = documentObject.documentMode;
- if(mode && mode != 5 && Math.floor(isIE) != mode){
- isIE = mode;
- }
- dojo.isIE = has.add("ie", isIE, true, true);
- }
- }
- if(thisObject && typeof callback == "string"){
- callback = thisObject[callback];
- }
- return callback.apply(thisObject, cbArguments || []);
- }finally{
- dojo.doc = ret.doc = oldDoc;
- dojo.isQuirks = has.add("quirks", oldQ, true, true);
- dojo.isIE = has.add("ie", oldIE, true, true);
- }
- }
- };
- 1 && lang.mixin(dojo, ret);
- return ret;
- });
- },
- 'dojo/dom-class':function(){
- define(["./_base/lang", "./_base/array", "./dom"], function(lang, array, dom){
- // module:
- // dojo/dom-class
- var className = "className";
- /* Part I of classList-based implementation is preserved here for posterity
- var classList = "classList";
- has.add("dom-classList", function(){
- return classList in document.createElement("p");
- });
- */
- // =============================
- // (CSS) Class Functions
- // =============================
- var cls, // exports object
- spaces = /\s+/, a1 = [""];
- function str2array(s){
- if(typeof s == "string" || s instanceof String){
- if(s && !spaces.test(s)){
- a1[0] = s;
- return a1;
- }
- var a = s.split(spaces);
- if(a.length && !a[0]){
- a.shift();
- }
- if(a.length && !a[a.length - 1]){
- a.pop();
- }
- return a;
- }
- // assumed to be an array
- if(!s){
- return [];
- }
- return array.filter(s, function(x){ return x; });
- }
- /* Part II of classList-based implementation is preserved here for posterity
- if(has("dom-classList")){
- // new classList version
- cls = {
- contains: function containsClass(node, classStr){
- var clslst = classStr && dom.byId(node)[classList];
- return clslst && clslst.contains(classStr); // Boolean
- },
- add: function addClass(node, classStr){
- node = dom.byId(node);
- classStr = str2array(classStr);
- for(var i = 0, len = classStr.length; i < len; ++i){
- node[classList].add(classStr[i]);
- }
- },
- remove: function removeClass(node, classStr){
- node = dom.byId(node);
- if(classStr === undefined){
- node[className] = "";
- }else{
- classStr = str2array(classStr);
- for(var i = 0, len = classStr.length; i < len; ++i){
- node[classList].remove(classStr[i]);
- }
- }
- },
- replace: function replaceClass(node, addClassStr, removeClassStr){
- node = dom.byId(node);
- if(removeClassStr === undefined){
- node[className] = "";
- }else{
- removeClassStr = str2array(removeClassStr);
- for(var i = 0, len = removeClassStr.length; i < len; ++i){
- node[classList].remove(removeClassStr[i]);
- }
- }
- addClassStr = str2array(addClassStr);
- for(i = 0, len = addClassStr.length; i < len; ++i){
- node[classList].add(addClassStr[i]);
- }
- },
- toggle: function toggleClass(node, classStr, condition){
- node = dom.byId(node);
- if(condition === undefined){
- classStr = str2array(classStr);
- for(var i = 0, len = classStr.length; i < len; ++i){
- node[classList].toggle(classStr[i]);
- }
- }else{
- cls[condition ? "add" : "remove"](node, classStr);
- }
- return condition; // Boolean
- }
- }
- }
- */
- // regular DOM version
- var fakeNode = {}; // for effective replacement
- cls = {
- // summary:
- // This module defines the core dojo DOM class API.
- contains: function containsClass(/*DomNode|String*/ node, /*String*/ classStr){
- // summary:
- // Returns whether or not the specified classes are a portion of the
- // class list currently applied to the node.
- // node: String|DOMNode
- // String ID or DomNode reference to check the class for.
- // classStr: String
- // A string class name to look for.
- // example:
- // Do something if a node with id="someNode" has class="aSillyClassName" present
- // | if(dojo.hasClass("someNode","aSillyClassName")){ ... }
- return ((" " + dom.byId(node)[className] + " ").indexOf(" " + classStr + " ") >= 0); // Boolean
- },
- add: function addClass(/*DomNode|String*/ node, /*String|Array*/ classStr){
- // summary:
- // Adds the specified classes to the end of the class list on the
- // passed node. Will not re-apply duplicate classes.
- //
- // node: String|DOMNode
- // String ID or DomNode reference to add a class string too
- //
- // classStr: String|Array
- // A String class name to add, or several space-separated class names,
- // or an array of class names.
- //
- // example:
- // Add a class to some node:
- // | require(["dojo/dom-class"], function(domClass){
- // | domClass.add("someNode", "anewClass");
- // | });
- //
- // example:
- // Add two classes at once:
- // | require(["dojo/dom-class"], function(domClass){
- // | domClass.add("someNode", "firstClass secondClass");
- // | });
- //
- // example:
- // Add two classes at once (using array):
- // | require(["dojo/dom-class"], function(domClass){
- // | domClass.add("someNode", ["firstClass", "secondClass"]);
- // | });
- //
- // example:
- // Available in `dojo/NodeList` for multiple additions
- // | require(["dojo/query"], function(query){
- // | query("ul > li").addClass("firstLevel");
- // | });
- node = dom.byId(node);
- classStr = str2array(classStr);
- var cls = node[className], oldLen;
- cls = cls ? " " + cls + " " : " ";
- oldLen = cls.length;
- for(var i = 0, len = classStr.length, c; i < len; ++i){
- c = classStr[i];
- if(c && cls.indexOf(" " + c + " ") < 0){
- cls += c + " ";
- }
- }
- if(oldLen < cls.length){
- node[className] = cls.substr(1, cls.length - 2);
- }
- },
- remove: function removeClass(/*DomNode|String*/ node, /*String|Array?*/ classStr){
- // summary:
- // Removes the specified classes from node. No `contains()`
- // check is required.
- //
- // node: String|DOMNode
- // String ID or DomNode reference to remove the class from.
- //
- // classStr: String|Array
- // An optional String class name to remove, or several space-separated
- // class names, or an array of class names. If omitted, all class names
- // will be deleted.
- //
- // example:
- // Remove a class from some node:
- // | require(["dojo/dom-class"], function(domClass){
- // | domClass.remove("someNode", "firstClass");
- // | });
- //
- // example:
- // Remove two classes from some node:
- // | require(["dojo/dom-class"], function(domClass){
- // | domClass.remove("someNode", "firstClass secondClass");
- // | });
- //
- // example:
- // Remove two classes from some node (using array):
- // | require(["dojo/dom-class"], function(domClass){
- // | domClass.remove("someNode", ["firstClass", "secondClass"]);
- // | });
- //
- // example:
- // Remove all classes from some node:
- // | require(["dojo/dom-class"], function(domClass){
- // | domClass.remove("someNode");
- // | });
- //
- // example:
- // Available in `dojo/NodeList` for multiple removal
- // | require(["dojo/query"], function(query){
- // | query("ul > li").removeClass("foo");
- // | });
- node = dom.byId(node);
- var cls;
- if(classStr !== undefined){
- classStr = str2array(classStr);
- cls = " " + node[className] + " ";
- for(var i = 0, len = classStr.length; i < len; ++i){
- cls = cls.replace(" " + classStr[i] + " ", " ");
- }
- cls = lang.trim(cls);
- }else{
- cls = "";
- }
- if(node[className] != cls){ node[className] = cls; }
- },
- replace: function replaceClass(/*DomNode|String*/ node, /*String|Array*/ addClassStr, /*String|Array?*/ removeClassStr){
- // summary:
- // Replaces one or more classes on a node if not present.
- // Operates more quickly than calling dojo.removeClass and dojo.addClass
- //
- // node: String|DOMNode
- // String ID or DomNode reference to remove the class from.
- //
- // addClassStr: String|Array
- // A String class name to add, or several space-separated class names,
- // or an array of class names.
- //
- // removeClassStr: String|Array?
- // A String class name to remove, or several space-separated class names,
- // or an array of class names.
- //
- // example:
- // | require(["dojo/dom-class"], function(domClass){
- // | domClass.replace("someNode", "add1 add2", "remove1 remove2");
- // | });
- //
- // example:
- // Replace all classes with addMe
- // | require(["dojo/dom-class"], function(domClass){
- // | domClass.replace("someNode", "addMe");
- // | });
- //
- // example:
- // Available in `dojo/NodeList` for multiple toggles
- // | require(["dojo/query"], function(query){
- // | query(".findMe").replaceClass("addMe", "removeMe");
- // | });
- node = dom.byId(node);
- fakeNode[className] = node[className];
- cls.remove(fakeNode, removeClassStr);
- cls.add(fakeNode, addClassStr);
- if(node[className] !== fakeNode[className]){
- node[className] = fakeNode[className];
- }
- },
- toggle: function toggleClass(/*DomNode|String*/ node, /*String|Array*/ classStr, /*Boolean?*/ condition){
- // summary:
- // Adds a class to node if not present, or removes if present.
- // Pass a boolean condition if you want to explicitly add or remove.
- // Returns the condition that was specified directly or indirectly.
- //
- // node: String|DOMNode
- // String ID or DomNode reference to toggle a class string
- //
- // classStr: String|Array
- // A String class name to toggle, or several space-separated class names,
- // or an array of class names.
- //
- // condition:
- // If passed, true means to add the class, false means to remove.
- // Otherwise dojo.hasClass(node, classStr) is used to detect the class presence.
- //
- // example:
- // | require(["dojo/dom-class"], function(domClass){
- // | domClass.toggle("someNode", "hovered");
- // | });
- //
- // example:
- // Forcefully add a class
- // | require(["dojo/dom-class"], function(domClass){
- // | domClass.toggle("someNode", "hovered", true);
- // | });
- //
- // example:
- // Available in `dojo/NodeList` for multiple toggles
- // | require(["dojo/query"], function(query){
- // | query(".toggleMe").toggleClass("toggleMe");
- // | });
- node = dom.byId(node);
- if(condition === undefined){
- classStr = str2array(classStr);
- for(var i = 0, len = classStr.length, c; i < len; ++i){
- c = classStr[i];
- cls[cls.contains(node, c) ? "remove" : "add"](node, c);
- }
- }else{
- cls[condition ? "add" : "remove"](node, classStr);
- }
- return condition; // Boolean
- }
- };
- return cls;
- });
- },
- 'dojo/_base/config':function(){
- define(["../has", "require"], function(has, require){
- // module:
- // dojo/_base/config
- /*=====
- return {
- // summary:
- // This module defines the user configuration during bootstrap.
- // description:
- // By defining user configuration as a module value, an entire configuration can be specified in a build,
- // thereby eliminating the need for sniffing and or explicitly setting in the global variable dojoConfig.
- // Also, when multiple instances of dojo exist in a single application, each will necessarily be located
- // at an unique absolute module identifier as given by the package configuration. Implementing configuration
- // as a module allows for specifying unique, per-instance configurations.
- // example:
- // Create a second instance of dojo with a different, instance-unique configuration (assume the loader and
- // dojo.js are already loaded).
- // | // specify a configuration that creates a new instance of dojo at the absolute module identifier "myDojo"
- // | require({
- // | packages:[{
- // | name:"myDojo",
- // | location:".", //assume baseUrl points to dojo.js
- // | }]
- // | });
- // |
- // | // specify a configuration for the myDojo instance
- // | define("myDojo/config", {
- // | // normal configuration variables go here, e.g.,
- // | locale:"fr-ca"
- // | });
- // |
- // | // load and use the new instance of dojo
- // | require(["myDojo"], function(dojo){
- // | // dojo is the new instance of dojo
- // | // use as required
- // | });
- // isDebug: Boolean
- // Defaults to `false`. If set to `true`, ensures that Dojo provides
- // extended debugging feedback via Firebug. If Firebug is not available
- // on your platform, setting `isDebug` to `true` will force Dojo to
- // pull in (and display) the version of Firebug Lite which is
- // integrated into the Dojo distribution, thereby always providing a
- // debugging/logging console when `isDebug` is enabled. Note that
- // Firebug's `console.*` methods are ALWAYS defined by Dojo. If
- // `isDebug` is false and you are on a platform without Firebug, these
- // methods will be defined as no-ops.
- isDebug: false,
- // locale: String
- // The locale to assume for loading localized resources in this page,
- // specified according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt).
- // Must be specified entirely in lowercase, e.g. `en-us` and `zh-cn`.
- // See the documentation for `dojo.i18n` and `dojo.requireLocalization`
- // for details on loading localized resources. If no locale is specified,
- // Dojo assumes the locale of the user agent, according to `navigator.userLanguage`
- // or `navigator.language` properties.
- locale: undefined,
- // extraLocale: Array
- // No default value. Specifies additional locales whose
- // resources should also be loaded alongside the default locale when
- // calls to `dojo.requireLocalization()` are processed.
- extraLocale: undefined,
- // baseUrl: String
- // The directory in which `dojo.js` is located. Under normal
- // conditions, Dojo auto-detects the correct location from which it
- // was loaded. You may need to manually configure `baseUrl` in cases
- // where you have renamed `dojo.js` or in which `<base>` tags confuse
- // some browsers (e.g. IE 6). The variable `dojo.baseUrl` is assigned
- // either the value of `djConfig.baseUrl` if one is provided or the
- // auto-detected root if not. Other modules are located relative to
- // this path. The path should end in a slash.
- baseUrl: undefined,
- // modulePaths: [deprecated] Object
- // A map of module names to paths relative to `dojo.baseUrl`. The
- // key/value pairs correspond directly to the arguments which
- // `dojo.registerModulePath` accepts. Specifying
- // `djConfig.modulePaths = { "foo": "../../bar" }` is the equivalent
- // of calling `dojo.registerModulePath("foo", "../../bar");`. Multiple
- // modules may be configured via `djConfig.modulePaths`.
- modulePaths: {},
- // addOnLoad: Function|Array
- // Adds a callback via dojo/ready. Useful when Dojo is added after
- // the page loads and djConfig.afterOnLoad is true. Supports the same
- // arguments as dojo/ready. When using a function reference, use
- // `djConfig.addOnLoad = function(){};`. For object with function name use
- // `djConfig.addOnLoad = [myObject, "functionName"];` and for object with
- // function reference use
- // `djConfig.addOnLoad = [myObject, function(){}];`
- addOnLoad: null,
- // parseOnLoad: Boolean
- // Run the parser after the page is loaded
- parseOnLoad: false,
- // require: String[]
- // An array of module names to be loaded immediately after dojo.js has been included
- // in a page.
- require: [],
- // defaultDuration: Number
- // Default duration, in milliseconds, for wipe and fade animations within dijits.
- // Assigned to dijit.defaultDuration.
- defaultDuration: 200,
- // dojoBlankHtmlUrl: String
- // Used by some modules to configure an empty iframe. Used by dojo/io/iframe and
- // dojo/back, and dijit/popup support in IE where an iframe is needed to make sure native
- // controls do not bleed through the popups. Normally this configuration variable
- // does not need to be set, except when using cross-domain/CDN Dojo builds.
- // Save dojo/resources/blank.html to your domain and set `djConfig.dojoBlankHtmlUrl`
- // to the path on your domain your copy of blank.html.
- dojoBlankHtmlUrl: undefined,
- // ioPublish: Boolean?
- // Set this to true to enable publishing of topics for the different phases of
- // IO operations. Publishing is done via dojo/topic.publish(). See dojo/main.__IoPublish for a list
- // of topics that are published.
- ioPublish: false,
- // useCustomLogger: Anything?
- // If set to a value that evaluates to true such as a string or array and
- // isDebug is true and Firebug is not available or running, then it bypasses
- // the creation of Firebug Lite allowing you to define your own console object.
- useCustomLogger: undefined,
- // transparentColor: Array
- // Array containing the r, g, b components used as transparent color in dojo.Color;
- // if undefined, [255,255,255] (white) will be used.
- transparentColor: undefined,
-
- // deps: Function|Array
- // Defines dependencies to be used before the loader has been loaded.
- // When provided, they cause the loader to execute require(deps, callback)
- // once it has finished loading. Should be used with callback.
- deps: undefined,
-
- // callback: Function|Array
- // Defines a callback to be used when dependencies are defined before
- // the loader has been loaded. When provided, they cause the loader to
- // execute require(deps, callback) once it has finished loading.
- // Should be used with deps.
- callback: undefined,
-
- // deferredInstrumentation: Boolean
- // Whether deferred instrumentation should be loaded or included
- // in builds.
- deferredInstrumentation: true,
- // useDeferredInstrumentation: Boolean|String
- // Whether the deferred instrumentation should be used.
- //
- // * `"report-rejections"`: report each rejection as it occurs.
- // * `true` or `1` or `"report-unhandled-rejections"`: wait 1 second
- // in an attempt to detect unhandled rejections.
- useDeferredInstrumentation: "report-unhandled-rejections"
- };
- =====*/
- var result = {};
- if( 1 ){
- // must be the dojo loader; take a shallow copy of require.rawConfig
- var src = require.rawConfig, p;
- for(p in src){
- result[p] = src[p];
- }
- }else{
- var adviseHas = function(featureSet, prefix, booting){
- for(p in featureSet){
- p!="has" && has.add(prefix + p, featureSet[p], 0, booting);
- }
- };
- result = 1 ?
- // must be a built version of the dojo loader; all config stuffed in require.rawConfig
- require.rawConfig :
- // a foreign loader
- this.dojoConfig || this.djConfig || {};
- adviseHas(result, "config", 1);
- adviseHas(result.has, "", 1);
- }
- return result;
- });
- },
- 'dojo/main':function(){
- define([
- "./_base/kernel", // kernel.isAsync
- "./has",
- "require",
- "./sniff",
- "./_base/lang",
- "./_base/array",
- "./_base/config",
- "./ready",
- "./_base/declare",
- "./_base/connect",
- "./_base/Deferred",
- "./_base/json",
- "./_base/Color",
- "./has!dojo-firebug?./_firebug/firebug",
- "./_base/browser",
- "./_base/loader"
- ], function(kernel, has, require, sniff, lang, array, config, ready){
- // module:
- // dojo/main
- // summary:
- // This is the package main module for the dojo package; it loads dojo base appropriate for the execution environment.
- // the preferred way to load the dojo firebug console is by setting has("dojo-firebug") true in dojoConfig
- // the isDebug config switch is for backcompat and will work fine in sync loading mode; it works in
- // async mode too, but there's no guarantee when the module is loaded; therefore, if you need a firebug
- // console guaranteed at a particular spot in an app, either set config.has["dojo-firebug"] true before
- // loading dojo.js or explicitly include dojo/_firebug/firebug in a dependency list.
- if(config.isDebug){
- require(["./_firebug/firebug"]);
- }
- // dojoConfig.require is deprecated; use the loader configuration property deps
- 1 || has.add("dojo-config-require", 1);
- if( 1 ){
- var deps= config.require;
- if(deps){
- // config.require may be dot notation
- deps= array.map(lang.isArray(deps) ? deps : [deps], function(item){ return item.replace(/\./g, "/"); });
- if(kernel.isAsync){
- require(deps);
- }else{
- // this is a bit janky; in 1.6- dojo is defined before these requires are applied; but in 1.7+
- // dojo isn't defined until returning from this module; this is only a problem in sync mode
- // since we're in sync mode, we know we've got our loader with its priority ready queue
- ready(1, function(){require(deps);});
- }
- }
- }
- return kernel;
- });
- },
- 'dojo/_base/event':function(){
- define("dojo/_base/event", ["./kernel", "../on", "../has", "../dom-geometry"], function(dojo, on, has, dom){
- // module:
- // dojo/_base/event
- if(on._fixEvent){
- var fixEvent = on._fixEvent;
- on._fixEvent = function(evt, se){
- // add some additional normalization for back-compat, this isn't in on.js because it is somewhat more expensive
- evt = fixEvent(evt, se);
- if(evt){
- dom.normalizeEvent(evt);
- }
- return evt;
- };
- }
-
- var ret = {
- // summary:
- // This module defines dojo DOM event API. Usually you should use dojo/on, and evt.stopPropagation() +
- // evt.preventDefault(), rather than this module.
- fix: function(/*Event*/ evt, /*DOMNode*/ sender){
- // summary:
- // normalizes properties on the event object including event
- // bubbling methods, keystroke normalization, and x/y positions
- // evt: Event
- // native event object
- // sender: DOMNode
- // node to treat as "currentTarget"
- if(on._fixEvent){
- return on._fixEvent(evt, sender);
- }
- return evt; // Event
- },
-
- stop: function(/*Event*/ evt){
- // summary:
- // prevents propagation and clobbers the default action of the
- // passed event
- // evt: Event
- // The event object. If omitted, window.event is used on IE.
- if(has("dom-addeventlistener") || (evt && evt.preventDefault)){
- evt.preventDefault();
- evt.stopPropagation();
- }else{
- evt = evt || window.event;
- evt.cancelBubble = true;
- on._preventDefault.call(evt);
- }
- }
- };
- if( 1 ){
- dojo.fixEvent = ret.fix;
- dojo.stopEvent = ret.stop;
- }
- return ret;
- });
- },
- 'dojo/sniff':function(){
- define(["./has"], function(has){
- // module:
- // dojo/sniff
- /*=====
- return function(){
- // summary:
- // This module sets has() flags based on the current browser.
- // It returns the has() function.
- };
- =====*/
- if( 1 ){
- var n = navigator,
- dua = n.userAgent,
- dav = n.appVersion,
- tv = parseFloat(dav);
- has.add("air", dua.indexOf("AdobeAIR") >= 0),
- has.add("khtml", dav.indexOf("Konqueror") >= 0 ? tv : undefined);
- has.add("webkit", parseFloat(dua.split("WebKit/")[1]) || undefined);
- has.add("chrome", parseFloat(dua.split("Chrome/")[1]) || undefined);
- has.add("safari", dav.indexOf("Safari")>=0 && !has("chrome") ? parseFloat(dav.split("Version/")[1]) : undefined);
- has.add("mac", dav.indexOf("Macintosh") >= 0);
- has.add("quirks", document.compatMode == "BackCompat");
- has.add("ios", /iPhone|iPod|iPad/.test(dua));
- has.add("android", parseFloat(dua.split("Android ")[1]) || undefined);
- if(!has("webkit")){
- // Opera
- if(dua.indexOf("Opera") >= 0){
- // see http://dev.opera.com/articles/view/opera-ua-string-changes and http://www.useragentstring.com/pages/Opera/
- // 9.8 has both styles; <9.8, 9.9 only old style
- has.add("opera", tv >= 9.8 ? parseFloat(dua.split("Version/")[1]) || tv : tv);
- }
- // Mozilla and firefox
- if(dua.indexOf("Gecko") >= 0 && !has("khtml") && !has("webkit")){
- has.add("mozilla", tv);
- }
- if(has("mozilla")){
- //We really need to get away from this. Consider a sane isGecko approach for the future.
- has.add("ff", parseFloat(dua.split("Firefox/")[1] || dua.split("Minefield/")[1]) || undefined);
- }
- // IE
- if(document.all && !has("opera")){
- var isIE = parseFloat(dav.split("MSIE ")[1]) || undefined;
- //In cases where the page has an HTTP header or META tag with
- //X-UA-Compatible, then it is in emulation mode.
- //Make sure isIE reflects the desired version.
- //document.documentMode of 5 means quirks mode.
- //Only switch the value if documentMode's major version
- //is different from isIE's major version.
- var mode = document.documentMode;
- if(mode && mode != 5 && Math.floor(isIE) != mode){
- isIE = mode;
- }
- has.add("ie", isIE);
- }
- // Wii
- has.add("wii", typeof opera != "undefined" && opera.wiiremote);
- }
- }
- return has;
- });
- },
- 'dojo/request/handlers':function(){
- define([
- '../json',
- '../_base/kernel',
- '../_base/array',
- '../has'
- ], function(JSON, kernel, array, has){
- has.add('activex', typeof ActiveXObject !== 'undefined');
- var handleXML;
- if(has('activex')){
- // GUIDs obtained from http://msdn.microsoft.com/en-us/library/ms757837(VS.85).aspx
- var dp = [
- 'Msxml2.DOMDocument.6.0',
- 'Msxml2.DOMDocument.4.0',
- 'MSXML2.DOMDocument.3.0',
- 'MSXML.DOMDocument' // 2.0
- ];
- handleXML = function(response){
- var result = response.data;
- if(!result || !result.documentElement){
- var text = response.text;
- array.some(dp, function(p){
- try{
- var dom = new ActiveXObject(p);
- dom.async = false;
- dom.loadXML(text);
- result = dom;
- }catch(e){ return false; }
- return true;
- });
- }
- return result;
- };
- }
- var handlers = {
- 'javascript': function(response){
- return kernel.eval(response.text || '');
- },
- 'json': function(response){
- return JSON.parse(response.text || null);
- },
- 'xml': handleXML
- };
- function handle(response){
- var handler = handlers[response.options.handleAs];
- response.data = handler ? handler(response) : (response.data || response.text);
- return response;
- }
- handle.register = function(name, handler){
- handlers[name] = handler;
- };
- return handle;
- });
- },
- 'dojo/aspect':function(){
- define("dojo/aspect", [], function(){
- // module:
- // dojo/aspect
- "use strict";
- var undefined, nextId = 0;
- function advise(dispatcher, type, advice, receiveArguments){
- var previous = dispatcher[type];
- var around = type == "around";
- var signal;
- if(around){
- var advised = advice(function(){
- return previous.advice(this, arguments);
- });
- signal = {
- remove: function(){
- signal.cancelled = true;
- },
- advice: function(target, args){
- return signal.cancelled ?
- previous.advice(target, args) : // cancelled, skip to next one
- advised.apply(target, args); // called the advised function
- }
- };
- }else{
- // create the remove handler
- signal = {
- remove: function(){
- var previous = signal.previous;
- var next = signal.next;
- if(!next && !previous){
- delete dispatcher[type];
- }else{
- if(previous){
- previous.next = next;
- }else{
- dispatcher[type] = next;
- }
- if(next){
- next.previous = previous;
- }
- }
- },
- id: nextId++,
- advice: advice,
- receiveArguments: receiveArguments
- };
- }
- if(previous && !around){
- if(type == "after"){
- // add the listener to the end of the list
- var next = previous;
- while(next){
- previous = next;
- next = next.next;
- }
- previous.next = signal;
- signal.previous = previous;
- }else if(type == "before"){
- // add to beginning
- dispatcher[type] = signal;
- signal.next = previous;
- previous.previous = signal;
- }
- }else{
- // around or first one just replaces
- dispatcher[type] = signal;
- }
- return signal;
- }
- function aspect(type){
- return function(target, methodName, advice, receiveArguments){
- var existing = target[methodName], dispatcher;
- if(!existing || existing.target != target){
- // no dispatcher in place
- target[methodName] = dispatcher = function(){
- var executionId = nextId;
- // before advice
- var args = arguments;
- var before = dispatcher.before;
- while(before){
- args = before.advice.apply(this, args) || args;
- before = before.next;
- }
- // around advice
- if(dispatcher.around){
- var results = dispatcher.around.advice(this, args);
- }
- // after advice
- var after = dispatcher.after;
- while(after && after.id < executionId){
- if(after.receiveArguments){
- var newResults = after.advice.apply(this, args);
- // change the return value only if a new value was returned
- results = newResults === undefined ? results : newResults;
- }else{
- results = after.advice.call(this, results, args);
- }
- after = after.next;
- }
- return results;
- };
- if(existing){
- dispatcher.around = {advice: function(target, args){
- return existing.apply(target, args);
- }};
- }
- dispatcher.target = target;
- }
- var results = advise((dispatcher || existing), type, advice, receiveArguments);
- advice = null;
- return results;
- };
- }
- // TODOC: after/before/around return object
- var after = aspect("after");
- /*=====
- after = function(target, methodName, advice, receiveArguments){
- // summary:
- // The "after" export of the aspect module is a function that can be used to attach
- // "after" advice to a method. This function will be executed after the original method
- // is executed. By default the function will be called with a single argument, the return
- // value of the original method, or the the return value of the last executed advice (if a previous one exists).
- // The fourth (optional) argument can be set to true to so the function receives the original
- // arguments (from when the original method was called) rather than the return value.
- // If there are multiple "after" advisors, they are executed in the order they were registered.
- // target: Object
- // This is the target object
- // methodName: String
- // This is the name of the method to attach to.
- // advice: Function
- // This is function to be called after the original method
- // receiveArguments: Boolean?
- // If this is set to true, the advice function receives the original arguments (from when the original mehtod
- // was called) rather than the return value of the original/previous method.
- // returns:
- // A signal object that can be used to cancel the advice. If remove() is called on this signal object, it will
- // stop the advice function from being executed.
- };
- =====*/
- var before = aspect("before");
- /*=====
- before = function(target, methodName, advice){
- // summary:
- // The "before" export of the aspect module is a function that can be used to attach
- // "before" advice to a method. This function will be executed before the original method
- // is executed. This function will be called with the arguments used to call the method.
- // This function may optionally return an array as the new arguments to use to call
- // the original method (or the previous, next-to-execute before advice, if one exists).
- // If the before method doesn't return anything (returns undefined) the original arguments
- // will be preserved.
- // If there are multiple "before" advisors, they are executed in the reverse order they were registered.
- // target: Object
- // This is the target object
- // methodName: String
- // This is the name of the method to attach to.
- // advice: Function
- // This is function to be called before the original method
- };
- =====*/
- var around = aspect("around");
- /*=====
- around = function(target, methodName, advice){
- // summary:
- // The "around" export of the aspect module is a function that can be used to attach
- // "around" advice to a method. The advisor function is immediately executed when
- // the around() is called, is passed a single argument that is a function that can be
- // called to continue execution of the original method (or the next around advisor).
- // The advisor function should return a function, and this function will be called whenever
- // the method is called. It will be called with the arguments used to call the method.
- // Whatever this function returns will be returned as the result of the method call (unless after advise changes it).
- // example:
- // If there are multiple "around" advisors, the most recent one is executed first,
- // which can then delegate to the next one and so on. For example:
- // | around(obj, "foo", function(originalFoo){
- // | return function(){
- // | var start = new Date().getTime();
- // | var results = originalFoo.apply(this, arguments); // call the original
- // | var end = new Date().getTime();
- // | console.log("foo execution took " + (end - start) + " ms");
- // | return results;
- // | };
- // | });
- // target: Object
- // This is the target object
- // methodName: String
- // This is the name of the method to attach to.
- // advice: Function
- // This is function to be called around the original method
- };
- =====*/
- return {
- // summary:
- // provides aspect oriented programming functionality, allowing for
- // one to add before, around, or after advice on existing methods.
- // example:
- // | define(["dojo/aspect"], function(aspect){
- // | var signal = aspect.after(targetObject, "methodName", function(someArgument){
- // | this will be called when targetObject.methodName() is called, after the original function is called
- // | });
- //
- // example:
- // The returned signal object can be used to cancel the advice.
- // | signal.remove(); // this will stop the advice from being executed anymore
- // | aspect.before(targetObject, "methodName", function(someArgument){
- // | // this will be called when targetObject.methodName() is called, before the original function is called
- // | });
- before: before,
- around: around,
- after: after
- };
- });
- },
- 'dojo/ready':function(){
- define("dojo/ready", ["./_base/kernel", "./has", "require", "./domReady", "./_base/lang"], function(dojo, has, require, domReady, lang){
- // module:
- // dojo/ready
- // note:
- // This module should be unnecessary in dojo 2.0
- var
- // truthy if DOMContentLoaded or better (e.g., window.onload fired) has been achieved
- isDomReady = 0,
- // a function to call to cause onLoad to be called when all requested modules have been loaded
- requestCompleteSignal,
- // The queue of functions waiting to execute as soon as dojo.ready conditions satisfied
- loadQ = [],
- // prevent recursion in onLoad
- onLoadRecursiveGuard = 0,
- handleDomReady = function(){
- isDomReady = 1;
- dojo._postLoad = dojo.config.afterOnLoad = true;
- if(loadQ.length){
- requestCompleteSignal(onLoad);
- }
- },
- // run the next function queued with dojo.ready
- onLoad = function(){
- if(isDomReady && !onLoadRecursiveGuard && loadQ.length){
- //guard against recursions into this function
- onLoadRecursiveGuard = 1;
- var f = loadQ.shift();
- try{
- f();
- }
- // FIXME: signal the error via require.on
- finally{
- onLoadRecursiveGuard = 0;
- }
- onLoadRecursiveGuard = 0;
- if(loadQ.length){
- requestCompleteSignal(onLoad);
- }
- }
- };
- require.on("idle", onLoad);
- requestCompleteSignal = function(){
- if(require.idle()){
- onLoad();
- } // else do nothing, onLoad will be called with the next idle signal
- };
- var ready = dojo.ready = dojo.addOnLoad = function(priority, context, callback){
- // summary:
- // Add a function to execute on DOM content loaded and all requested modules have arrived and been evaluated.
- // In most cases, the `domReady` plug-in should suffice and this method should not be needed.
- // priority: Integer?
- // The order in which to exec this callback relative to other callbacks, defaults to 1000
- // context: Object?|Function
- // The context in which to run execute callback, or a callback if not using context
- // callback: Function?
- // The function to execute.
- //
- // example:
- // Simple DOM and Modules ready syntax
- // | require(["dojo/ready"], function(ready){
- // | ready(function(){ alert("Dom ready!"); });
- // | });
- //
- // example:
- // Using a priority
- // | require(["dojo/ready"], function(ready){
- // | ready(2, function(){ alert("low priority ready!"); })
- // | });
- //
- // example:
- // Using context
- // | require(["dojo/ready"], function(ready){
- // | ready(foo, function(){
- // | // in here, this == foo
- // | });
- // | });
- //
- // example:
- // Using dojo/hitch style args:
- // | require(["dojo/ready"], function(ready){
- // | var foo = { dojoReady: function(){ console.warn(this, "dojo dom and modules ready."); } };
- // | ready(foo, "dojoReady");
- // | });
- var hitchArgs = lang._toArray(arguments);
- if(typeof priority != "number"){
- callback = context;
- context = priority;
- priority = 1000;
- }else{
- hitchArgs.shift();
- }
- callback = callback ?
- lang.hitch.apply(dojo, hitchArgs) :
- function(){
- context();
- };
- callback.priority = priority;
- for(var i = 0; i < loadQ.length && priority >= loadQ[i].priority; i++){}
- loadQ.splice(i, 0, callback);
- requestCompleteSignal();
- };
- 1 || has.add("dojo-config-addOnLoad", 1);
- if( 1 ){
- var dca = dojo.config.addOnLoad;
- if(dca){
- ready[(lang.isArray(dca) ? "apply" : "call")](dojo, dca);
- }
- }
- if( 1 && dojo.config.parseOnLoad && !dojo.isAsync){
- ready(99, function(){
- if(!dojo.parser){
- dojo.deprecated("Add explicit require(['dojo/parser']);", "", "2.0");
- require(["dojo/parser"]);
- }
- });
- }
- if( 1 ){
- domReady(handleDomReady);
- }else{
- handleDomReady();
- }
- return ready;
- });
- },
- 'dojo/_base/connect':function(){
- define(["./kernel", "../on", "../topic", "../aspect", "./event", "../mouse", "./sniff", "./lang", "../keys"], function(dojo, on, hub, aspect, eventModule, mouse, has, lang){
- // module:
- // dojo/_base/connect
- has.add("events-keypress-typed", function(){ // keypresses should only occur a printable character is hit
- var testKeyEvent = {charCode: 0};
- try{
- testKeyEvent = document.createEvent("KeyboardEvent");
- (testKeyEvent.initKeyboardEvent || testKeyEvent.initKeyEvent).call(testKeyEvent, "keypress", true, true, null, false, false, false, false, 9, 3);
- }catch(e){}
- return testKeyEvent.charCode == 0 && !has("opera");
- });
- function connect_(obj, event, context, method, dontFix){
- method = lang.hitch(context, method);
- if(!obj || !(obj.addEventListener || obj.attachEvent)){
- // it is a not a DOM node and we are using the dojo.connect style of treating a
- // method like an event, must go right to aspect
- return aspect.after(obj || dojo.global, event, method, true);
- }
- if(typeof event == "string" && event.substring(0, 2) == "on"){
- event = event.substring(2);
- }
- if(!obj){
- obj = dojo.global;
- }
- if(!dontFix){
- switch(event){
- // dojo.connect has special handling for these event types
- case "keypress":
- event = keypress;
- break;
- case "mouseenter":
- event = mouse.enter;
- break;
- case "mouseleave":
- event = mouse.leave;
- break;
- }
- }
- return on(obj, event, method, dontFix);
- }
- var _punctMap = {
- 106:42,
- 111:47,
- 186:59,
- 187:43,
- 188:44,
- 189:45,
- 190:46,
- 191:47,
- 192:96,
- 219:91,
- 220:92,
- 221:93,
- 222:39,
- 229:113
- };
- var evtCopyKey = has("mac") ? "metaKey" : "ctrlKey";
- var _synthesizeEvent = function(evt, props){
- var faux = lang.mixin({}, evt, props);
- setKeyChar(faux);
- // FIXME: would prefer to use lang.hitch: lang.hitch(evt, evt.preventDefault);
- // but it throws an error when preventDefault is invoked on Safari
- // does Event.preventDefault not support "apply" on Safari?
- faux.preventDefault = function(){ evt.preventDefault(); };
- faux.stopPropagation = function(){ evt.stopPropagation(); };
- return faux;
- };
- function setKeyChar(evt){
- evt.keyChar = evt.charCode ? String.fromCharCode(evt.charCode) : '';
- evt.charOrCode = evt.keyChar || evt.keyCode;
- }
- var keypress;
- if(has("events-keypress-typed")){
- // this emulates Firefox's keypress behavior where every keydown can correspond to a keypress
- var _trySetKeyCode = function(e, code){
- try{
- // squelch errors when keyCode is read-only
- // (e.g. if keyCode is ctrl or shift)
- return (e.keyCode = code);
- }catch(e){
- return 0;
- }
- };
- keypress = function(object, listener){
- var keydownSignal = on(object, "keydown", function(evt){
- // munge key/charCode
- var k=evt.keyCode;
- // These are Windows Virtual Key Codes
- // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/WinUI/WindowsUserInterface/UserInput/VirtualKeyCodes.asp
- var unprintable = (k!=13) && k!=32 && (k!=27||!has("ie")) && (k<48||k>90) && (k<96||k>111) && (k<186||k>192) && (k<219||k>222) && k!=229;
- // synthesize keypress for most unprintables and CTRL-keys
- if(unprintable||evt.ctrlKey){
- var c = unprintable ? 0 : k;
- if(evt.ctrlKey){
- if(k==3 || k==13){
- return listener.call(evt.currentTarget, evt); // IE will post CTRL-BREAK, CTRL-ENTER as keypress natively
- }else if(c>95 && c<106){
- c -= 48; // map CTRL-[numpad 0-9] to ASCII
- }else if((!evt.shiftKey)&&(c>=65&&c<=90)){
- c += 32; // map CTRL-[A-Z] to lowercase
- }else{
- c = _punctMap[c] || c; // map other problematic CTRL combinations to ASCII
- }
- }
- // simulate a keypress event
- var faux = _synthesizeEvent(evt, {type: 'keypress', faux: true, charCode: c});
- listener.call(evt.currentTarget, faux);
- if(has("ie")){
- _trySetKeyCode(evt, faux.keyCode);
- }
- }
- });
- var keypressSignal = on(object, "keypress", function(evt){
- var c = evt.charCode;
- c = c>=32 ? c : 0;
- evt = _synthesizeEvent(evt, {charCode: c, faux: true});
- return listener.call(this, evt);
- });
- return {
- remove: function(){
- keydownSignal.remove();
- keypressSignal.remove();
- }
- };
- };
- }else{
- if(has("opera")){
- keypress = function(object, listener){
- return on(object, "keypress", function(evt){
- var c = evt.which;
- if(c==3){
- c=99; // Mozilla maps CTRL-BREAK to CTRL-c
- }
- // can't trap some keys at all, like INSERT and DELETE
- // there is no differentiating info between DELETE and ".", or INSERT and "-"
- c = c<32 && !evt.shiftKey ? 0 : c;
- if(evt.ctrlKey && !evt.shiftKey && c>=65 && c<=90){
- // lowercase CTRL-[A-Z] keys
- c += 32;
- }
- return listener.call(this, _synthesizeEvent(evt, { charCode: c }));
- });
- };
- }else{
- keypress = function(object, listener){
- return on(object, "keypress", function(evt){
- setKeyChar(evt);
- return listener.call(this, evt);
- });
- };
- }
- }
- var connect = {
- // summary:
- // This module defines the dojo.connect API.
- // This modules also provides keyboard event handling helpers.
- // This module exports an extension event for emulating Firefox's keypress handling.
- // However, this extension event exists primarily for backwards compatibility and
- // is not recommended. WebKit and IE uses an alternate keypress handling (only
- // firing for printable characters, to distinguish from keydown events), and most
- // consider the WebKit/IE behavior more desirable.
- _keypress:keypress,
- connect:function(obj, event, context, method, dontFix){
- // summary:
- // `dojo.connect` is a deprecated event handling and delegation method in
- // Dojo. It allows one function to "listen in" on the execution of
- // any other, triggering the second whenever the first is called. Many
- // listeners may be attached to a function, and source functions may
- // be either regular function calls or DOM events.
- //
- // description:
- // Connects listeners to actions, so that after event fires, a
- // listener is called with the same arguments passed to the original
- // function.
- //
- // Since `dojo.connect` allows the source of events to be either a
- // "regular" JavaScript function or a DOM event, it provides a uniform
- // interface for listening to all the types of events that an
- // application is likely to deal with though a single, unified
- // interface. DOM programmers may want to think of it as
- // "addEventListener for everything and anything".
- //
- // When setting up a connection, the `event` parameter must be a
- // string that is the name of the method/event to be listened for. If
- // `obj` is null, `kernel.global` is assumed, meaning that connections
- // to global methods are supported but also that you may inadvertently
- // connect to a global by passing an incorrect object name or invalid
- // reference.
- //
- // `dojo.connect` generally is forgiving. If you pass the name of a
- // function or method that does not yet exist on `obj`, connect will
- // not fail, but will instead set up a stub method. Similarly, null
- // arguments may simply be omitted such that fewer than 4 arguments
- // may be required to set up a connection See the examples for details.
- //
- // The return value is a handle that is needed to
- // remove this connection with `dojo.disconnect`.
- //
- // obj: Object?
- // The source object for the event function.
- // Defaults to `kernel.global` if null.
- // If obj is a DOM node, the connection is delegated
- // to the DOM event manager (unless dontFix is true).
- //
- // event: String
- // String name of the event function in obj.
- // I.e. identifies a property `obj[event]`.
- //
- // context: Object|null
- // The object that method will receive as "this".
- //
- // If context is null and method is a function, then method
- // inherits the context of event.
- //
- // If method is a string then context must be the source
- // object object for method (context[method]). If context is null,
- // kernel.global is used.
- //
- // method: String|Function
- // A function reference, or name of a function in context.
- // The function identified by method fires after event does.
- // method receives the same arguments as the event.
- // See context argument comments for information on method's scope.
- //
- // dontFix: Boolean?
- // If obj is a DOM node, set dontFix to true to prevent delegation
- // of this connection to the DOM event manager.
- //
- // example:
- // When obj.onchange(), do ui.update():
- // | dojo.connect(obj, "onchange", ui, "update");
- // | dojo.connect(obj, "onchange", ui, ui.update); // same
- //
- // example:
- // Using return value for disconnect:
- // | var link = dojo.connect(obj, "onchange", ui, "update");
- // | ...
- // | dojo.disconnect(link);
- //
- // example:
- // When onglobalevent executes, watcher.handler is invoked:
- // | dojo.connect(null, "onglobalevent", watcher, "handler");
- //
- // example:
- // When ob.onCustomEvent executes, customEventHandler is invoked:
- // | dojo.connect(ob, "onCustomEvent", null, "customEventHandler");
- // | dojo.connect(ob, "onCustomEvent", "customEventHandler"); // same
- //
- // example:
- // When ob.onCustomEvent executes, customEventHandler is invoked
- // with the same scope (this):
- // | dojo.connect(ob, "onCustomEvent", null, customEventHandler);
- // | dojo.connect(ob, "onCustomEvent", customEventHandler); // same
- //
- // example:
- // When globalEvent executes, globalHandler is invoked
- // with the same scope (this):
- // | dojo.connect(null, "globalEvent", null, globalHandler);
- // | dojo.connect("globalEvent", globalHandler); // same
- // normalize arguments
- var a=arguments, args=[], i=0;
- // if a[0] is a String, obj was omitted
- args.push(typeof a[0] == "string" ? null : a[i++], a[i++]);
- // if the arg-after-next is a String or Function, context was NOT omitted
- var a1 = a[i+1];
- args.push(typeof a1 == "string" || typeof a1 == "function" ? a[i++] : null, a[i++]);
- // absorb any additional arguments
- for(var l=a.length; i<l; i++){ args.push(a[i]); }
- return connect_.apply(this, args);
- },
- disconnect:function(handle){
- // summary:
- // Remove a link created by dojo.connect.
- // description:
- // Removes the connection between event and the method referenced by handle.
- // handle: Handle
- // the return value of the dojo.connect call that created the connection.
- if(handle){
- handle.remove();
- }
- },
- subscribe:function(topic, context, method){
- // summary:
- // Attach a listener to a named topic. The listener function is invoked whenever the
- // named topic is published (see: dojo.publish).
- // Returns a handle which is needed to unsubscribe this listener.
- // topic: String
- // The topic to which to subscribe.
- // context: Object?
- // Scope in which method will be invoked, or null for default scope.
- // method: String|Function
- // The name of a function in context, or a function reference. This is the function that
- // is invoked when topic is published.
- // example:
- // | dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); });
- // | dojo.publish("alerts", [ "read this", "hello world" ]);
- return hub.subscribe(topic, lang.hitch(context, method));
- },
- publish:function(topic, args){
- // summary:
- // Invoke all listener method subscribed to topic.
- // topic: String
- // The name of the topic to publish.
- // args: Array?
- // An array of arguments. The arguments will be applied
- // to each topic subscriber (as first class parameters, via apply).
- // example:
- // | dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
- // | dojo.publish("alerts", [ "read this", "hello world" ]);
- return hub.publish.apply(hub, [topic].concat(args));
- },
- connectPublisher:function(topic, obj, event){
- // summary:
- // Ensure that every time obj.event() is called, a message is published
- // on the topic. Returns a handle which can be passed to
- // dojo.disconnect() to disable subsequent automatic publication on
- // the topic.
- // topic: String
- // The name of the topic to publish.
- // obj: Object?
- // The source object for the event function. Defaults to kernel.global
- // if null.
- // event: String
- // The name of the event function in obj.
- // I.e. identifies a property obj[event].
- // example:
- // | dojo.connectPublisher("/ajax/start", dojo, "xhrGet");
- var pf = function(){ connect.publish(topic, arguments); };
- return event ? connect.connect(obj, event, pf) : connect.connect(obj, pf); //Handle
- },
- isCopyKey: function(e){
- // summary:
- // Checks an event for the copy key (meta on Mac, and ctrl anywhere else)
- // e: Event
- // Event object to examine
- return e[evtCopyKey]; // Boolean
- }
- };
- connect.unsubscribe = connect.disconnect;
- /*=====
- connect.unsubscribe = function(handle){
- // summary:
- // Remove a topic listener.
- // handle: Handle
- // The handle returned from a call to subscribe.
- // example:
- // | var alerter = dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
- // | ...
- // | dojo.unsubscribe(alerter);
- };
- =====*/
- 1 && lang.mixin(dojo, connect);
- return connect;
- });
- },
- 'dojo/errors/CancelError':function(){
- define(["./create"], function(create){
- // module:
- // dojo/errors/CancelError
- /*=====
- return function(){
- // summary:
- // Default error if a promise is canceled without a reason.
- };
- =====*/
- return create("CancelError", null, null, { dojoType: "cancel" });
- });
- }}});
- (function(){
- // must use this.require to make this work in node.js
- var require = this.require;
- // consume the cached dojo layer
- require({cache:{}});
- !require.async && require(["dojo"]);
- require.boot && require.apply(null, require.boot);
- })();
|