mobile.js.uncompressed.js 142 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571
  1. require({cache:{
  2. 'dojox/mobile/ViewController':function(){
  3. define("dojox/mobile/ViewController", [
  4. "dojo/_base/kernel",
  5. "dojo/_base/array",
  6. "dojo/_base/connect",
  7. "dojo/_base/declare",
  8. "dojo/_base/lang",
  9. "dojo/_base/window",
  10. "dojo/dom",
  11. "dojo/dom-class",
  12. "dojo/dom-construct",
  13. // "dojo/hash", // optionally prereq'ed
  14. "dojo/on",
  15. "dojo/ready",
  16. "dijit/registry", // registry.byId
  17. "./ProgressIndicator",
  18. "./TransitionEvent"
  19. ], function(dojo, array, connect, declare, lang, win, dom, domClass, domConstruct, on, ready, registry, ProgressIndicator, TransitionEvent){
  20. // module:
  21. // dojox/mobile/ViewController
  22. // summary:
  23. // A singleton class that controlls view transition.
  24. var dm = lang.getObject("dojox.mobile", true);
  25. var Controller = declare("dojox.mobile.ViewController", null, {
  26. // summary:
  27. // A singleton class that controlls view transition.
  28. // description:
  29. // This class listens to the "startTransition" events and performs
  30. // view transitions. If the transition destination is an external
  31. // view specified with the url parameter, retrieves the view
  32. // content and parses it to create a new target view.
  33. constructor: function(){
  34. this.viewMap={};
  35. this.currentView=null;
  36. this.defaultView=null;
  37. ready(lang.hitch(this, function(){
  38. on(win.body(), "startTransition", lang.hitch(this, "onStartTransition"));
  39. }));
  40. },
  41. findCurrentView: function(moveTo,src){
  42. // summary:
  43. // Searches for the currently showing view.
  44. if(moveTo){
  45. var w = registry.byId(moveTo);
  46. if(w && w.getShowingView){ return w.getShowingView(); }
  47. }
  48. if(dm.currentView){
  49. return dm.currentView; //TODO:1.8 may not return an expected result especially when views are nested
  50. }
  51. //TODO:1.8 probably never reaches here
  52. w = src;
  53. while(true){
  54. w = w.getParent();
  55. if(!w){ return null; }
  56. if(domClass.contains(w.domNode, "mblView")){ break; }
  57. }
  58. return w;
  59. },
  60. onStartTransition: function(evt){
  61. // summary:
  62. // A handler that performs view transition.
  63. evt.preventDefault();
  64. if(!evt.detail || (evt.detail && !evt.detail.moveTo && !evt.detail.href && !evt.detail.url && !evt.detail.scene)){ return; }
  65. var w = this.findCurrentView(evt.detail.moveTo, (evt.target && evt.target.id)?registry.byId(evt.target.id):registry.byId(evt.target)); // the current view widget
  66. if(!w || (evt.detail && evt.detail.moveTo && w === registry.byId(evt.detail.moveTo))){ return; }
  67. if(evt.detail.href){
  68. var t = registry.byId(evt.target.id).hrefTarget;
  69. if(t){
  70. dm.openWindow(evt.detail.href, t);
  71. }else{
  72. w.performTransition(null, evt.detail.transitionDir, evt.detail.transition, evt.target, function(){location.href = evt.detail.href;});
  73. }
  74. return;
  75. } else if(evt.detail.scene){
  76. connect.publish("/dojox/mobile/app/pushScene", [evt.detail.scene]);
  77. return;
  78. }
  79. var moveTo = evt.detail.moveTo;
  80. if(evt.detail.url){
  81. var id;
  82. if(dm._viewMap && dm._viewMap[evt.detail.url]){
  83. // external view has already been loaded
  84. id = dm._viewMap[evt.detail.url];
  85. }else{
  86. // get the specified external view and append it to the <body>
  87. var text = this._text;
  88. if(!text){
  89. if(registry.byId(evt.target.id).sync){
  90. // We do not add explicit dependency on dojo/_base/xhr to this module
  91. // to be able to create a build that does not contain dojo/_base/xhr.
  92. // User applications that do sync loading here need to explicitly
  93. // require dojo/_base/xhr up front.
  94. dojo.xhrGet({url:evt.detail.url, sync:true, load:function(result){
  95. text = lang.trim(result);
  96. }});
  97. }else{
  98. var s = "dojo/_base/xhr"; // assign to a variable so as not to be picked up by the build tool
  99. require([s], lang.hitch(this, function(xhr){
  100. var prog = ProgressIndicator.getInstance();
  101. win.body().appendChild(prog.domNode);
  102. prog.start();
  103. var obj = xhr.get({
  104. url: evt.detail.url,
  105. handleAs: "text"
  106. });
  107. obj.addCallback(lang.hitch(this, function(response, ioArgs){
  108. prog.stop();
  109. if(response){
  110. this._text = response;
  111. new TransitionEvent(evt.target, {
  112. transition: evt.detail.transition,
  113. transitionDir: evt.detail.transitionDir,
  114. moveTo: moveTo,
  115. href: evt.detail.href,
  116. url: evt.detail.url,
  117. scene: evt.detail.scene},
  118. evt.detail)
  119. .dispatch();
  120. }
  121. }));
  122. obj.addErrback(function(error){
  123. prog.stop();
  124. console.log("Failed to load "+evt.detail.url+"\n"+(error.description||error));
  125. });
  126. }));
  127. return;
  128. }
  129. }
  130. this._text = null;
  131. id = this._parse(text, registry.byId(evt.target.id).urlTarget);
  132. if(!dm._viewMap){
  133. dm._viewMap = [];
  134. }
  135. dm._viewMap[evt.detail.url] = id;
  136. }
  137. moveTo = id;
  138. w = this.findCurrentView(moveTo,registry.byId(evt.target.id)) || w; // the current view widget
  139. }
  140. var src = registry.getEnclosingWidget(evt.target);
  141. var context, method;
  142. if(src && src.callback){
  143. context = src;
  144. method = src.callback;
  145. }
  146. w.performTransition(moveTo, evt.detail.transitionDir, evt.detail.transition, context, method);
  147. },
  148. _parse: function(text, id){
  149. // summary:
  150. // Parses the given view content.
  151. // description:
  152. // If the content is html fragment, constructs dom tree with it
  153. // and runs the parser. If the content is json data, passes it
  154. // to _instantiate().
  155. var container, view, i, j, len;
  156. var currentView = this.findCurrentView();
  157. var target = registry.byId(id) && registry.byId(id).containerNode
  158. || dom.byId(id)
  159. || currentView && currentView.domNode.parentNode
  160. || win.body();
  161. // if a fixed bottom bar exists, a new view should be placed before it.
  162. var refNode = null;
  163. for(j = target.childNodes.length - 1; j >= 0; j--){
  164. var c = target.childNodes[j];
  165. if(c.nodeType === 1){
  166. if(c.getAttribute("fixed") === "bottom"){
  167. refNode = c;
  168. break;
  169. }
  170. }
  171. }
  172. if(text.charAt(0) === "<"){ // html markup
  173. container = domConstruct.create("DIV", {innerHTML: text});
  174. for(i = 0; i < container.childNodes.length; i++){
  175. var n = container.childNodes[i];
  176. if(n.nodeType === 1){
  177. view = n; // expecting <div dojoType="dojox.mobile.View">
  178. break;
  179. }
  180. }
  181. if(!view){
  182. console.log("dojox.mobile.ViewController#_parse: invalid view content");
  183. return;
  184. }
  185. view.style.visibility = "hidden";
  186. target.insertBefore(container, refNode);
  187. var ws = dojo.parser.parse(container);
  188. array.forEach(ws, function(w){
  189. if(w && !w._started && w.startup){
  190. w.startup();
  191. }
  192. });
  193. // allows multiple root nodes in the fragment,
  194. // but transition will be performed to the 1st view.
  195. for(i = 0, len = container.childNodes.length; i < len; i++){
  196. target.insertBefore(container.firstChild, refNode); // reparent
  197. }
  198. target.removeChild(container);
  199. registry.byNode(view)._visible = true;
  200. }else if(text.charAt(0) === "{"){ // json
  201. container = domConstruct.create("DIV");
  202. target.insertBefore(container, refNode);
  203. this._ws = [];
  204. view = this._instantiate(eval('('+text+')'), container);
  205. for(i = 0; i < this._ws.length; i++){
  206. var w = this._ws[i];
  207. w.startup && !w._started && (!w.getParent || !w.getParent()) && w.startup();
  208. }
  209. this._ws = null;
  210. }
  211. view.style.display = "none";
  212. view.style.visibility = "visible";
  213. return dojo.hash ? "#" + view.id : view.id;
  214. },
  215. _instantiate: function(/*Object*/obj, /*DomNode*/node, /*Widget*/parent){
  216. // summary:
  217. // Given the evaluated json data, does the same thing as what
  218. // the parser does.
  219. var widget;
  220. for(var key in obj){
  221. if(key.charAt(0) == "@"){ continue; }
  222. var cls = lang.getObject(key);
  223. if(!cls){ continue; }
  224. var params = {};
  225. var proto = cls.prototype;
  226. var objs = lang.isArray(obj[key]) ? obj[key] : [obj[key]];
  227. for(var i = 0; i < objs.length; i++){
  228. for(var prop in objs[i]){
  229. if(prop.charAt(0) == "@"){
  230. var val = objs[i][prop];
  231. prop = prop.substring(1);
  232. if(typeof proto[prop] == "string"){
  233. params[prop] = val;
  234. }else if(typeof proto[prop] == "number"){
  235. params[prop] = val - 0;
  236. }else if(typeof proto[prop] == "boolean"){
  237. params[prop] = (val != "false");
  238. }else if(typeof proto[prop] == "object"){
  239. params[prop] = eval("(" + val + ")");
  240. }
  241. }
  242. }
  243. widget = new cls(params, node);
  244. if(node){ // to call View's startup()
  245. widget._visible = true;
  246. this._ws.push(widget);
  247. }
  248. if(parent && parent.addChild){
  249. parent.addChild(widget);
  250. }
  251. this._instantiate(objs[i], null, widget);
  252. }
  253. }
  254. return widget && widget.domNode;
  255. }
  256. });
  257. new Controller(); // singleton
  258. return Controller;
  259. });
  260. },
  261. 'dojox/mobile/RoundRect':function(){
  262. define("dojox/mobile/RoundRect", [
  263. "dojo/_base/array",
  264. "dojo/_base/declare",
  265. "dojo/_base/window",
  266. "dijit/_Contained",
  267. "dijit/_Container",
  268. "dijit/_WidgetBase"
  269. ], function(array, declare, win, Contained, Container, WidgetBase){
  270. /*=====
  271. var Contained = dijit._Contained;
  272. var Container = dijit._Container;
  273. var WidgetBase = dijit._WidgetBase;
  274. =====*/
  275. // module:
  276. // dojox/mobile/RoundRect
  277. // summary:
  278. // A simple round rectangle container.
  279. return declare("dojox.mobile.RoundRect", [WidgetBase, Container, Contained], {
  280. // summary:
  281. // A simple round rectangle container.
  282. // description:
  283. // RoundRect is a simple round rectangle container for any HTML
  284. // and/or widgets. You can achieve the same appearance by just
  285. // applying the -webkit-border-radius style to a div tag. However,
  286. // if you use RoundRect, you can get a round rectangle even on
  287. // non-CSS3 browsers such as (older) IE.
  288. // shadow: Boolean
  289. // If true, adds a shadow effect to the container element.
  290. shadow: false,
  291. buildRendering: function(){
  292. this.domNode = this.containerNode = this.srcNodeRef || win.doc.createElement("DIV");
  293. this.domNode.className = this.shadow ? "mblRoundRect mblShadow" : "mblRoundRect";
  294. },
  295. resize: function(){
  296. // summary:
  297. // Calls resize() of each child widget.
  298. array.forEach(this.getChildren(), function(child){
  299. if(child.resize){ child.resize(); }
  300. });
  301. }
  302. });
  303. });
  304. },
  305. 'dojox/mobile/RoundRectList':function(){
  306. define("dojox/mobile/RoundRectList", [
  307. "dojo/_base/array",
  308. "dojo/_base/declare",
  309. "dojo/_base/window",
  310. "dijit/_Contained",
  311. "dijit/_Container",
  312. "dijit/_WidgetBase"
  313. ], function(array, declare, win, Contained, Container, WidgetBase){
  314. /*=====
  315. var Contained = dijit._Contained;
  316. var Container = dijit._Container;
  317. var WidgetBase = dijit._WidgetBase;
  318. =====*/
  319. // module:
  320. // dojox/mobile/RoundRectList
  321. // summary:
  322. // A rounded rectangle list.
  323. return declare("dojox.mobile.RoundRectList", [WidgetBase, Container, Contained], {
  324. // summary:
  325. // A rounded rectangle list.
  326. // description:
  327. // RoundRectList is a rounded rectangle list, which can be used to
  328. // display a group of items. Each item must be
  329. // dojox.mobile.ListItem.
  330. // transition: String
  331. // The default animated transition effect for child items.
  332. transition: "slide",
  333. // iconBase: String
  334. // The default icon path for child items.
  335. iconBase: "",
  336. // iconPos: String
  337. // The default icon position for child items.
  338. iconPos: "",
  339. // select: String
  340. // Selection mode of the list. The check mark is shown for the
  341. // selected list item(s). The value can be "single", "multiple", or
  342. // "". If "single", there can be only one selected item at a time.
  343. // If "multiple", there can be multiple selected items at a time.
  344. select: "",
  345. // stateful: String
  346. // If true, the last selected item remains highlighted.
  347. stateful: false,
  348. buildRendering: function(){
  349. this.domNode = this.containerNode = this.srcNodeRef || win.doc.createElement("UL");
  350. this.domNode.className = "mblRoundRectList";
  351. },
  352. resize: function(){
  353. // summary:
  354. // Calls resize() of each child widget.
  355. array.forEach(this.getChildren(), function(child){
  356. if(child.resize){ child.resize(); }
  357. });
  358. },
  359. onCheckStateChanged: function(/*Widget*/listItem, /*String*/newState){
  360. // summary:
  361. // Stub function to connect to from your application.
  362. // description:
  363. // Called when the check state has been changed.
  364. },
  365. _setStatefulAttr: function(stateful){
  366. this.stateful = stateful;
  367. array.forEach(this.getChildren(), function(child){
  368. child.setArrow && child.setArrow();
  369. });
  370. },
  371. deselectItem: function(/*ListItem*/item){
  372. // summary:
  373. // Deselects the given item.
  374. item.deselect();
  375. },
  376. deselectAll: function(){
  377. // summary:
  378. // Deselects all the items.
  379. array.forEach(this.getChildren(), function(child){
  380. child.deselect && child.deselect();
  381. });
  382. },
  383. selectItem: function(/*ListItem*/item){
  384. // summary:
  385. // Selects the given item.
  386. item.select();
  387. }
  388. });
  389. });
  390. },
  391. 'dojox/mobile/sniff':function(){
  392. define("dojox/mobile/sniff", [
  393. "dojo/_base/window",
  394. "dojo/_base/sniff"
  395. ], function(win, has){
  396. var ua = navigator.userAgent;
  397. // BlackBerry (OS 6 or later only)
  398. has.add("bb", ua.indexOf("BlackBerry") >= 0 && parseFloat(ua.split("Version/")[1]) || undefined, undefined, true);
  399. // Android
  400. has.add("android", parseFloat(ua.split("Android ")[1]) || undefined, undefined, true);
  401. // iPhone, iPod, or iPad
  402. // If iPod or iPad is detected, in addition to has("ipod") or has("ipad"),
  403. // has("iphone") will also have iOS version number.
  404. if(ua.match(/(iPhone|iPod|iPad)/)){
  405. var p = RegExp.$1.replace(/P/, 'p');
  406. var v = ua.match(/OS ([\d_]+)/) ? RegExp.$1 : "1";
  407. var os = parseFloat(v.replace(/_/, '.').replace(/_/g, ''));
  408. has.add(p, os, undefined, true);
  409. has.add("iphone", os, undefined, true);
  410. }
  411. if(has("webkit")){
  412. has.add("touch", (typeof win.doc.documentElement.ontouchstart != "undefined" &&
  413. navigator.appVersion.indexOf("Mobile") != -1) || !!has("android"), undefined, true);
  414. }
  415. return has;
  416. });
  417. },
  418. 'dojox/mobile/TransitionEvent':function(){
  419. define("dojox/mobile/TransitionEvent", [
  420. "dojo/_base/declare",
  421. "dojo/_base/Deferred",
  422. "dojo/_base/lang",
  423. "dojo/on",
  424. "./transition"
  425. ], function(declare, Deferred, lang, on, transitDeferred){
  426. return declare("dojox.mobile.TransitionEvent", null, {
  427. constructor: function(target, transitionOptions, triggerEvent){
  428. this.transitionOptions=transitionOptions;
  429. this.target = target;
  430. this.triggerEvent=triggerEvent||null;
  431. },
  432. dispatch: function(){
  433. var opts = {bubbles:true, cancelable:true, detail: this.transitionOptions, triggerEvent: this.triggerEvent};
  434. //console.log("Target: ", this.target, " opts: ", opts);
  435. var evt = on.emit(this.target,"startTransition", opts);
  436. //console.log('evt: ', evt);
  437. if(evt){
  438. Deferred.when(transitDeferred, lang.hitch(this, function(transition){
  439. Deferred.when(transition.call(this, evt), lang.hitch(this, function(results){
  440. this.endTransition(results);
  441. }));
  442. }));
  443. }
  444. },
  445. endTransition: function(results){
  446. on.emit(this.target, "endTransition" , {detail: results.transitionOptions});
  447. }
  448. });
  449. });
  450. },
  451. 'dijit/_WidgetBase':function(){
  452. define("dijit/_WidgetBase", [
  453. "require", // require.toUrl
  454. "dojo/_base/array", // array.forEach array.map
  455. "dojo/aspect",
  456. "dojo/_base/config", // config.blankGif
  457. "dojo/_base/connect", // connect.connect
  458. "dojo/_base/declare", // declare
  459. "dojo/dom", // dom.byId
  460. "dojo/dom-attr", // domAttr.set domAttr.remove
  461. "dojo/dom-class", // domClass.add domClass.replace
  462. "dojo/dom-construct", // domConstruct.create domConstruct.destroy domConstruct.place
  463. "dojo/dom-geometry", // isBodyLtr
  464. "dojo/dom-style", // domStyle.set, domStyle.get
  465. "dojo/_base/kernel",
  466. "dojo/_base/lang", // mixin(), isArray(), etc.
  467. "dojo/on",
  468. "dojo/ready",
  469. "dojo/Stateful", // Stateful
  470. "dojo/topic",
  471. "dojo/_base/window", // win.doc.createTextNode
  472. "./registry" // registry.getUniqueId(), registry.findWidgets()
  473. ], function(require, array, aspect, config, connect, declare,
  474. dom, domAttr, domClass, domConstruct, domGeometry, domStyle, kernel,
  475. lang, on, ready, Stateful, topic, win, registry){
  476. /*=====
  477. var Stateful = dojo.Stateful;
  478. =====*/
  479. // module:
  480. // dijit/_WidgetBase
  481. // summary:
  482. // Future base class for all Dijit widgets.
  483. // For back-compat, remove in 2.0.
  484. if(!kernel.isAsync){
  485. ready(0, function(){
  486. var requires = ["dijit/_base/manager"];
  487. require(requires); // use indirection so modules not rolled into a build
  488. });
  489. }
  490. // Nested hash listing attributes for each tag, all strings in lowercase.
  491. // ex: {"div": {"style": true, "tabindex" true}, "form": { ...
  492. var tagAttrs = {};
  493. function getAttrs(obj){
  494. var ret = {};
  495. for(var attr in obj){
  496. ret[attr.toLowerCase()] = true;
  497. }
  498. return ret;
  499. }
  500. function nonEmptyAttrToDom(attr){
  501. // summary:
  502. // Returns a setter function that copies the attribute to this.domNode,
  503. // or removes the attribute from this.domNode, depending on whether the
  504. // value is defined or not.
  505. return function(val){
  506. domAttr[val ? "set" : "remove"](this.domNode, attr, val);
  507. this._set(attr, val);
  508. };
  509. }
  510. function isEqual(a, b){
  511. // summary:
  512. // Function that determines whether two values are identical,
  513. // taking into account that NaN is not normally equal to itself
  514. // in JS.
  515. return a === b || (/* a is NaN */ a !== a && /* b is NaN */ b !== b);
  516. }
  517. return declare("dijit._WidgetBase", Stateful, {
  518. // summary:
  519. // Future base class for all Dijit widgets.
  520. // description:
  521. // Future base class for all Dijit widgets.
  522. // _Widget extends this class adding support for various features needed by desktop.
  523. //
  524. // Provides stubs for widget lifecycle methods for subclasses to extend, like postMixInProperties(), buildRendering(),
  525. // postCreate(), startup(), and destroy(), and also public API methods like set(), get(), and watch().
  526. //
  527. // Widgets can provide custom setters/getters for widget attributes, which are called automatically by set(name, value).
  528. // For an attribute XXX, define methods _setXXXAttr() and/or _getXXXAttr().
  529. //
  530. // _setXXXAttr can also be a string/hash/array mapping from a widget attribute XXX to the widget's DOMNodes:
  531. //
  532. // - DOM node attribute
  533. // | _setFocusAttr: {node: "focusNode", type: "attribute"}
  534. // | _setFocusAttr: "focusNode" (shorthand)
  535. // | _setFocusAttr: "" (shorthand, maps to this.domNode)
  536. // Maps this.focus to this.focusNode.focus, or (last example) this.domNode.focus
  537. //
  538. // - DOM node innerHTML
  539. // | _setTitleAttr: { node: "titleNode", type: "innerHTML" }
  540. // Maps this.title to this.titleNode.innerHTML
  541. //
  542. // - DOM node innerText
  543. // | _setTitleAttr: { node: "titleNode", type: "innerText" }
  544. // Maps this.title to this.titleNode.innerText
  545. //
  546. // - DOM node CSS class
  547. // | _setMyClassAttr: { node: "domNode", type: "class" }
  548. // Maps this.myClass to this.domNode.className
  549. //
  550. // If the value of _setXXXAttr is an array, then each element in the array matches one of the
  551. // formats of the above list.
  552. //
  553. // If the custom setter is null, no action is performed other than saving the new value
  554. // in the widget (in this).
  555. //
  556. // If no custom setter is defined for an attribute, then it will be copied
  557. // to this.focusNode (if the widget defines a focusNode), or this.domNode otherwise.
  558. // That's only done though for attributes that match DOMNode attributes (title,
  559. // alt, aria-labelledby, etc.)
  560. // id: [const] String
  561. // A unique, opaque ID string that can be assigned by users or by the
  562. // system. If the developer passes an ID which is known not to be
  563. // unique, the specified ID is ignored and the system-generated ID is
  564. // used instead.
  565. id: "",
  566. _setIdAttr: "domNode", // to copy to this.domNode even for auto-generated id's
  567. // lang: [const] String
  568. // Rarely used. Overrides the default Dojo locale used to render this widget,
  569. // as defined by the [HTML LANG](http://www.w3.org/TR/html401/struct/dirlang.html#adef-lang) attribute.
  570. // Value must be among the list of locales specified during by the Dojo bootstrap,
  571. // formatted according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt) (like en-us).
  572. lang: "",
  573. // set on domNode even when there's a focus node. but don't set lang="", since that's invalid.
  574. _setLangAttr: nonEmptyAttrToDom("lang"),
  575. // dir: [const] String
  576. // Bi-directional support, as defined by the [HTML DIR](http://www.w3.org/TR/html401/struct/dirlang.html#adef-dir)
  577. // attribute. Either left-to-right "ltr" or right-to-left "rtl". If undefined, widgets renders in page's
  578. // default direction.
  579. dir: "",
  580. // set on domNode even when there's a focus node. but don't set dir="", since that's invalid.
  581. _setDirAttr: nonEmptyAttrToDom("dir"), // to set on domNode even when there's a focus node
  582. // textDir: String
  583. // Bi-directional support, the main variable which is responsible for the direction of the text.
  584. // The text direction can be different than the GUI direction by using this parameter in creation
  585. // of a widget.
  586. // Allowed values:
  587. // 1. "ltr"
  588. // 2. "rtl"
  589. // 3. "auto" - contextual the direction of a text defined by first strong letter.
  590. // By default is as the page direction.
  591. textDir: "",
  592. // class: String
  593. // HTML class attribute
  594. "class": "",
  595. _setClassAttr: { node: "domNode", type: "class" },
  596. // style: String||Object
  597. // HTML style attributes as cssText string or name/value hash
  598. style: "",
  599. // title: String
  600. // HTML title attribute.
  601. //
  602. // For form widgets this specifies a tooltip to display when hovering over
  603. // the widget (just like the native HTML title attribute).
  604. //
  605. // For TitlePane or for when this widget is a child of a TabContainer, AccordionContainer,
  606. // etc., it's used to specify the tab label, accordion pane title, etc.
  607. title: "",
  608. // tooltip: String
  609. // When this widget's title attribute is used to for a tab label, accordion pane title, etc.,
  610. // this specifies the tooltip to appear when the mouse is hovered over that text.
  611. tooltip: "",
  612. // baseClass: [protected] String
  613. // Root CSS class of the widget (ex: dijitTextBox), used to construct CSS classes to indicate
  614. // widget state.
  615. baseClass: "",
  616. // srcNodeRef: [readonly] DomNode
  617. // pointer to original DOM node
  618. srcNodeRef: null,
  619. // domNode: [readonly] DomNode
  620. // This is our visible representation of the widget! Other DOM
  621. // Nodes may by assigned to other properties, usually through the
  622. // template system's data-dojo-attach-point syntax, but the domNode
  623. // property is the canonical "top level" node in widget UI.
  624. domNode: null,
  625. // containerNode: [readonly] DomNode
  626. // Designates where children of the source DOM node will be placed.
  627. // "Children" in this case refers to both DOM nodes and widgets.
  628. // For example, for myWidget:
  629. //
  630. // | <div data-dojo-type=myWidget>
  631. // | <b> here's a plain DOM node
  632. // | <span data-dojo-type=subWidget>and a widget</span>
  633. // | <i> and another plain DOM node </i>
  634. // | </div>
  635. //
  636. // containerNode would point to:
  637. //
  638. // | <b> here's a plain DOM node
  639. // | <span data-dojo-type=subWidget>and a widget</span>
  640. // | <i> and another plain DOM node </i>
  641. //
  642. // In templated widgets, "containerNode" is set via a
  643. // data-dojo-attach-point assignment.
  644. //
  645. // containerNode must be defined for any widget that accepts innerHTML
  646. // (like ContentPane or BorderContainer or even Button), and conversely
  647. // is null for widgets that don't, like TextBox.
  648. containerNode: null,
  649. /*=====
  650. // _started: Boolean
  651. // startup() has completed.
  652. _started: false,
  653. =====*/
  654. // attributeMap: [protected] Object
  655. // Deprecated. Instead of attributeMap, widget should have a _setXXXAttr attribute
  656. // for each XXX attribute to be mapped to the DOM.
  657. //
  658. // attributeMap sets up a "binding" between attributes (aka properties)
  659. // of the widget and the widget's DOM.
  660. // Changes to widget attributes listed in attributeMap will be
  661. // reflected into the DOM.
  662. //
  663. // For example, calling set('title', 'hello')
  664. // on a TitlePane will automatically cause the TitlePane's DOM to update
  665. // with the new title.
  666. //
  667. // attributeMap is a hash where the key is an attribute of the widget,
  668. // and the value reflects a binding to a:
  669. //
  670. // - DOM node attribute
  671. // | focus: {node: "focusNode", type: "attribute"}
  672. // Maps this.focus to this.focusNode.focus
  673. //
  674. // - DOM node innerHTML
  675. // | title: { node: "titleNode", type: "innerHTML" }
  676. // Maps this.title to this.titleNode.innerHTML
  677. //
  678. // - DOM node innerText
  679. // | title: { node: "titleNode", type: "innerText" }
  680. // Maps this.title to this.titleNode.innerText
  681. //
  682. // - DOM node CSS class
  683. // | myClass: { node: "domNode", type: "class" }
  684. // Maps this.myClass to this.domNode.className
  685. //
  686. // If the value is an array, then each element in the array matches one of the
  687. // formats of the above list.
  688. //
  689. // There are also some shorthands for backwards compatibility:
  690. // - string --> { node: string, type: "attribute" }, for example:
  691. // | "focusNode" ---> { node: "focusNode", type: "attribute" }
  692. // - "" --> { node: "domNode", type: "attribute" }
  693. attributeMap: {},
  694. // _blankGif: [protected] String
  695. // Path to a blank 1x1 image.
  696. // Used by <img> nodes in templates that really get their image via CSS background-image.
  697. _blankGif: config.blankGif || require.toUrl("dojo/resources/blank.gif"),
  698. //////////// INITIALIZATION METHODS ///////////////////////////////////////
  699. postscript: function(/*Object?*/params, /*DomNode|String*/srcNodeRef){
  700. // summary:
  701. // Kicks off widget instantiation. See create() for details.
  702. // tags:
  703. // private
  704. this.create(params, srcNodeRef);
  705. },
  706. create: function(/*Object?*/params, /*DomNode|String?*/srcNodeRef){
  707. // summary:
  708. // Kick off the life-cycle of a widget
  709. // params:
  710. // Hash of initialization parameters for widget, including
  711. // scalar values (like title, duration etc.) and functions,
  712. // typically callbacks like onClick.
  713. // srcNodeRef:
  714. // If a srcNodeRef (DOM node) is specified:
  715. // - use srcNodeRef.innerHTML as my contents
  716. // - if this is a behavioral widget then apply behavior
  717. // to that srcNodeRef
  718. // - otherwise, replace srcNodeRef with my generated DOM
  719. // tree
  720. // description:
  721. // Create calls a number of widget methods (postMixInProperties, buildRendering, postCreate,
  722. // etc.), some of which of you'll want to override. See http://dojotoolkit.org/reference-guide/dijit/_WidgetBase.html
  723. // for a discussion of the widget creation lifecycle.
  724. //
  725. // Of course, adventurous developers could override create entirely, but this should
  726. // only be done as a last resort.
  727. // tags:
  728. // private
  729. // store pointer to original DOM tree
  730. this.srcNodeRef = dom.byId(srcNodeRef);
  731. // For garbage collection. An array of listener handles returned by this.connect() / this.subscribe()
  732. this._connects = [];
  733. // For widgets internal to this widget, invisible to calling code
  734. this._supportingWidgets = [];
  735. // this is here for back-compat, remove in 2.0 (but check NodeList-instantiate.html test)
  736. if(this.srcNodeRef && (typeof this.srcNodeRef.id == "string")){ this.id = this.srcNodeRef.id; }
  737. // mix in our passed parameters
  738. if(params){
  739. this.params = params;
  740. lang.mixin(this, params);
  741. }
  742. this.postMixInProperties();
  743. // generate an id for the widget if one wasn't specified
  744. // (be sure to do this before buildRendering() because that function might
  745. // expect the id to be there.)
  746. if(!this.id){
  747. this.id = registry.getUniqueId(this.declaredClass.replace(/\./g,"_"));
  748. }
  749. registry.add(this);
  750. this.buildRendering();
  751. if(this.domNode){
  752. // Copy attributes listed in attributeMap into the [newly created] DOM for the widget.
  753. // Also calls custom setters for all attributes with custom setters.
  754. this._applyAttributes();
  755. // If srcNodeRef was specified, then swap out original srcNode for this widget's DOM tree.
  756. // For 2.0, move this after postCreate(). postCreate() shouldn't depend on the
  757. // widget being attached to the DOM since it isn't when a widget is created programmatically like
  758. // new MyWidget({}). See #11635.
  759. var source = this.srcNodeRef;
  760. if(source && source.parentNode && this.domNode !== source){
  761. source.parentNode.replaceChild(this.domNode, source);
  762. }
  763. }
  764. if(this.domNode){
  765. // Note: for 2.0 may want to rename widgetId to dojo._scopeName + "_widgetId",
  766. // assuming that dojo._scopeName even exists in 2.0
  767. this.domNode.setAttribute("widgetId", this.id);
  768. }
  769. this.postCreate();
  770. // If srcNodeRef has been processed and removed from the DOM (e.g. TemplatedWidget) then delete it to allow GC.
  771. if(this.srcNodeRef && !this.srcNodeRef.parentNode){
  772. delete this.srcNodeRef;
  773. }
  774. this._created = true;
  775. },
  776. _applyAttributes: function(){
  777. // summary:
  778. // Step during widget creation to copy widget attributes to the
  779. // DOM according to attributeMap and _setXXXAttr objects, and also to call
  780. // custom _setXXXAttr() methods.
  781. //
  782. // Skips over blank/false attribute values, unless they were explicitly specified
  783. // as parameters to the widget, since those are the default anyway,
  784. // and setting tabIndex="" is different than not setting tabIndex at all.
  785. //
  786. // For backwards-compatibility reasons attributeMap overrides _setXXXAttr when
  787. // _setXXXAttr is a hash/string/array, but _setXXXAttr as a functions override attributeMap.
  788. // tags:
  789. // private
  790. // Get list of attributes where this.set(name, value) will do something beyond
  791. // setting this[name] = value. Specifically, attributes that have:
  792. // - associated _setXXXAttr() method/hash/string/array
  793. // - entries in attributeMap.
  794. var ctor = this.constructor,
  795. list = ctor._setterAttrs;
  796. if(!list){
  797. list = (ctor._setterAttrs = []);
  798. for(var attr in this.attributeMap){
  799. list.push(attr);
  800. }
  801. var proto = ctor.prototype;
  802. for(var fxName in proto){
  803. if(fxName in this.attributeMap){ continue; }
  804. var setterName = "_set" + fxName.replace(/^[a-z]|-[a-zA-Z]/g, function(c){ return c.charAt(c.length-1).toUpperCase(); }) + "Attr";
  805. if(setterName in proto){
  806. list.push(fxName);
  807. }
  808. }
  809. }
  810. // Call this.set() for each attribute that was either specified as parameter to constructor,
  811. // or was found above and has a default non-null value. For correlated attributes like value and displayedValue, the one
  812. // specified as a parameter should take precedence, so apply attributes in this.params last.
  813. // Particularly important for new DateTextBox({displayedValue: ...}) since DateTextBox's default value is
  814. // NaN and thus is not ignored like a default value of "".
  815. array.forEach(list, function(attr){
  816. if(this.params && attr in this.params){
  817. // skip this one, do it below
  818. }else if(this[attr]){
  819. this.set(attr, this[attr]);
  820. }
  821. }, this);
  822. for(var param in this.params){
  823. this.set(param, this[param]);
  824. }
  825. },
  826. postMixInProperties: function(){
  827. // summary:
  828. // Called after the parameters to the widget have been read-in,
  829. // but before the widget template is instantiated. Especially
  830. // useful to set properties that are referenced in the widget
  831. // template.
  832. // tags:
  833. // protected
  834. },
  835. buildRendering: function(){
  836. // summary:
  837. // Construct the UI for this widget, setting this.domNode.
  838. // Most widgets will mixin `dijit._TemplatedMixin`, which implements this method.
  839. // tags:
  840. // protected
  841. if(!this.domNode){
  842. // Create root node if it wasn't created by _Templated
  843. this.domNode = this.srcNodeRef || domConstruct.create('div');
  844. }
  845. // baseClass is a single class name or occasionally a space-separated list of names.
  846. // Add those classes to the DOMNode. If RTL mode then also add with Rtl suffix.
  847. // TODO: make baseClass custom setter
  848. if(this.baseClass){
  849. var classes = this.baseClass.split(" ");
  850. if(!this.isLeftToRight()){
  851. classes = classes.concat( array.map(classes, function(name){ return name+"Rtl"; }));
  852. }
  853. domClass.add(this.domNode, classes);
  854. }
  855. },
  856. postCreate: function(){
  857. // summary:
  858. // Processing after the DOM fragment is created
  859. // description:
  860. // Called after the DOM fragment has been created, but not necessarily
  861. // added to the document. Do not include any operations which rely on
  862. // node dimensions or placement.
  863. // tags:
  864. // protected
  865. },
  866. startup: function(){
  867. // summary:
  868. // Processing after the DOM fragment is added to the document
  869. // description:
  870. // Called after a widget and its children have been created and added to the page,
  871. // and all related widgets have finished their create() cycle, up through postCreate().
  872. // This is useful for composite widgets that need to control or layout sub-widgets.
  873. // Many layout widgets can use this as a wiring phase.
  874. if(this._started){ return; }
  875. this._started = true;
  876. array.forEach(this.getChildren(), function(obj){
  877. if(!obj._started && !obj._destroyed && lang.isFunction(obj.startup)){
  878. obj.startup();
  879. obj._started = true;
  880. }
  881. });
  882. },
  883. //////////// DESTROY FUNCTIONS ////////////////////////////////
  884. destroyRecursive: function(/*Boolean?*/ preserveDom){
  885. // summary:
  886. // Destroy this widget and its descendants
  887. // description:
  888. // This is the generic "destructor" function that all widget users
  889. // should call to cleanly discard with a widget. Once a widget is
  890. // destroyed, it is removed from the manager object.
  891. // preserveDom:
  892. // If true, this method will leave the original DOM structure
  893. // alone of descendant Widgets. Note: This will NOT work with
  894. // dijit._Templated widgets.
  895. this._beingDestroyed = true;
  896. this.destroyDescendants(preserveDom);
  897. this.destroy(preserveDom);
  898. },
  899. destroy: function(/*Boolean*/ preserveDom){
  900. // summary:
  901. // Destroy this widget, but not its descendants.
  902. // This method will, however, destroy internal widgets such as those used within a template.
  903. // preserveDom: Boolean
  904. // If true, this method will leave the original DOM structure alone.
  905. // Note: This will not yet work with _Templated widgets
  906. this._beingDestroyed = true;
  907. this.uninitialize();
  908. // remove this.connect() and this.subscribe() listeners
  909. var c;
  910. while((c = this._connects.pop())){
  911. c.remove();
  912. }
  913. // destroy widgets created as part of template, etc.
  914. var w;
  915. while((w = this._supportingWidgets.pop())){
  916. if(w.destroyRecursive){
  917. w.destroyRecursive();
  918. }else if(w.destroy){
  919. w.destroy();
  920. }
  921. }
  922. this.destroyRendering(preserveDom);
  923. registry.remove(this.id);
  924. this._destroyed = true;
  925. },
  926. destroyRendering: function(/*Boolean?*/ preserveDom){
  927. // summary:
  928. // Destroys the DOM nodes associated with this widget
  929. // preserveDom:
  930. // If true, this method will leave the original DOM structure alone
  931. // during tear-down. Note: this will not work with _Templated
  932. // widgets yet.
  933. // tags:
  934. // protected
  935. if(this.bgIframe){
  936. this.bgIframe.destroy(preserveDom);
  937. delete this.bgIframe;
  938. }
  939. if(this.domNode){
  940. if(preserveDom){
  941. domAttr.remove(this.domNode, "widgetId");
  942. }else{
  943. domConstruct.destroy(this.domNode);
  944. }
  945. delete this.domNode;
  946. }
  947. if(this.srcNodeRef){
  948. if(!preserveDom){
  949. domConstruct.destroy(this.srcNodeRef);
  950. }
  951. delete this.srcNodeRef;
  952. }
  953. },
  954. destroyDescendants: function(/*Boolean?*/ preserveDom){
  955. // summary:
  956. // Recursively destroy the children of this widget and their
  957. // descendants.
  958. // preserveDom:
  959. // If true, the preserveDom attribute is passed to all descendant
  960. // widget's .destroy() method. Not for use with _Templated
  961. // widgets.
  962. // get all direct descendants and destroy them recursively
  963. array.forEach(this.getChildren(), function(widget){
  964. if(widget.destroyRecursive){
  965. widget.destroyRecursive(preserveDom);
  966. }
  967. });
  968. },
  969. uninitialize: function(){
  970. // summary:
  971. // Stub function. Override to implement custom widget tear-down
  972. // behavior.
  973. // tags:
  974. // protected
  975. return false;
  976. },
  977. ////////////////// GET/SET, CUSTOM SETTERS, ETC. ///////////////////
  978. _setStyleAttr: function(/*String||Object*/ value){
  979. // summary:
  980. // Sets the style attribute of the widget according to value,
  981. // which is either a hash like {height: "5px", width: "3px"}
  982. // or a plain string
  983. // description:
  984. // Determines which node to set the style on based on style setting
  985. // in attributeMap.
  986. // tags:
  987. // protected
  988. var mapNode = this.domNode;
  989. // Note: technically we should revert any style setting made in a previous call
  990. // to his method, but that's difficult to keep track of.
  991. if(lang.isObject(value)){
  992. domStyle.set(mapNode, value);
  993. }else{
  994. if(mapNode.style.cssText){
  995. mapNode.style.cssText += "; " + value;
  996. }else{
  997. mapNode.style.cssText = value;
  998. }
  999. }
  1000. this._set("style", value);
  1001. },
  1002. _attrToDom: function(/*String*/ attr, /*String*/ value, /*Object?*/ commands){
  1003. // summary:
  1004. // Reflect a widget attribute (title, tabIndex, duration etc.) to
  1005. // the widget DOM, as specified by commands parameter.
  1006. // If commands isn't specified then it's looked up from attributeMap.
  1007. // Note some attributes like "type"
  1008. // cannot be processed this way as they are not mutable.
  1009. //
  1010. // tags:
  1011. // private
  1012. commands = arguments.length >= 3 ? commands : this.attributeMap[attr];
  1013. array.forEach(lang.isArray(commands) ? commands : [commands], function(command){
  1014. // Get target node and what we are doing to that node
  1015. var mapNode = this[command.node || command || "domNode"]; // DOM node
  1016. var type = command.type || "attribute"; // class, innerHTML, innerText, or attribute
  1017. switch(type){
  1018. case "attribute":
  1019. if(lang.isFunction(value)){ // functions execute in the context of the widget
  1020. value = lang.hitch(this, value);
  1021. }
  1022. // Get the name of the DOM node attribute; usually it's the same
  1023. // as the name of the attribute in the widget (attr), but can be overridden.
  1024. // Also maps handler names to lowercase, like onSubmit --> onsubmit
  1025. var attrName = command.attribute ? command.attribute :
  1026. (/^on[A-Z][a-zA-Z]*$/.test(attr) ? attr.toLowerCase() : attr);
  1027. domAttr.set(mapNode, attrName, value);
  1028. break;
  1029. case "innerText":
  1030. mapNode.innerHTML = "";
  1031. mapNode.appendChild(win.doc.createTextNode(value));
  1032. break;
  1033. case "innerHTML":
  1034. mapNode.innerHTML = value;
  1035. break;
  1036. case "class":
  1037. domClass.replace(mapNode, value, this[attr]);
  1038. break;
  1039. }
  1040. }, this);
  1041. },
  1042. get: function(name){
  1043. // summary:
  1044. // Get a property from a widget.
  1045. // name:
  1046. // The property to get.
  1047. // description:
  1048. // Get a named property from a widget. The property may
  1049. // potentially be retrieved via a getter method. If no getter is defined, this
  1050. // just retrieves the object's property.
  1051. //
  1052. // For example, if the widget has properties `foo` and `bar`
  1053. // and a method named `_getFooAttr()`, calling:
  1054. // `myWidget.get("foo")` would be equivalent to calling
  1055. // `widget._getFooAttr()` and `myWidget.get("bar")`
  1056. // would be equivalent to the expression
  1057. // `widget.bar2`
  1058. var names = this._getAttrNames(name);
  1059. return this[names.g] ? this[names.g]() : this[name];
  1060. },
  1061. set: function(name, value){
  1062. // summary:
  1063. // Set a property on a widget
  1064. // name:
  1065. // The property to set.
  1066. // value:
  1067. // The value to set in the property.
  1068. // description:
  1069. // Sets named properties on a widget which may potentially be handled by a
  1070. // setter in the widget.
  1071. //
  1072. // For example, if the widget has properties `foo` and `bar`
  1073. // and a method named `_setFooAttr()`, calling
  1074. // `myWidget.set("foo", "Howdy!")` would be equivalent to calling
  1075. // `widget._setFooAttr("Howdy!")` and `myWidget.set("bar", 3)`
  1076. // would be equivalent to the statement `widget.bar = 3;`
  1077. //
  1078. // set() may also be called with a hash of name/value pairs, ex:
  1079. //
  1080. // | myWidget.set({
  1081. // | foo: "Howdy",
  1082. // | bar: 3
  1083. // | });
  1084. //
  1085. // This is equivalent to calling `set(foo, "Howdy")` and `set(bar, 3)`
  1086. if(typeof name === "object"){
  1087. for(var x in name){
  1088. this.set(x, name[x]);
  1089. }
  1090. return this;
  1091. }
  1092. var names = this._getAttrNames(name),
  1093. setter = this[names.s];
  1094. if(lang.isFunction(setter)){
  1095. // use the explicit setter
  1096. var result = setter.apply(this, Array.prototype.slice.call(arguments, 1));
  1097. }else{
  1098. // Mapping from widget attribute to DOMNode attribute/value/etc.
  1099. // Map according to:
  1100. // 1. attributeMap setting, if one exists (TODO: attributeMap deprecated, remove in 2.0)
  1101. // 2. _setFooAttr: {...} type attribute in the widget (if one exists)
  1102. // 3. apply to focusNode or domNode if standard attribute name, excluding funcs like onClick.
  1103. // Checks if an attribute is a "standard attribute" by whether the DOMNode JS object has a similar
  1104. // attribute name (ex: accept-charset attribute matches jsObject.acceptCharset).
  1105. // Note also that Tree.focusNode() is a function not a DOMNode, so test for that.
  1106. var defaultNode = this.focusNode && !lang.isFunction(this.focusNode) ? "focusNode" : "domNode",
  1107. tag = this[defaultNode].tagName,
  1108. attrsForTag = tagAttrs[tag] || (tagAttrs[tag] = getAttrs(this[defaultNode])),
  1109. map = name in this.attributeMap ? this.attributeMap[name] :
  1110. names.s in this ? this[names.s] :
  1111. ((names.l in attrsForTag && typeof value != "function") ||
  1112. /^aria-|^data-|^role$/.test(name)) ? defaultNode : null;
  1113. if(map != null){
  1114. this._attrToDom(name, value, map);
  1115. }
  1116. this._set(name, value);
  1117. }
  1118. return result || this;
  1119. },
  1120. _attrPairNames: {}, // shared between all widgets
  1121. _getAttrNames: function(name){
  1122. // summary:
  1123. // Helper function for get() and set().
  1124. // Caches attribute name values so we don't do the string ops every time.
  1125. // tags:
  1126. // private
  1127. var apn = this._attrPairNames;
  1128. if(apn[name]){ return apn[name]; }
  1129. var uc = name.replace(/^[a-z]|-[a-zA-Z]/g, function(c){ return c.charAt(c.length-1).toUpperCase(); });
  1130. return (apn[name] = {
  1131. n: name+"Node",
  1132. s: "_set"+uc+"Attr", // converts dashes to camel case, ex: accept-charset --> _setAcceptCharsetAttr
  1133. g: "_get"+uc+"Attr",
  1134. l: uc.toLowerCase() // lowercase name w/out dashes, ex: acceptcharset
  1135. });
  1136. },
  1137. _set: function(/*String*/ name, /*anything*/ value){
  1138. // summary:
  1139. // Helper function to set new value for specified attribute, and call handlers
  1140. // registered with watch() if the value has changed.
  1141. var oldValue = this[name];
  1142. this[name] = value;
  1143. if(this._watchCallbacks && this._created && !isEqual(value, oldValue)){
  1144. this._watchCallbacks(name, oldValue, value);
  1145. }
  1146. },
  1147. on: function(/*String*/ type, /*Function*/ func){
  1148. // summary:
  1149. // Call specified function when event occurs, ex: myWidget.on("click", function(){ ... }).
  1150. // description:
  1151. // Call specified function when event `type` occurs, ex: `myWidget.on("click", function(){ ... })`.
  1152. // Note that the function is not run in any particular scope, so if (for example) you want it to run in the
  1153. // widget's scope you must do `myWidget.on("click", lang.hitch(myWidget, func))`.
  1154. return aspect.after(this, this._onMap(type), func, true);
  1155. },
  1156. _onMap: function(/*String*/ type){
  1157. // summary:
  1158. // Maps on() type parameter (ex: "mousemove") to method name (ex: "onMouseMove")
  1159. var ctor = this.constructor, map = ctor._onMap;
  1160. if(!map){
  1161. map = (ctor._onMap = {});
  1162. for(var attr in ctor.prototype){
  1163. if(/^on/.test(attr)){
  1164. map[attr.replace(/^on/, "").toLowerCase()] = attr;
  1165. }
  1166. }
  1167. }
  1168. return map[type.toLowerCase()]; // String
  1169. },
  1170. toString: function(){
  1171. // summary:
  1172. // Returns a string that represents the widget
  1173. // description:
  1174. // When a widget is cast to a string, this method will be used to generate the
  1175. // output. Currently, it does not implement any sort of reversible
  1176. // serialization.
  1177. return '[Widget ' + this.declaredClass + ', ' + (this.id || 'NO ID') + ']'; // String
  1178. },
  1179. getChildren: function(){
  1180. // summary:
  1181. // Returns all the widgets contained by this, i.e., all widgets underneath this.containerNode.
  1182. // Does not return nested widgets, nor widgets that are part of this widget's template.
  1183. return this.containerNode ? registry.findWidgets(this.containerNode) : []; // dijit._Widget[]
  1184. },
  1185. getParent: function(){
  1186. // summary:
  1187. // Returns the parent widget of this widget
  1188. return registry.getEnclosingWidget(this.domNode.parentNode);
  1189. },
  1190. connect: function(
  1191. /*Object|null*/ obj,
  1192. /*String|Function*/ event,
  1193. /*String|Function*/ method){
  1194. // summary:
  1195. // Connects specified obj/event to specified method of this object
  1196. // and registers for disconnect() on widget destroy.
  1197. // description:
  1198. // Provide widget-specific analog to dojo.connect, except with the
  1199. // implicit use of this widget as the target object.
  1200. // Events connected with `this.connect` are disconnected upon
  1201. // destruction.
  1202. // returns:
  1203. // A handle that can be passed to `disconnect` in order to disconnect before
  1204. // the widget is destroyed.
  1205. // example:
  1206. // | var btn = new dijit.form.Button();
  1207. // | // when foo.bar() is called, call the listener we're going to
  1208. // | // provide in the scope of btn
  1209. // | btn.connect(foo, "bar", function(){
  1210. // | console.debug(this.toString());
  1211. // | });
  1212. // tags:
  1213. // protected
  1214. var handle = connect.connect(obj, event, this, method);
  1215. this._connects.push(handle);
  1216. return handle; // _Widget.Handle
  1217. },
  1218. disconnect: function(handle){
  1219. // summary:
  1220. // Disconnects handle created by `connect`.
  1221. // Also removes handle from this widget's list of connects.
  1222. // tags:
  1223. // protected
  1224. var i = array.indexOf(this._connects, handle);
  1225. if(i != -1){
  1226. handle.remove();
  1227. this._connects.splice(i, 1);
  1228. }
  1229. },
  1230. subscribe: function(t, method){
  1231. // summary:
  1232. // Subscribes to the specified topic and calls the specified method
  1233. // of this object and registers for unsubscribe() on widget destroy.
  1234. // description:
  1235. // Provide widget-specific analog to dojo.subscribe, except with the
  1236. // implicit use of this widget as the target object.
  1237. // t: String
  1238. // The topic
  1239. // method: Function
  1240. // The callback
  1241. // example:
  1242. // | var btn = new dijit.form.Button();
  1243. // | // when /my/topic is published, this button changes its label to
  1244. // | // be the parameter of the topic.
  1245. // | btn.subscribe("/my/topic", function(v){
  1246. // | this.set("label", v);
  1247. // | });
  1248. // tags:
  1249. // protected
  1250. var handle = topic.subscribe(t, lang.hitch(this, method));
  1251. this._connects.push(handle);
  1252. return handle; // _Widget.Handle
  1253. },
  1254. unsubscribe: function(/*Object*/ handle){
  1255. // summary:
  1256. // Unsubscribes handle created by this.subscribe.
  1257. // Also removes handle from this widget's list of subscriptions
  1258. // tags:
  1259. // protected
  1260. this.disconnect(handle);
  1261. },
  1262. isLeftToRight: function(){
  1263. // summary:
  1264. // Return this widget's explicit or implicit orientation (true for LTR, false for RTL)
  1265. // tags:
  1266. // protected
  1267. return this.dir ? (this.dir == "ltr") : domGeometry.isBodyLtr(); //Boolean
  1268. },
  1269. isFocusable: function(){
  1270. // summary:
  1271. // Return true if this widget can currently be focused
  1272. // and false if not
  1273. return this.focus && (domStyle.get(this.domNode, "display") != "none");
  1274. },
  1275. placeAt: function(/* String|DomNode|_Widget */reference, /* String?|Int? */position){
  1276. // summary:
  1277. // Place this widget's domNode reference somewhere in the DOM based
  1278. // on standard domConstruct.place conventions, or passing a Widget reference that
  1279. // contains and addChild member.
  1280. //
  1281. // description:
  1282. // A convenience function provided in all _Widgets, providing a simple
  1283. // shorthand mechanism to put an existing (or newly created) Widget
  1284. // somewhere in the dom, and allow chaining.
  1285. //
  1286. // reference:
  1287. // The String id of a domNode, a domNode reference, or a reference to a Widget possessing
  1288. // an addChild method.
  1289. //
  1290. // position:
  1291. // If passed a string or domNode reference, the position argument
  1292. // accepts a string just as domConstruct.place does, one of: "first", "last",
  1293. // "before", or "after".
  1294. //
  1295. // If passed a _Widget reference, and that widget reference has an ".addChild" method,
  1296. // it will be called passing this widget instance into that method, supplying the optional
  1297. // position index passed.
  1298. //
  1299. // returns:
  1300. // dijit._Widget
  1301. // Provides a useful return of the newly created dijit._Widget instance so you
  1302. // can "chain" this function by instantiating, placing, then saving the return value
  1303. // to a variable.
  1304. //
  1305. // example:
  1306. // | // create a Button with no srcNodeRef, and place it in the body:
  1307. // | var button = new dijit.form.Button({ label:"click" }).placeAt(win.body());
  1308. // | // now, 'button' is still the widget reference to the newly created button
  1309. // | button.on("click", function(e){ console.log('click'); }));
  1310. //
  1311. // example:
  1312. // | // create a button out of a node with id="src" and append it to id="wrapper":
  1313. // | var button = new dijit.form.Button({},"src").placeAt("wrapper");
  1314. //
  1315. // example:
  1316. // | // place a new button as the first element of some div
  1317. // | var button = new dijit.form.Button({ label:"click" }).placeAt("wrapper","first");
  1318. //
  1319. // example:
  1320. // | // create a contentpane and add it to a TabContainer
  1321. // | var tc = dijit.byId("myTabs");
  1322. // | new dijit.layout.ContentPane({ href:"foo.html", title:"Wow!" }).placeAt(tc)
  1323. if(reference.declaredClass && reference.addChild){
  1324. reference.addChild(this, position);
  1325. }else{
  1326. domConstruct.place(this.domNode, reference, position);
  1327. }
  1328. return this;
  1329. },
  1330. getTextDir: function(/*String*/ text,/*String*/ originalDir){
  1331. // summary:
  1332. // Return direction of the text.
  1333. // The function overridden in the _BidiSupport module,
  1334. // its main purpose is to calculate the direction of the
  1335. // text, if was defined by the programmer through textDir.
  1336. // tags:
  1337. // protected.
  1338. return originalDir;
  1339. },
  1340. applyTextDir: function(/*===== element, text =====*/){
  1341. // summary:
  1342. // The function overridden in the _BidiSupport module,
  1343. // originally used for setting element.dir according to this.textDir.
  1344. // In this case does nothing.
  1345. // element: DOMNode
  1346. // text: String
  1347. // tags:
  1348. // protected.
  1349. },
  1350. defer: function(fcn, delay){
  1351. // summary:
  1352. // Wrapper to setTimeout to avoid deferred functions executing
  1353. // after the originating widget has been destroyed.
  1354. // Returns an object handle with a remove method (that returns null) (replaces clearTimeout).
  1355. // fcn: function reference
  1356. // delay: Optional number (defaults to 0)
  1357. // tags:
  1358. // protected.
  1359. var timer = setTimeout(lang.hitch(this,
  1360. function(){
  1361. if(!timer){ return; }
  1362. timer = null;
  1363. if(!this._destroyed){
  1364. lang.hitch(this, fcn)();
  1365. }
  1366. }),
  1367. delay || 0
  1368. );
  1369. return {
  1370. remove: function(){
  1371. if(timer){
  1372. clearTimeout(timer);
  1373. timer = null;
  1374. }
  1375. return null; // so this works well: handle = handle.remove();
  1376. }
  1377. };
  1378. }
  1379. });
  1380. });
  1381. },
  1382. 'dojox/mobile/View':function(){
  1383. define("dojox/mobile/View", [
  1384. "dojo/_base/kernel", // to test dojo.hash
  1385. "dojo/_base/array",
  1386. "dojo/_base/config",
  1387. "dojo/_base/connect",
  1388. "dojo/_base/declare",
  1389. "dojo/_base/lang",
  1390. "dojo/_base/sniff",
  1391. "dojo/_base/window",
  1392. "dojo/_base/Deferred",
  1393. "dojo/dom",
  1394. "dojo/dom-class",
  1395. "dojo/dom-geometry",
  1396. "dojo/dom-style",
  1397. // "dojo/hash", // optionally prereq'ed
  1398. "dijit/registry", // registry.byNode
  1399. "dijit/_Contained",
  1400. "dijit/_Container",
  1401. "dijit/_WidgetBase",
  1402. "./ViewController", // to load ViewController for you (no direct references)
  1403. "./transition"
  1404. ], function(dojo, array, config, connect, declare, lang, has, win, Deferred, dom, domClass, domGeometry, domStyle, registry, Contained, Container, WidgetBase, ViewController, transitDeferred){
  1405. /*=====
  1406. var Contained = dijit._Contained;
  1407. var Container = dijit._Container;
  1408. var WidgetBase = dijit._WidgetBase;
  1409. var ViewController = dojox.mobile.ViewController;
  1410. =====*/
  1411. // module:
  1412. // dojox/mobile/View
  1413. // summary:
  1414. // A widget that represents a view that occupies the full screen
  1415. var dm = lang.getObject("dojox.mobile", true);
  1416. return declare("dojox.mobile.View", [WidgetBase, Container, Contained], {
  1417. // summary:
  1418. // A widget that represents a view that occupies the full screen
  1419. // description:
  1420. // View acts as a container for any HTML and/or widgets. An entire
  1421. // HTML page can have multiple View widgets and the user can
  1422. // navigate through the views back and forth without page
  1423. // transitions.
  1424. // selected: Boolean
  1425. // If true, the view is displayed at startup time.
  1426. selected: false,
  1427. // keepScrollPos: Boolean
  1428. // If true, the scroll position is kept between views.
  1429. keepScrollPos: true,
  1430. constructor: function(params, node){
  1431. if(node){
  1432. dom.byId(node).style.visibility = "hidden";
  1433. }
  1434. this._aw = has("android") >= 2.2 && has("android") < 3; // flag for android animation workaround
  1435. },
  1436. buildRendering: function(){
  1437. this.domNode = this.containerNode = this.srcNodeRef || win.doc.createElement("DIV");
  1438. this.domNode.className = "mblView";
  1439. this.connect(this.domNode, "webkitAnimationEnd", "onAnimationEnd");
  1440. this.connect(this.domNode, "webkitAnimationStart", "onAnimationStart");
  1441. if(!config['mblCSS3Transition']){
  1442. this.connect(this.domNode, "webkitTransitionEnd", "onAnimationEnd");
  1443. }
  1444. var id = location.href.match(/#(\w+)([^\w=]|$)/) ? RegExp.$1 : null;
  1445. this._visible = this.selected && !id || this.id == id;
  1446. if(this.selected){
  1447. dm._defaultView = this;
  1448. }
  1449. },
  1450. startup: function(){
  1451. if(this._started){ return; }
  1452. var siblings = [];
  1453. var children = this.domNode.parentNode.childNodes;
  1454. var visible = false;
  1455. // check if a visible view exists
  1456. for(var i = 0; i < children.length; i++){
  1457. var c = children[i];
  1458. if(c.nodeType === 1 && domClass.contains(c, "mblView")){
  1459. siblings.push(c);
  1460. visible = visible || registry.byNode(c)._visible;
  1461. }
  1462. }
  1463. var _visible = this._visible;
  1464. // if no visible view exists, make the first view visible
  1465. if(siblings.length === 1 || (!visible && siblings[0] === this.domNode)){
  1466. _visible = true;
  1467. }
  1468. var _this = this;
  1469. setTimeout(function(){ // necessary to render the view correctly
  1470. if(!_visible){
  1471. _this.domNode.style.display = "none";
  1472. }else{
  1473. dm.currentView = _this; //TODO:1.8 reconsider this. currentView may not have a currently showing view when views are nested.
  1474. _this.onStartView();
  1475. connect.publish("/dojox/mobile/startView", [_this]);
  1476. }
  1477. if(_this.domNode.style.visibility != "visible"){ // this check is to avoid screen flickers
  1478. _this.domNode.style.visibility = "visible";
  1479. }
  1480. var parent = _this.getParent && _this.getParent();
  1481. if(!parent || !parent.resize){ // top level widget
  1482. _this.resize();
  1483. }
  1484. }, has("ie") ? 100 : 0); // give IE a little time to complete drawing
  1485. this.inherited(arguments);
  1486. },
  1487. resize: function(){
  1488. // summary:
  1489. // Calls resize() of each child widget.
  1490. array.forEach(this.getChildren(), function(child){
  1491. if(child.resize){ child.resize(); }
  1492. });
  1493. },
  1494. onStartView: function(){
  1495. // summary:
  1496. // Stub function to connect to from your application.
  1497. // description:
  1498. // Called only when this view is shown at startup time.
  1499. },
  1500. onBeforeTransitionIn: function(moveTo, dir, transition, context, method){
  1501. // summary:
  1502. // Stub function to connect to from your application.
  1503. // description:
  1504. // Called before the arriving transition occurs.
  1505. },
  1506. onAfterTransitionIn: function(moveTo, dir, transition, context, method){
  1507. // summary:
  1508. // Stub function to connect to from your application.
  1509. // description:
  1510. // Called after the arriving transition occurs.
  1511. },
  1512. onBeforeTransitionOut: function(moveTo, dir, transition, context, method){
  1513. // summary:
  1514. // Stub function to connect to from your application.
  1515. // description:
  1516. // Called before the leaving transition occurs.
  1517. },
  1518. onAfterTransitionOut: function(moveTo, dir, transition, context, method){
  1519. // summary:
  1520. // Stub function to connect to from your application.
  1521. // description:
  1522. // Called after the leaving transition occurs.
  1523. },
  1524. _saveState: function(moveTo, dir, transition, context, method){
  1525. this._context = context;
  1526. this._method = method;
  1527. if(transition == "none"){
  1528. transition = null;
  1529. }
  1530. this._moveTo = moveTo;
  1531. this._dir = dir;
  1532. this._transition = transition;
  1533. this._arguments = lang._toArray(arguments);
  1534. this._args = [];
  1535. if(context || method){
  1536. for(var i = 5; i < arguments.length; i++){
  1537. this._args.push(arguments[i]);
  1538. }
  1539. }
  1540. },
  1541. _fixViewState: function(/*DomNode*/toNode){
  1542. // summary:
  1543. // Sanity check for view transition states.
  1544. // description:
  1545. // Sometimes uninitialization of Views fails after making view transition,
  1546. // and that results in failure of subsequent view transitions.
  1547. // This function does the uninitialization for all the sibling views.
  1548. var nodes = this.domNode.parentNode.childNodes;
  1549. for(var i = 0; i < nodes.length; i++){
  1550. var n = nodes[i];
  1551. if(n.nodeType === 1 && domClass.contains(n, "mblView")){
  1552. n.className = "mblView"; //TODO: Should remove classes one by one. This would clear user defined classes or even mblScrollableView.
  1553. }
  1554. }
  1555. toNode.className = "mblView"; // just in case toNode is a sibling of an ancestor.
  1556. },
  1557. convertToId: function(moveTo){
  1558. if(typeof(moveTo) == "string"){
  1559. // removes a leading hash mark (#) and params if exists
  1560. // ex. "#bar&myParam=0003" -> "bar"
  1561. moveTo.match(/^#?([^&?]+)/);
  1562. return RegExp.$1;
  1563. }
  1564. return moveTo;
  1565. },
  1566. performTransition: function(/*String*/moveTo, /*Number*/dir, /*String*/transition,
  1567. /*Object|null*/context, /*String|Function*/method /*optional args*/){
  1568. // summary:
  1569. // Function to perform the various types of view transitions, such as fade, slide, and flip.
  1570. // moveTo: String
  1571. // The id of the transition destination view which resides in
  1572. // the current page.
  1573. // If the value has a hash sign ('#') before the id
  1574. // (e.g. #view1) and the dojo.hash module is loaded by the user
  1575. // application, the view transition updates the hash in the
  1576. // browser URL so that the user can bookmark the destination
  1577. // view. In this case, the user can also use the browser's
  1578. // back/forward button to navigate through the views in the
  1579. // browser history.
  1580. // If null, transitions to a blank view.
  1581. // If '#', returns immediately without transition.
  1582. // dir: Number
  1583. // The transition direction. If 1, transition forward. If -1, transition backward.
  1584. // For example, the slide transition slides the view from right to left when dir == 1,
  1585. // and from left to right when dir == -1.
  1586. // transition: String
  1587. // A type of animated transition effect. You can choose from
  1588. // the standard transition types, "slide", "fade", "flip", or
  1589. // from the extended transition types, "cover", "coverv",
  1590. // "dissolve", "reveal", "revealv", "scaleIn",
  1591. // "scaleOut", "slidev", "swirl", "zoomIn", "zoomOut". If
  1592. // "none" is specified, transition occurs immediately without
  1593. // animation.
  1594. // context: Object
  1595. // The object that the callback function will receive as "this".
  1596. // method: String|Function
  1597. // A callback function that is called when the transition has been finished.
  1598. // A function reference, or name of a function in context.
  1599. // tags:
  1600. // public
  1601. //
  1602. // example:
  1603. // Transition backward to a view whose id is "foo" with the slide animation.
  1604. // | performTransition("foo", -1, "slide");
  1605. //
  1606. // example:
  1607. // Transition forward to a blank view, and then open another page.
  1608. // | performTransition(null, 1, "slide", null, function(){location.href = href;});
  1609. if(moveTo === "#"){ return; }
  1610. if(dojo.hash){
  1611. if(typeof(moveTo) == "string" && moveTo.charAt(0) == '#' && !dm._params){
  1612. dm._params = [];
  1613. for(var i = 0; i < arguments.length; i++){
  1614. dm._params.push(arguments[i]);
  1615. }
  1616. dojo.hash(moveTo);
  1617. return;
  1618. }
  1619. }
  1620. this._saveState.apply(this, arguments);
  1621. var toNode;
  1622. if(moveTo){
  1623. toNode = this.convertToId(moveTo);
  1624. }else{
  1625. if(!this._dummyNode){
  1626. this._dummyNode = win.doc.createElement("DIV");
  1627. win.body().appendChild(this._dummyNode);
  1628. }
  1629. toNode = this._dummyNode;
  1630. }
  1631. var fromNode = this.domNode;
  1632. var fromTop = fromNode.offsetTop;
  1633. toNode = this.toNode = dom.byId(toNode);
  1634. if(!toNode){ console.log("dojox.mobile.View#performTransition: destination view not found: "+moveTo); return; }
  1635. toNode.style.visibility = this._aw ? "visible" : "hidden";
  1636. toNode.style.display = "";
  1637. this._fixViewState(toNode);
  1638. var toWidget = registry.byNode(toNode);
  1639. if(toWidget){
  1640. // Now that the target view became visible, it's time to run resize()
  1641. if(config["mblAlwaysResizeOnTransition"] || !toWidget._resized){
  1642. dm.resizeAll(null, toWidget);
  1643. toWidget._resized = true;
  1644. }
  1645. if(transition && transition != "none"){
  1646. // Temporarily add padding to align with the fromNode while transition
  1647. toWidget.containerNode.style.paddingTop = fromTop + "px";
  1648. }
  1649. toWidget.movedFrom = fromNode.id;
  1650. }
  1651. this.onBeforeTransitionOut.apply(this, arguments);
  1652. connect.publish("/dojox/mobile/beforeTransitionOut", [this].concat(lang._toArray(arguments)));
  1653. if(toWidget){
  1654. // perform view transition keeping the scroll position
  1655. if(this.keepScrollPos && !this.getParent()){
  1656. var scrollTop = win.body().scrollTop || win.doc.documentElement.scrollTop || win.global.pageYOffset || 0;
  1657. fromNode._scrollTop = scrollTop;
  1658. var toTop = (dir == 1) ? 0 : (toNode._scrollTop || 0);
  1659. toNode.style.top = "0px";
  1660. if(scrollTop > 1 || toTop !== 0){
  1661. fromNode.style.top = toTop - scrollTop + "px";
  1662. if(config["mblHideAddressBar"] !== false){
  1663. setTimeout(function(){ // iPhone needs setTimeout
  1664. win.global.scrollTo(0, (toTop || 1));
  1665. }, 0);
  1666. }
  1667. }
  1668. }else{
  1669. toNode.style.top = "0px";
  1670. }
  1671. toWidget.onBeforeTransitionIn.apply(toWidget, arguments);
  1672. connect.publish("/dojox/mobile/beforeTransitionIn", [toWidget].concat(lang._toArray(arguments)));
  1673. }
  1674. if(!this._aw){
  1675. toNode.style.display = "none";
  1676. toNode.style.visibility = "visible";
  1677. }
  1678. if(dm._iw && dm.scrollable){ // Workaround for iPhone flicker issue (only when scrollable.js is loaded)
  1679. var ss = dm.getScreenSize();
  1680. // Show cover behind the view.
  1681. // cover's z-index is set to -10000, lower than z-index value specified in transition css.
  1682. win.body().appendChild(dm._iwBgCover);
  1683. domStyle.set(dm._iwBgCover, {
  1684. position: "absolute",
  1685. top: "0px",
  1686. left: "0px",
  1687. height: (ss.h + 1) + "px", // "+1" means the height of scrollTo(0,1)
  1688. width: ss.w + "px",
  1689. backgroundColor: domStyle.get(win.body(), "background-color"),
  1690. zIndex: -10000,
  1691. display: ""
  1692. });
  1693. // Show toNode behind the cover.
  1694. domStyle.set(toNode, {
  1695. position: "absolute",
  1696. zIndex: -10001,
  1697. visibility: "visible",
  1698. display: ""
  1699. });
  1700. // setTimeout seems to be necessary to avoid flicker.
  1701. // Also the duration of setTimeout should be long enough to avoid flicker.
  1702. // 0 is not effective. 50 sometimes causes flicker.
  1703. setTimeout(lang.hitch(this, function(){
  1704. this._doTransition(fromNode, toNode, transition, dir);
  1705. }), 80);
  1706. }else{
  1707. this._doTransition(fromNode, toNode, transition, dir);
  1708. }
  1709. },
  1710. _toCls: function(s){
  1711. // convert from transition name to corresponding class name
  1712. // ex. "slide" -> "mblSlide"
  1713. return "mbl"+s.charAt(0).toUpperCase() + s.substring(1);
  1714. },
  1715. _doTransition: function(fromNode, toNode, transition, dir){
  1716. var rev = (dir == -1) ? " mblReverse" : "";
  1717. if(dm._iw && dm.scrollable){ // Workaround for iPhone flicker issue (only when scrollable.js is loaded)
  1718. // Show toNode after flicker ends
  1719. domStyle.set(toNode, {
  1720. position: "",
  1721. zIndex: ""
  1722. });
  1723. // Remove cover
  1724. win.body().removeChild(dm._iwBgCover);
  1725. }else if(!this._aw){
  1726. toNode.style.display = "";
  1727. }
  1728. if(!transition || transition == "none"){
  1729. this.domNode.style.display = "none";
  1730. this.invokeCallback();
  1731. }else if(config['mblCSS3Transition']){
  1732. //get dojox/css3/transit first
  1733. Deferred.when(transitDeferred, lang.hitch(this, function(transit){
  1734. //follow the style of .mblView.mblIn in View.css
  1735. //need to set the toNode to absolute position
  1736. var toPosition = domStyle.get(toNode, "position");
  1737. domStyle.set(toNode, "position", "absolute");
  1738. Deferred.when(transit(fromNode, toNode, {transition: transition, reverse: (dir===-1)?true:false}),lang.hitch(this,function(){
  1739. domStyle.set(toNode, "position", toPosition);
  1740. this.invokeCallback();
  1741. }));
  1742. }));
  1743. }else{
  1744. var s = this._toCls(transition);
  1745. domClass.add(fromNode, s + " mblOut" + rev);
  1746. domClass.add(toNode, s + " mblIn" + rev);
  1747. setTimeout(function(){
  1748. domClass.add(fromNode, "mblTransition");
  1749. domClass.add(toNode, "mblTransition");
  1750. }, 100);
  1751. // set transform origin
  1752. var fromOrigin = "50% 50%";
  1753. var toOrigin = "50% 50%";
  1754. var scrollTop, posX, posY;
  1755. if(transition.indexOf("swirl") != -1 || transition.indexOf("zoom") != -1){
  1756. if(this.keepScrollPos && !this.getParent()){
  1757. scrollTop = win.body().scrollTop || win.doc.documentElement.scrollTop || win.global.pageYOffset || 0;
  1758. }else{
  1759. scrollTop = -domGeometry.position(fromNode, true).y;
  1760. }
  1761. posY = win.global.innerHeight / 2 + scrollTop;
  1762. fromOrigin = "50% " + posY + "px";
  1763. toOrigin = "50% " + posY + "px";
  1764. }else if(transition.indexOf("scale") != -1){
  1765. var viewPos = domGeometry.position(fromNode, true);
  1766. posX = ((this.clickedPosX !== undefined) ? this.clickedPosX : win.global.innerWidth / 2) - viewPos.x;
  1767. if(this.keepScrollPos && !this.getParent()){
  1768. scrollTop = win.body().scrollTop || win.doc.documentElement.scrollTop || win.global.pageYOffset || 0;
  1769. }else{
  1770. scrollTop = -viewPos.y;
  1771. }
  1772. posY = ((this.clickedPosY !== undefined) ? this.clickedPosY : win.global.innerHeight / 2) + scrollTop;
  1773. fromOrigin = posX + "px " + posY + "px";
  1774. toOrigin = posX + "px " + posY + "px";
  1775. }
  1776. domStyle.set(fromNode, {webkitTransformOrigin:fromOrigin});
  1777. domStyle.set(toNode, {webkitTransformOrigin:toOrigin});
  1778. }
  1779. dm.currentView = registry.byNode(toNode);
  1780. },
  1781. onAnimationStart: function(e){
  1782. },
  1783. onAnimationEnd: function(e){
  1784. var name = e.animationName || e.target.className;
  1785. if(name.indexOf("Out") === -1 &&
  1786. name.indexOf("In") === -1 &&
  1787. name.indexOf("Shrink") === -1){ return; }
  1788. var isOut = false;
  1789. if(domClass.contains(this.domNode, "mblOut")){
  1790. isOut = true;
  1791. this.domNode.style.display = "none";
  1792. domClass.remove(this.domNode, [this._toCls(this._transition), "mblIn", "mblOut", "mblReverse"]);
  1793. }else{
  1794. // Reset the temporary padding
  1795. this.containerNode.style.paddingTop = "";
  1796. }
  1797. domStyle.set(this.domNode, {webkitTransformOrigin:""});
  1798. if(name.indexOf("Shrink") !== -1){
  1799. var li = e.target;
  1800. li.style.display = "none";
  1801. domClass.remove(li, "mblCloseContent");
  1802. }
  1803. if(isOut){
  1804. this.invokeCallback();
  1805. }
  1806. // this.domNode may be destroyed as a result of invoking the callback,
  1807. // so check for that before accessing it.
  1808. this.domNode && (this.domNode.className = "mblView");
  1809. // clear the clicked position
  1810. this.clickedPosX = this.clickedPosY = undefined;
  1811. },
  1812. invokeCallback: function(){
  1813. this.onAfterTransitionOut.apply(this, this._arguments);
  1814. connect.publish("/dojox/mobile/afterTransitionOut", [this].concat(this._arguments));
  1815. var toWidget = registry.byNode(this.toNode);
  1816. if(toWidget){
  1817. toWidget.onAfterTransitionIn.apply(toWidget, this._arguments);
  1818. connect.publish("/dojox/mobile/afterTransitionIn", [toWidget].concat(this._arguments));
  1819. toWidget.movedFrom = undefined;
  1820. }
  1821. var c = this._context, m = this._method;
  1822. if(!c && !m){ return; }
  1823. if(!m){
  1824. m = c;
  1825. c = null;
  1826. }
  1827. c = c || win.global;
  1828. if(typeof(m) == "string"){
  1829. c[m].apply(c, this._args);
  1830. }else{
  1831. m.apply(c, this._args);
  1832. }
  1833. },
  1834. getShowingView: function(){
  1835. // summary:
  1836. // Find the currently showing view from my sibling views.
  1837. // description:
  1838. // Note that dojox.mobile.currentView is the last shown view.
  1839. // If the page consists of a splitter, there are multiple showing views.
  1840. var nodes = this.domNode.parentNode.childNodes;
  1841. for(var i = 0; i < nodes.length; i++){
  1842. var n = nodes[i];
  1843. if(n.nodeType === 1 && domClass.contains(n, "mblView") && domStyle.get(n, "display") !== "none"){
  1844. return registry.byNode(n);
  1845. }
  1846. }
  1847. return null;
  1848. },
  1849. show: function(){
  1850. // summary:
  1851. // Shows this view without a transition animation.
  1852. var view = this.getShowingView();
  1853. if(view){
  1854. view.domNode.style.display = "none"; // from-style
  1855. }
  1856. this.domNode.style.display = ""; // to-style
  1857. dm.currentView = this;
  1858. }
  1859. });
  1860. });
  1861. },
  1862. 'dojox/main':function(){
  1863. define("dojox/main", ["dojo/_base/kernel"], function(dojo) {
  1864. // module:
  1865. // dojox/main
  1866. // summary:
  1867. // The dojox package main module; dojox package is somewhat unusual in that the main module currently just provides an empty object.
  1868. return dojo.dojox;
  1869. });
  1870. },
  1871. 'dojox/mobile/transition':function(){
  1872. define("dojox/mobile/transition", [
  1873. "dojo/_base/Deferred",
  1874. "dojo/_base/config"
  1875. ], function(Deferred, config){
  1876. /* summary: this is the wrapper module which load
  1877. * dojox/css3/transit conditionally. If mblCSS3Transition
  1878. * is set to 'dojox/css3/transit', it will be loaded as
  1879. * the module to conduct the view transition.
  1880. */
  1881. if(config['mblCSS3Transition']){
  1882. //require dojox/css3/transit and resolve it as the result of transitDeferred.
  1883. var transitDeferred = new Deferred();
  1884. require([config['mblCSS3Transition']], function(transit){
  1885. transitDeferred.resolve(transit);
  1886. });
  1887. return transitDeferred;
  1888. }
  1889. return null;
  1890. });
  1891. },
  1892. 'dojo/Stateful':function(){
  1893. define(["./_base/declare", "./_base/lang", "./_base/array"], function(declare, lang, array) {
  1894. // module:
  1895. // dojo/Stateful
  1896. // summary:
  1897. // TODOC
  1898. return declare("dojo.Stateful", null, {
  1899. // summary:
  1900. // Base class for objects that provide named properties with optional getter/setter
  1901. // control and the ability to watch for property changes
  1902. // example:
  1903. // | var obj = new dojo.Stateful();
  1904. // | obj.watch("foo", function(){
  1905. // | console.log("foo changed to " + this.get("foo"));
  1906. // | });
  1907. // | obj.set("foo","bar");
  1908. postscript: function(mixin){
  1909. if(mixin){
  1910. lang.mixin(this, mixin);
  1911. }
  1912. },
  1913. get: function(/*String*/name){
  1914. // summary:
  1915. // Get a property on a Stateful instance.
  1916. // name:
  1917. // The property to get.
  1918. // returns:
  1919. // The property value on this Stateful instance.
  1920. // description:
  1921. // Get a named property on a Stateful object. The property may
  1922. // potentially be retrieved via a getter method in subclasses. In the base class
  1923. // this just retrieves the object's property.
  1924. // For example:
  1925. // | stateful = new dojo.Stateful({foo: 3});
  1926. // | stateful.get("foo") // returns 3
  1927. // | stateful.foo // returns 3
  1928. return this[name]; //Any
  1929. },
  1930. set: function(/*String*/name, /*Object*/value){
  1931. // summary:
  1932. // Set a property on a Stateful instance
  1933. // name:
  1934. // The property to set.
  1935. // value:
  1936. // The value to set in the property.
  1937. // returns:
  1938. // The function returns this dojo.Stateful instance.
  1939. // description:
  1940. // Sets named properties on a stateful object and notifies any watchers of
  1941. // the property. A programmatic setter may be defined in subclasses.
  1942. // For example:
  1943. // | stateful = new dojo.Stateful();
  1944. // | stateful.watch(function(name, oldValue, value){
  1945. // | // this will be called on the set below
  1946. // | }
  1947. // | stateful.set(foo, 5);
  1948. //
  1949. // set() may also be called with a hash of name/value pairs, ex:
  1950. // | myObj.set({
  1951. // | foo: "Howdy",
  1952. // | bar: 3
  1953. // | })
  1954. // This is equivalent to calling set(foo, "Howdy") and set(bar, 3)
  1955. if(typeof name === "object"){
  1956. for(var x in name){
  1957. if(name.hasOwnProperty(x) && x !="_watchCallbacks"){
  1958. this.set(x, name[x]);
  1959. }
  1960. }
  1961. return this;
  1962. }
  1963. var oldValue = this[name];
  1964. this[name] = value;
  1965. if(this._watchCallbacks){
  1966. this._watchCallbacks(name, oldValue, value);
  1967. }
  1968. return this; //dojo.Stateful
  1969. },
  1970. watch: function(/*String?*/name, /*Function*/callback){
  1971. // summary:
  1972. // Watches a property for changes
  1973. // name:
  1974. // Indicates the property to watch. This is optional (the callback may be the
  1975. // only parameter), and if omitted, all the properties will be watched
  1976. // returns:
  1977. // An object handle for the watch. The unwatch method of this object
  1978. // can be used to discontinue watching this property:
  1979. // | var watchHandle = obj.watch("foo", callback);
  1980. // | watchHandle.unwatch(); // callback won't be called now
  1981. // callback:
  1982. // The function to execute when the property changes. This will be called after
  1983. // the property has been changed. The callback will be called with the |this|
  1984. // set to the instance, the first argument as the name of the property, the
  1985. // second argument as the old value and the third argument as the new value.
  1986. var callbacks = this._watchCallbacks;
  1987. if(!callbacks){
  1988. var self = this;
  1989. callbacks = this._watchCallbacks = function(name, oldValue, value, ignoreCatchall){
  1990. var notify = function(propertyCallbacks){
  1991. if(propertyCallbacks){
  1992. propertyCallbacks = propertyCallbacks.slice();
  1993. for(var i = 0, l = propertyCallbacks.length; i < l; i++){
  1994. propertyCallbacks[i].call(self, name, oldValue, value);
  1995. }
  1996. }
  1997. };
  1998. notify(callbacks['_' + name]);
  1999. if(!ignoreCatchall){
  2000. notify(callbacks["*"]); // the catch-all
  2001. }
  2002. }; // we use a function instead of an object so it will be ignored by JSON conversion
  2003. }
  2004. if(!callback && typeof name === "function"){
  2005. callback = name;
  2006. name = "*";
  2007. }else{
  2008. // prepend with dash to prevent name conflicts with function (like "name" property)
  2009. name = '_' + name;
  2010. }
  2011. var propertyCallbacks = callbacks[name];
  2012. if(typeof propertyCallbacks !== "object"){
  2013. propertyCallbacks = callbacks[name] = [];
  2014. }
  2015. propertyCallbacks.push(callback);
  2016. return {
  2017. unwatch: function(){
  2018. propertyCallbacks.splice(array.indexOf(propertyCallbacks, callback), 1);
  2019. }
  2020. }; //Object
  2021. }
  2022. });
  2023. });
  2024. },
  2025. 'dojox/mobile/Heading':function(){
  2026. define("dojox/mobile/Heading", [
  2027. "dojo/_base/array",
  2028. "dojo/_base/connect",
  2029. "dojo/_base/declare",
  2030. "dojo/_base/lang",
  2031. "dojo/_base/window",
  2032. "dojo/dom-class",
  2033. "dojo/dom-construct",
  2034. "dojo/dom-style",
  2035. "dijit/registry", // registry.byId
  2036. "dijit/_Contained",
  2037. "dijit/_Container",
  2038. "dijit/_WidgetBase",
  2039. "./View"
  2040. ], function(array, connect, declare, lang, win, domClass, domConstruct, domStyle, registry, Contained, Container, WidgetBase, View){
  2041. var dm = lang.getObject("dojox.mobile", true);
  2042. /*=====
  2043. var Contained = dijit._Contained;
  2044. var Container = dijit._Container;
  2045. var WidgetBase = dijit._WidgetBase;
  2046. =====*/
  2047. // module:
  2048. // dojox/mobile/Heading
  2049. // summary:
  2050. // A widget that represents a navigation bar.
  2051. return declare("dojox.mobile.Heading", [WidgetBase, Container, Contained],{
  2052. // summary:
  2053. // A widget that represents a navigation bar.
  2054. // description:
  2055. // Heading is a widget that represents a navigation bar, which
  2056. // usually appears at the top of an application. It usually
  2057. // displays the title of the current view and can contain a
  2058. // navigational control. If you use it with
  2059. // dojox.mobile.ScrollableView, it can also be used as a fixed
  2060. // header bar or a fixed footer bar. In such cases, specify the
  2061. // fixed="top" attribute to be a fixed header bar or the
  2062. // fixed="bottom" attribute to be a fixed footer bar. Heading can
  2063. // have one or more ToolBarButton widgets as its children.
  2064. // back: String
  2065. // A label for the navigational control to return to the previous
  2066. // View.
  2067. back: "",
  2068. // href: String
  2069. // A URL to open when the navigational control is pressed.
  2070. href: "",
  2071. // moveTo: String
  2072. // The id of the transition destination view which resides in the
  2073. // current page.
  2074. //
  2075. // If the value has a hash sign ('#') before the id (e.g. #view1)
  2076. // and the dojo.hash module is loaded by the user application, the
  2077. // view transition updates the hash in the browser URL so that the
  2078. // user can bookmark the destination view. In this case, the user
  2079. // can also use the browser's back/forward button to navigate
  2080. // through the views in the browser history.
  2081. //
  2082. // If null, transitions to a blank view.
  2083. // If '#', returns immediately without transition.
  2084. moveTo: "",
  2085. // transition: String
  2086. // A type of animated transition effect. You can choose from the
  2087. // standard transition types, "slide", "fade", "flip", or from the
  2088. // extended transition types, "cover", "coverv", "dissolve",
  2089. // "reveal", "revealv", "scaleIn", "scaleOut", "slidev",
  2090. // "swirl", "zoomIn", "zoomOut". If "none" is specified, transition
  2091. // occurs immediately without animation.
  2092. transition: "slide",
  2093. // label: String
  2094. // A title text of the heading. If the label is not specified, the
  2095. // innerHTML of the node is used as a label.
  2096. label: "",
  2097. // iconBase: String
  2098. // The default icon path for child items.
  2099. iconBase: "",
  2100. // backProp: Object
  2101. // Properties for the back button.
  2102. backProp: {className: "mblArrowButton"},
  2103. // tag: String
  2104. // A name of html tag to create as domNode.
  2105. tag: "H1",
  2106. buildRendering: function(){
  2107. this.domNode = this.containerNode = this.srcNodeRef || win.doc.createElement(this.tag);
  2108. this.domNode.className = "mblHeading";
  2109. if(!this.label){
  2110. array.forEach(this.domNode.childNodes, function(n){
  2111. if(n.nodeType == 3){
  2112. var v = lang.trim(n.nodeValue);
  2113. if(v){
  2114. this.label = v;
  2115. this.labelNode = domConstruct.create("SPAN", {innerHTML:v}, n, "replace");
  2116. }
  2117. }
  2118. }, this);
  2119. }
  2120. if(!this.labelNode){
  2121. this.labelNode = domConstruct.create("SPAN", null, this.domNode);
  2122. }
  2123. this.labelNode.className = "mblHeadingSpanTitle";
  2124. this.labelDivNode = domConstruct.create("DIV", {
  2125. className: "mblHeadingDivTitle",
  2126. innerHTML: this.labelNode.innerHTML
  2127. }, this.domNode);
  2128. },
  2129. startup: function(){
  2130. if(this._started){ return; }
  2131. var parent = this.getParent && this.getParent();
  2132. if(!parent || !parent.resize){ // top level widget
  2133. var _this = this;
  2134. setTimeout(function(){ // necessary to render correctly
  2135. _this.resize();
  2136. }, 0);
  2137. }
  2138. this.inherited(arguments);
  2139. },
  2140. resize: function(){
  2141. if(this._btn){
  2142. this._btn.style.width = this._body.offsetWidth + this._head.offsetWidth + "px";
  2143. }
  2144. if(this.labelNode){
  2145. // find the rightmost left button (B), and leftmost right button (C)
  2146. // +-----------------------------+
  2147. // | |A| |B| |C| |D| |
  2148. // +-----------------------------+
  2149. var leftBtn, rightBtn;
  2150. var children = this.containerNode.childNodes;
  2151. for(var i = children.length - 1; i >= 0; i--){
  2152. var c = children[i];
  2153. if(c.nodeType === 1){
  2154. if(!rightBtn && domClass.contains(c, "mblToolBarButton") && domStyle.get(c, "float") === "right"){
  2155. rightBtn = c;
  2156. }
  2157. if(!leftBtn && (domClass.contains(c, "mblToolBarButton") && domStyle.get(c, "float") === "left" || c === this._btn)){
  2158. leftBtn = c;
  2159. }
  2160. }
  2161. }
  2162. if(!this.labelNodeLen && this.label){
  2163. this.labelNode.style.display = "inline";
  2164. this.labelNodeLen = this.labelNode.offsetWidth;
  2165. this.labelNode.style.display = "";
  2166. }
  2167. var bw = this.domNode.offsetWidth; // bar width
  2168. var rw = rightBtn ? bw - rightBtn.offsetLeft + 5 : 0; // rightBtn width
  2169. var lw = leftBtn ? leftBtn.offsetLeft + leftBtn.offsetWidth + 5 : 0; // leftBtn width
  2170. var tw = this.labelNodeLen || 0; // title width
  2171. domClass[bw - Math.max(rw,lw)*2 > tw ? "add" : "remove"](this.domNode, "mblHeadingCenterTitle");
  2172. }
  2173. array.forEach(this.getChildren(), function(child){
  2174. if(child.resize){ child.resize(); }
  2175. });
  2176. },
  2177. _setBackAttr: function(/*String*/back){
  2178. if (!back){
  2179. domConstruct.destroy(this._btn);
  2180. this._btn = null;
  2181. this.back = "";
  2182. }else{
  2183. if(!this._btn){
  2184. var btn = domConstruct.create("DIV", this.backProp, this.domNode, "first");
  2185. var head = domConstruct.create("DIV", {className:"mblArrowButtonHead"}, btn);
  2186. var body = domConstruct.create("DIV", {className:"mblArrowButtonBody mblArrowButtonText"}, btn);
  2187. this._body = body;
  2188. this._head = head;
  2189. this._btn = btn;
  2190. this.backBtnNode = btn;
  2191. this.connect(body, "onclick", "onClick");
  2192. }
  2193. this.back = back;
  2194. this._body.innerHTML = this._cv ? this._cv(this.back) : this.back;
  2195. }
  2196. this.resize();
  2197. },
  2198. _setLabelAttr: function(/*String*/label){
  2199. this.label = label;
  2200. this.labelNode.innerHTML = this.labelDivNode.innerHTML = this._cv ? this._cv(label) : label;
  2201. },
  2202. findCurrentView: function(){
  2203. // summary:
  2204. // Search for the view widget that contains this widget.
  2205. var w = this;
  2206. while(true){
  2207. w = w.getParent();
  2208. if(!w){ return null; }
  2209. if(w instanceof View){ break; }
  2210. }
  2211. return w;
  2212. },
  2213. onClick: function(e){
  2214. var h1 = this.domNode;
  2215. domClass.add(h1, "mblArrowButtonSelected");
  2216. setTimeout(function(){
  2217. domClass.remove(h1, "mblArrowButtonSelected");
  2218. }, 1000);
  2219. if(this.back && !this.moveTo && !this.href && history){
  2220. history.back();
  2221. return;
  2222. }
  2223. // keep the clicked position for transition animations
  2224. var view = this.findCurrentView();
  2225. if(view){
  2226. view.clickedPosX = e.clientX;
  2227. view.clickedPosY = e.clientY;
  2228. }
  2229. this.goTo(this.moveTo, this.href);
  2230. },
  2231. goTo: function(moveTo, href){
  2232. // summary:
  2233. // Given the destination, makes a view transition.
  2234. var view = this.findCurrentView();
  2235. if(!view){ return; }
  2236. if(href){
  2237. view.performTransition(null, -1, this.transition, this, function(){location.href = href;});
  2238. }else{
  2239. if(dm.app && dm.app.STAGE_CONTROLLER_ACTIVE){
  2240. // If in a full mobile app, then use its mechanisms to move back a scene
  2241. connect.publish("/dojox/mobile/app/goback");
  2242. }else{
  2243. // Basically transition should be performed between two
  2244. // siblings that share the same parent.
  2245. // However, when views are nested and transition occurs from
  2246. // an inner view, search for an ancestor view that is a sibling
  2247. // of the target view, and use it as a source view.
  2248. var node = registry.byId(view.convertToId(moveTo));
  2249. if(node){
  2250. var parent = node.getParent();
  2251. while(view){
  2252. var myParent = view.getParent();
  2253. if(parent === myParent){
  2254. break;
  2255. }
  2256. view = myParent;
  2257. }
  2258. }
  2259. if(view){
  2260. view.performTransition(moveTo, -1, this.transition);
  2261. }
  2262. }
  2263. }
  2264. }
  2265. });
  2266. });
  2267. },
  2268. 'dojox/mobile/Switch':function(){
  2269. define("dojox/mobile/Switch", [
  2270. "dojo/_base/array",
  2271. "dojo/_base/connect",
  2272. "dojo/_base/declare",
  2273. "dojo/_base/event",
  2274. "dojo/_base/window",
  2275. "dojo/dom-class",
  2276. "dijit/_Contained",
  2277. "dijit/_WidgetBase",
  2278. "./sniff"
  2279. ], function(array, connect, declare, event, win, domClass, Contained, WidgetBase, has){
  2280. /*=====
  2281. Contained = dijit._Contained;
  2282. WidgetBase = dijit._WidgetBase;
  2283. =====*/
  2284. // module:
  2285. // dojox/mobile/Switch
  2286. // summary:
  2287. // A toggle switch with a sliding knob.
  2288. return declare("dojox.mobile.Switch", [WidgetBase, Contained],{
  2289. // summary:
  2290. // A toggle switch with a sliding knob.
  2291. // description:
  2292. // Switch is a toggle switch with a sliding knob. You can either
  2293. // tap or slide the knob to toggle the switch. The onStateChanged
  2294. // handler is called when the switch is manipulated.
  2295. // value: String
  2296. // The initial state of the switch. "on" or "off". The default
  2297. // value is "on".
  2298. value: "on",
  2299. // name: String
  2300. // A name for a hidden input field, which holds the current value.
  2301. name: "",
  2302. // leftLabel: String
  2303. // The left-side label of the switch.
  2304. leftLabel: "ON",
  2305. // rightLabel: String
  2306. // The right-side label of the switch.
  2307. rightLabel: "OFF",
  2308. /* internal properties */
  2309. _width: 53,
  2310. buildRendering: function(){
  2311. this.domNode = win.doc.createElement("DIV");
  2312. var c = (this.srcNodeRef && this.srcNodeRef.className) || this.className || this["class"];
  2313. this._swClass = (c || "").replace(/ .*/,"");
  2314. this.domNode.className = "mblSwitch";
  2315. var nameAttr = this.name ? " name=\"" + this.name + "\"" : "";
  2316. this.domNode.innerHTML =
  2317. '<div class="mblSwitchInner">'
  2318. + '<div class="mblSwitchBg mblSwitchBgLeft">'
  2319. + '<div class="mblSwitchText mblSwitchTextLeft"></div>'
  2320. + '</div>'
  2321. + '<div class="mblSwitchBg mblSwitchBgRight">'
  2322. + '<div class="mblSwitchText mblSwitchTextRight"></div>'
  2323. + '</div>'
  2324. + '<div class="mblSwitchKnob"></div>'
  2325. + '<input type="hidden"'+nameAttr+'></div>'
  2326. + '</div>';
  2327. var n = this.inner = this.domNode.firstChild;
  2328. this.left = n.childNodes[0];
  2329. this.right = n.childNodes[1];
  2330. this.knob = n.childNodes[2];
  2331. this.input = n.childNodes[3];
  2332. },
  2333. postCreate: function(){
  2334. this.connect(this.domNode, "onclick", "onClick");
  2335. this.connect(this.domNode, has("touch") ? "touchstart" : "onmousedown", "onTouchStart");
  2336. this._initialValue = this.value; // for reset()
  2337. },
  2338. _changeState: function(/*String*/state, /*Boolean*/anim){
  2339. var on = (state === "on");
  2340. this.left.style.display = "";
  2341. this.right.style.display = "";
  2342. this.inner.style.left = "";
  2343. if(anim){
  2344. domClass.add(this.domNode, "mblSwitchAnimation");
  2345. }
  2346. domClass.remove(this.domNode, on ? "mblSwitchOff" : "mblSwitchOn");
  2347. domClass.add(this.domNode, on ? "mblSwitchOn" : "mblSwitchOff");
  2348. var _this = this;
  2349. setTimeout(function(){
  2350. _this.left.style.display = on ? "" : "none";
  2351. _this.right.style.display = !on ? "" : "none";
  2352. domClass.remove(_this.domNode, "mblSwitchAnimation");
  2353. }, anim ? 300 : 0);
  2354. },
  2355. startup: function(){
  2356. if(this._swClass.indexOf("Round") != -1){
  2357. var r = Math.round(this.domNode.offsetHeight / 2);
  2358. this.createRoundMask(this._swClass, r, this.domNode.offsetWidth);
  2359. }
  2360. },
  2361. createRoundMask: function(className, r, w){
  2362. if(!has("webkit") || !className){ return; }
  2363. if(!this._createdMasks){ this._createdMasks = []; }
  2364. if(this._createdMasks[className]){ return; }
  2365. this._createdMasks[className] = 1;
  2366. var ctx = win.doc.getCSSCanvasContext("2d", className+"Mask", w, 100);
  2367. ctx.fillStyle = "#000000";
  2368. ctx.beginPath();
  2369. ctx.moveTo(r, 0);
  2370. ctx.arcTo(0, 0, 0, 2*r, r);
  2371. ctx.arcTo(0, 2*r, r, 2*r, r);
  2372. ctx.lineTo(w - r, 2*r);
  2373. ctx.arcTo(w, 2*r, w, r, r);
  2374. ctx.arcTo(w, 0, w - r, 0, r);
  2375. ctx.closePath();
  2376. ctx.fill();
  2377. },
  2378. onClick: function(e){
  2379. if(this._moved){ return; }
  2380. this.value = this.input.value = (this.value == "on") ? "off" : "on";
  2381. this._changeState(this.value, true);
  2382. this.onStateChanged(this.value);
  2383. },
  2384. onTouchStart: function(e){
  2385. // summary:
  2386. // Internal function to handle touchStart events.
  2387. this._moved = false;
  2388. this.innerStartX = this.inner.offsetLeft;
  2389. if(!this._conn){
  2390. this._conn = [];
  2391. this._conn.push(connect.connect(this.inner, has("touch") ? "touchmove" : "onmousemove", this, "onTouchMove"));
  2392. this._conn.push(connect.connect(this.inner, has("touch") ? "touchend" : "onmouseup", this, "onTouchEnd"));
  2393. }
  2394. this.touchStartX = e.touches ? e.touches[0].pageX : e.clientX;
  2395. this.left.style.display = "";
  2396. this.right.style.display = "";
  2397. event.stop(e);
  2398. },
  2399. onTouchMove: function(e){
  2400. // summary:
  2401. // Internal function to handle touchMove events.
  2402. e.preventDefault();
  2403. var dx;
  2404. if(e.targetTouches){
  2405. if(e.targetTouches.length != 1){ return false; }
  2406. dx = e.targetTouches[0].clientX - this.touchStartX;
  2407. }else{
  2408. dx = e.clientX - this.touchStartX;
  2409. }
  2410. var pos = this.innerStartX + dx;
  2411. var d = 10;
  2412. if(pos <= -(this._width-d)){ pos = -this._width; }
  2413. if(pos >= -d){ pos = 0; }
  2414. this.inner.style.left = pos + "px";
  2415. if(Math.abs(dx) > d){
  2416. this._moved = true;
  2417. }
  2418. },
  2419. onTouchEnd: function(e){
  2420. // summary:
  2421. // Internal function to handle touchEnd events.
  2422. array.forEach(this._conn, connect.disconnect);
  2423. this._conn = null;
  2424. if(this.innerStartX == this.inner.offsetLeft){
  2425. if(has("touch")){
  2426. var ev = win.doc.createEvent("MouseEvents");
  2427. ev.initEvent("click", true, true);
  2428. this.inner.dispatchEvent(ev);
  2429. }
  2430. return;
  2431. }
  2432. var newState = (this.inner.offsetLeft < -(this._width/2)) ? "off" : "on";
  2433. this._changeState(newState, true);
  2434. if(newState != this.value){
  2435. this.value = this.input.value = newState;
  2436. this.onStateChanged(newState);
  2437. }
  2438. },
  2439. onStateChanged: function(/*String*/newState){
  2440. // summary:
  2441. // Stub function to connect to from your application.
  2442. // description:
  2443. // Called when the state has been changed.
  2444. },
  2445. _setValueAttr: function(/*String*/value){
  2446. this._changeState(value, false);
  2447. if(this.value != value){
  2448. this.onStateChanged(value);
  2449. }
  2450. this.value = this.input.value = value;
  2451. },
  2452. _setLeftLabelAttr: function(/*String*/label){
  2453. this.leftLabel = label;
  2454. this.left.firstChild.innerHTML = this._cv ? this._cv(label) : label;
  2455. },
  2456. _setRightLabelAttr: function(/*String*/label){
  2457. this.rightLabel = label;
  2458. this.right.firstChild.innerHTML = this._cv ? this._cv(label) : label;
  2459. },
  2460. reset: function(){
  2461. // summary:
  2462. // Reset the widget's value to what it was at initialization time
  2463. this.set("value", this._initialValue);
  2464. }
  2465. });
  2466. });
  2467. },
  2468. 'dojox/mobile/ListItem':function(){
  2469. define("dojox/mobile/ListItem", [
  2470. "dojo/_base/array",
  2471. "dojo/_base/connect",
  2472. "dojo/_base/declare",
  2473. "dojo/_base/lang",
  2474. "dojo/dom-class",
  2475. "dojo/dom-construct",
  2476. "dojo/has",
  2477. "./common",
  2478. "./_ItemBase",
  2479. "./TransitionEvent"
  2480. ], function(array, connect, declare, lang, domClass, domConstruct, has, common, ItemBase, TransitionEvent){
  2481. /*=====
  2482. var ItemBase = dojox.mobile._ItemBase;
  2483. =====*/
  2484. // module:
  2485. // dojox/mobile/ListItem
  2486. // summary:
  2487. // An item of either RoundRectList or EdgeToEdgeList.
  2488. return declare("dojox.mobile.ListItem", ItemBase, {
  2489. // summary:
  2490. // An item of either RoundRectList or EdgeToEdgeList.
  2491. // description:
  2492. // ListItem represents an item of either RoundRectList or
  2493. // EdgeToEdgeList. There are three ways to move to a different
  2494. // view, moveTo, href, and url. You can choose only one of them.
  2495. // rightText: String
  2496. // A right-aligned text to display on the item.
  2497. rightText: "",
  2498. // rightIcon: String
  2499. // An icon to display at the right hand side of the item. The value
  2500. // can be either a path for an image file or a class name of a DOM
  2501. // button.
  2502. rightIcon: "",
  2503. // rightIcon2: String
  2504. // An icon to display at the left of the rightIcon. The value can
  2505. // be either a path for an image file or a class name of a DOM
  2506. // button.
  2507. rightIcon2: "",
  2508. // anchorLabel: Boolean
  2509. // If true, the label text becomes a clickable anchor text. When
  2510. // the user clicks on the text, the onAnchorLabelClicked handler is
  2511. // called. You can override or connect to the handler and implement
  2512. // any action. The handler has no default action.
  2513. anchorLabel: false,
  2514. // noArrow: Boolean
  2515. // If true, the right hand side arrow is not displayed.
  2516. noArrow: false,
  2517. // selected: Boolean
  2518. // If true, the item is highlighted to indicate it is selected.
  2519. selected: false,
  2520. // checked: Boolean
  2521. // If true, a check mark is displayed at the right of the item.
  2522. checked: false,
  2523. // arrowClass: String
  2524. // An icon to display as an arrow. The value can be either a path
  2525. // for an image file or a class name of a DOM button.
  2526. arrowClass: "mblDomButtonArrow",
  2527. // checkClass: String
  2528. // An icon to display as a check mark. The value can be either a
  2529. // path for an image file or a class name of a DOM button.
  2530. checkClass: "mblDomButtonCheck",
  2531. // variableHeight: Boolean
  2532. // If true, the height of the item varies according to its
  2533. // content. In dojo 1.6 or older, the "mblVariableHeight" class was
  2534. // used for this purpose. In dojo 1.7, adding the mblVariableHeight
  2535. // class still works for backward compatibility.
  2536. variableHeight: false,
  2537. // rightIconTitle: String
  2538. // An alt text for the right icon.
  2539. rightIconTitle: "",
  2540. // rightIcon2Title: String
  2541. // An alt text for the right icon2.
  2542. rightIcon2Title: "",
  2543. // btnClass: String
  2544. // Deprecated. For backward compatibility.
  2545. btnClass: "",
  2546. // btnClass2: String
  2547. // Deprecated. For backward compatibility.
  2548. btnClass2: "",
  2549. // tag: String
  2550. // A name of html tag to create as domNode.
  2551. tag: "li",
  2552. postMixInProperties: function(){
  2553. // for backward compatibility
  2554. if(this.btnClass){
  2555. this.rightIcon = this.btnClass;
  2556. }
  2557. this._setBtnClassAttr = this._setRightIconAttr;
  2558. this._setBtnClass2Attr = this._setRightIcon2Attr;
  2559. },
  2560. buildRendering: function(){
  2561. this.domNode = this.srcNodeRef || domConstruct.create(this.tag);
  2562. this.inherited(arguments);
  2563. this.domNode.className = "mblListItem" + (this.selected ? " mblItemSelected" : "");
  2564. // label
  2565. var box = this.box = domConstruct.create("DIV");
  2566. box.className = "mblListItemTextBox";
  2567. if(this.anchorLabel){
  2568. box.style.cursor = "pointer";
  2569. }
  2570. var r = this.srcNodeRef;
  2571. if(r && !this.label){
  2572. this.label = "";
  2573. for(var i = 0, len = r.childNodes.length; i < len; i++){
  2574. var n = r.firstChild;
  2575. if(n.nodeType === 3 && lang.trim(n.nodeValue) !== ""){
  2576. n.nodeValue = this._cv ? this._cv(n.nodeValue) : n.nodeValue;
  2577. this.labelNode = domConstruct.create("SPAN", {className:"mblListItemLabel"});
  2578. this.labelNode.appendChild(n);
  2579. n = this.labelNode;
  2580. }
  2581. box.appendChild(n);
  2582. }
  2583. }
  2584. if(!this.labelNode){
  2585. this.labelNode = domConstruct.create("SPAN", {className:"mblListItemLabel"}, box);
  2586. }
  2587. if(this.anchorLabel){
  2588. box.style.display = "inline"; // to narrow the text region
  2589. }
  2590. var a = this.anchorNode = domConstruct.create("A");
  2591. a.className = "mblListItemAnchor";
  2592. this.domNode.appendChild(a);
  2593. a.appendChild(box);
  2594. },
  2595. startup: function(){
  2596. if(this._started){ return; }
  2597. this.inheritParams();
  2598. var parent = this.getParent();
  2599. if(this.moveTo || this.href || this.url || this.clickable || (parent && parent.select)){
  2600. this._onClickHandle = this.connect(this.anchorNode, "onclick", "onClick");
  2601. }
  2602. this.setArrow();
  2603. if(domClass.contains(this.domNode, "mblVariableHeight")){
  2604. this.variableHeight = true;
  2605. }
  2606. if(this.variableHeight){
  2607. domClass.add(this.domNode, "mblVariableHeight");
  2608. setTimeout(lang.hitch(this, "layoutVariableHeight"));
  2609. }
  2610. this.set("icon", this.icon); // _setIconAttr may be called twice but this is necessary for offline instantiation
  2611. if(!this.checked && this.checkClass.indexOf(',') !== -1){
  2612. this.set("checked", this.checked);
  2613. }
  2614. this.inherited(arguments);
  2615. },
  2616. resize: function(){
  2617. if(this.variableHeight){
  2618. this.layoutVariableHeight();
  2619. }
  2620. },
  2621. onClick: function(e){
  2622. var a = e.currentTarget;
  2623. var li = a.parentNode;
  2624. if(domClass.contains(li, "mblItemSelected")){ return; } // already selected
  2625. if(this.anchorLabel){
  2626. for(var p = e.target; p.tagName !== this.tag.toUpperCase(); p = p.parentNode){
  2627. if(p.className == "mblListItemTextBox"){
  2628. domClass.add(p, "mblListItemTextBoxSelected");
  2629. setTimeout(function(){
  2630. domClass.remove(p, "mblListItemTextBoxSelected");
  2631. }, has("android") ? 300 : 1000);
  2632. this.onAnchorLabelClicked(e);
  2633. return;
  2634. }
  2635. }
  2636. }
  2637. var parent = this.getParent();
  2638. if(parent.select){
  2639. if(parent.select === "single"){
  2640. if(!this.checked){
  2641. this.set("checked", true);
  2642. }
  2643. }else if(parent.select === "multiple"){
  2644. this.set("checked", !this.checked);
  2645. }
  2646. }
  2647. this.select();
  2648. if (this.href && this.hrefTarget) {
  2649. common.openWindow(this.href, this.hrefTarget);
  2650. return;
  2651. }
  2652. var transOpts;
  2653. if(this.moveTo || this.href || this.url || this.scene){
  2654. transOpts = {moveTo: this.moveTo, href: this.href, url: this.url, scene: this.scene, transition: this.transition, transitionDir: this.transitionDir};
  2655. }else if(this.transitionOptions){
  2656. transOpts = this.transitionOptions;
  2657. }
  2658. if(transOpts){
  2659. this.setTransitionPos(e);
  2660. return new TransitionEvent(this.domNode,transOpts,e).dispatch();
  2661. }
  2662. },
  2663. select: function(){
  2664. // summary:
  2665. // Makes this widget in the selected state.
  2666. var parent = this.getParent();
  2667. if(parent.stateful){
  2668. parent.deselectAll();
  2669. }else{
  2670. var _this = this;
  2671. setTimeout(function(){
  2672. _this.deselect();
  2673. }, has("android") ? 300 : 1000);
  2674. }
  2675. domClass.add(this.domNode, "mblItemSelected");
  2676. },
  2677. deselect: function(){
  2678. // summary:
  2679. // Makes this widget in the deselected state.
  2680. domClass.remove(this.domNode, "mblItemSelected");
  2681. },
  2682. onAnchorLabelClicked: function(e){
  2683. // summary:
  2684. // Stub function to connect to from your application.
  2685. },
  2686. layoutVariableHeight: function(){
  2687. var h = this.anchorNode.offsetHeight;
  2688. if(h === this.anchorNodeHeight){ return; }
  2689. this.anchorNodeHeight = h;
  2690. array.forEach([
  2691. this.rightTextNode,
  2692. this.rightIcon2Node,
  2693. this.rightIconNode,
  2694. this.iconNode
  2695. ], function(n){
  2696. if(n){
  2697. var t = Math.round((h - n.offsetHeight) / 2);
  2698. n.style.marginTop = t + "px";
  2699. }
  2700. });
  2701. },
  2702. setArrow: function(){
  2703. // summary:
  2704. // Sets the arrow icon if necessary.
  2705. if(this.checked){ return; }
  2706. var c = "";
  2707. var parent = this.getParent();
  2708. if(this.moveTo || this.href || this.url || this.clickable){
  2709. if(!this.noArrow && !(parent && parent.stateful)){
  2710. c = this.arrowClass;
  2711. }
  2712. }
  2713. if(c){
  2714. this._setRightIconAttr(c);
  2715. }
  2716. },
  2717. _setIconAttr: function(icon){
  2718. if(!this.getParent()){ return; } // icon may be invalid because inheritParams is not called yet
  2719. this.icon = icon;
  2720. var a = this.anchorNode;
  2721. if(!this.iconNode){
  2722. if(icon){
  2723. var ref = this.rightIconNode || this.rightIcon2Node || this.rightTextNode || this.box;
  2724. this.iconNode = domConstruct.create("DIV", {className:"mblListItemIcon"}, ref, "before");
  2725. }
  2726. }else{
  2727. domConstruct.empty(this.iconNode);
  2728. }
  2729. if(icon && icon !== "none"){
  2730. common.createIcon(icon, this.iconPos, null, this.alt, this.iconNode);
  2731. if(this.iconPos){
  2732. domClass.add(this.iconNode.firstChild, "mblListItemSpriteIcon");
  2733. }
  2734. domClass.remove(a, "mblListItemAnchorNoIcon");
  2735. }else{
  2736. domClass.add(a, "mblListItemAnchorNoIcon");
  2737. }
  2738. },
  2739. _setCheckedAttr: function(/*Boolean*/checked){
  2740. var parent = this.getParent();
  2741. if(parent && parent.select === "single" && checked){
  2742. array.forEach(parent.getChildren(), function(child){
  2743. child.set("checked", false);
  2744. });
  2745. }
  2746. this._setRightIconAttr(this.checkClass);
  2747. var icons = this.rightIconNode.childNodes;
  2748. if(icons.length === 1){
  2749. this.rightIconNode.style.display = checked ? "" : "none";
  2750. }else{
  2751. icons[0].style.display = checked ? "" : "none";
  2752. icons[1].style.display = !checked ? "" : "none";
  2753. }
  2754. domClass.toggle(this.domNode, "mblListItemChecked", checked);
  2755. if(parent && this.checked !== checked){
  2756. parent.onCheckStateChanged(this, checked);
  2757. }
  2758. this.checked = checked;
  2759. },
  2760. _setRightTextAttr: function(/*String*/text){
  2761. if(!this.rightTextNode){
  2762. this.rightTextNode = domConstruct.create("DIV", {className:"mblListItemRightText"}, this.box, "before");
  2763. }
  2764. this.rightText = text;
  2765. this.rightTextNode.innerHTML = this._cv ? this._cv(text) : text;
  2766. },
  2767. _setRightIconAttr: function(/*String*/icon){
  2768. if(!this.rightIconNode){
  2769. var ref = this.rightIcon2Node || this.rightTextNode || this.box;
  2770. this.rightIconNode = domConstruct.create("DIV", {className:"mblListItemRightIcon"}, ref, "before");
  2771. }else{
  2772. domConstruct.empty(this.rightIconNode);
  2773. }
  2774. this.rightIcon = icon;
  2775. var arr = (icon || "").split(/,/);
  2776. if(arr.length === 1){
  2777. common.createIcon(icon, null, null, this.rightIconTitle, this.rightIconNode);
  2778. }else{
  2779. common.createIcon(arr[0], null, null, this.rightIconTitle, this.rightIconNode);
  2780. common.createIcon(arr[1], null, null, this.rightIconTitle, this.rightIconNode);
  2781. }
  2782. },
  2783. _setRightIcon2Attr: function(/*String*/icon){
  2784. if(!this.rightIcon2Node){
  2785. var ref = this.rightTextNode || this.box;
  2786. this.rightIcon2Node = domConstruct.create("DIV", {className:"mblListItemRightIcon2"}, ref, "before");
  2787. }else{
  2788. domConstruct.empty(this.rightIcon2Node);
  2789. }
  2790. this.rightIcon2 = icon;
  2791. common.createIcon(icon, null, null, this.rightIcon2Title, this.rightIcon2Node);
  2792. },
  2793. _setLabelAttr: function(/*String*/text){
  2794. this.label = text;
  2795. this.labelNode.innerHTML = this._cv ? this._cv(text) : text;
  2796. }
  2797. });
  2798. });
  2799. },
  2800. 'dijit/registry':function(){
  2801. define("dijit/registry", [
  2802. "dojo/_base/array", // array.forEach array.map
  2803. "dojo/_base/sniff", // has("ie")
  2804. "dojo/_base/unload", // unload.addOnWindowUnload
  2805. "dojo/_base/window", // win.body
  2806. "." // dijit._scopeName
  2807. ], function(array, has, unload, win, dijit){
  2808. // module:
  2809. // dijit/registry
  2810. // summary:
  2811. // Registry of existing widget on page, plus some utility methods.
  2812. // Must be accessed through AMD api, ex:
  2813. // require(["dijit/registry"], function(registry){ registry.byId("foo"); })
  2814. var _widgetTypeCtr = {}, hash = {};
  2815. var registry = {
  2816. // summary:
  2817. // A set of widgets indexed by id
  2818. length: 0,
  2819. add: function(/*dijit._Widget*/ widget){
  2820. // summary:
  2821. // Add a widget to the registry. If a duplicate ID is detected, a error is thrown.
  2822. //
  2823. // widget: dijit._Widget
  2824. // Any dijit._Widget subclass.
  2825. if(hash[widget.id]){
  2826. throw new Error("Tried to register widget with id==" + widget.id + " but that id is already registered");
  2827. }
  2828. hash[widget.id] = widget;
  2829. this.length++;
  2830. },
  2831. remove: function(/*String*/ id){
  2832. // summary:
  2833. // Remove a widget from the registry. Does not destroy the widget; simply
  2834. // removes the reference.
  2835. if(hash[id]){
  2836. delete hash[id];
  2837. this.length--;
  2838. }
  2839. },
  2840. byId: function(/*String|Widget*/ id){
  2841. // summary:
  2842. // Find a widget by it's id.
  2843. // If passed a widget then just returns the widget.
  2844. return typeof id == "string" ? hash[id] : id; // dijit._Widget
  2845. },
  2846. byNode: function(/*DOMNode*/ node){
  2847. // summary:
  2848. // Returns the widget corresponding to the given DOMNode
  2849. return hash[node.getAttribute("widgetId")]; // dijit._Widget
  2850. },
  2851. toArray: function(){
  2852. // summary:
  2853. // Convert registry into a true Array
  2854. //
  2855. // example:
  2856. // Work with the widget .domNodes in a real Array
  2857. // | array.map(dijit.registry.toArray(), function(w){ return w.domNode; });
  2858. var ar = [];
  2859. for(var id in hash){
  2860. ar.push(hash[id]);
  2861. }
  2862. return ar; // dijit._Widget[]
  2863. },
  2864. getUniqueId: function(/*String*/widgetType){
  2865. // summary:
  2866. // Generates a unique id for a given widgetType
  2867. var id;
  2868. do{
  2869. id = widgetType + "_" +
  2870. (widgetType in _widgetTypeCtr ?
  2871. ++_widgetTypeCtr[widgetType] : _widgetTypeCtr[widgetType] = 0);
  2872. }while(hash[id]);
  2873. return dijit._scopeName == "dijit" ? id : dijit._scopeName + "_" + id; // String
  2874. },
  2875. findWidgets: function(/*DomNode*/ root){
  2876. // summary:
  2877. // Search subtree under root returning widgets found.
  2878. // Doesn't search for nested widgets (ie, widgets inside other widgets).
  2879. var outAry = [];
  2880. function getChildrenHelper(root){
  2881. for(var node = root.firstChild; node; node = node.nextSibling){
  2882. if(node.nodeType == 1){
  2883. var widgetId = node.getAttribute("widgetId");
  2884. if(widgetId){
  2885. var widget = hash[widgetId];
  2886. if(widget){ // may be null on page w/multiple dojo's loaded
  2887. outAry.push(widget);
  2888. }
  2889. }else{
  2890. getChildrenHelper(node);
  2891. }
  2892. }
  2893. }
  2894. }
  2895. getChildrenHelper(root);
  2896. return outAry;
  2897. },
  2898. _destroyAll: function(){
  2899. // summary:
  2900. // Code to destroy all widgets and do other cleanup on page unload
  2901. // Clean up focus manager lingering references to widgets and nodes
  2902. dijit._curFocus = null;
  2903. dijit._prevFocus = null;
  2904. dijit._activeStack = [];
  2905. // Destroy all the widgets, top down
  2906. array.forEach(registry.findWidgets(win.body()), function(widget){
  2907. // Avoid double destroy of widgets like Menu that are attached to <body>
  2908. // even though they are logically children of other widgets.
  2909. if(!widget._destroyed){
  2910. if(widget.destroyRecursive){
  2911. widget.destroyRecursive();
  2912. }else if(widget.destroy){
  2913. widget.destroy();
  2914. }
  2915. }
  2916. });
  2917. },
  2918. getEnclosingWidget: function(/*DOMNode*/ node){
  2919. // summary:
  2920. // Returns the widget whose DOM tree contains the specified DOMNode, or null if
  2921. // the node is not contained within the DOM tree of any widget
  2922. while(node){
  2923. var id = node.getAttribute && node.getAttribute("widgetId");
  2924. if(id){
  2925. return hash[id];
  2926. }
  2927. node = node.parentNode;
  2928. }
  2929. return null;
  2930. },
  2931. // In case someone needs to access hash.
  2932. // Actually, this is accessed from WidgetSet back-compatibility code
  2933. _hash: hash
  2934. };
  2935. /*=====
  2936. dijit.registry = {
  2937. // summary:
  2938. // A list of widgets on a page.
  2939. };
  2940. =====*/
  2941. dijit.registry = registry;
  2942. return registry;
  2943. });
  2944. },
  2945. 'dojox/mobile/common':function(){
  2946. define("dojox/mobile/common", [
  2947. "dojo/_base/kernel", // to test dojo.hash
  2948. "dojo/_base/array",
  2949. "dojo/_base/config",
  2950. "dojo/_base/connect",
  2951. "dojo/_base/lang",
  2952. "dojo/_base/window",
  2953. "dojo/dom-class",
  2954. "dojo/dom-construct",
  2955. "dojo/dom-style",
  2956. // "dojo/hash", // optionally prereq'ed
  2957. "dojo/ready",
  2958. "dijit/registry", // registry.toArray
  2959. "./sniff",
  2960. "./uacss"
  2961. ], function(dojo, array, config, connect, lang, win, domClass, domConstruct, domStyle, ready, registry, has, uacss){
  2962. var dm = lang.getObject("dojox.mobile", true);
  2963. /*=====
  2964. var dm = dojox.mobile;
  2965. =====*/
  2966. // module:
  2967. // dojox/mobile/common
  2968. // summary:
  2969. // A common module for dojox.mobile.
  2970. // description:
  2971. // This module includes common utility functions that are used by
  2972. // dojox.mobile widgets. Also, it provides functions that are commonly
  2973. // necessary for mobile web applications, such as the hide address bar
  2974. // function.
  2975. dm.getScreenSize = function(){
  2976. // summary:
  2977. // Returns the dimensions of the browser window.
  2978. return {
  2979. h: win.global.innerHeight || win.doc.documentElement.clientHeight,
  2980. w: win.global.innerWidth || win.doc.documentElement.clientWidth
  2981. };
  2982. };
  2983. dm.updateOrient = function(){
  2984. // summary:
  2985. // Updates the orientation specific css classes, 'dj_portrait' and
  2986. // 'dj_landscape'.
  2987. var dim = dm.getScreenSize();
  2988. domClass.replace(win.doc.documentElement,
  2989. dim.h > dim.w ? "dj_portrait" : "dj_landscape",
  2990. dim.h > dim.w ? "dj_landscape" : "dj_portrait");
  2991. };
  2992. dm.updateOrient();
  2993. dm.tabletSize = 500;
  2994. dm.detectScreenSize = function(/*Boolean?*/force){
  2995. // summary:
  2996. // Detects the screen size and determines if the screen is like
  2997. // phone or like tablet. If the result is changed,
  2998. // it sets either of the following css class to <html>
  2999. // - 'dj_phone'
  3000. // - 'dj_tablet'
  3001. // and it publishes either of the following events.
  3002. // - '/dojox/mobile/screenSize/phone'
  3003. // - '/dojox/mobile/screenSize/tablet'
  3004. var dim = dm.getScreenSize();
  3005. var sz = Math.min(dim.w, dim.h);
  3006. var from, to;
  3007. if(sz >= dm.tabletSize && (force || (!this._sz || this._sz < dm.tabletSize))){
  3008. from = "phone";
  3009. to = "tablet";
  3010. }else if(sz < dm.tabletSize && (force || (!this._sz || this._sz >= dm.tabletSize))){
  3011. from = "tablet";
  3012. to = "phone";
  3013. }
  3014. if(to){
  3015. domClass.replace(win.doc.documentElement, "dj_"+to, "dj_"+from);
  3016. connect.publish("/dojox/mobile/screenSize/"+to, [dim]);
  3017. }
  3018. this._sz = sz;
  3019. };
  3020. dm.detectScreenSize();
  3021. dm.setupIcon = function(/*DomNode*/iconNode, /*String*/iconPos){
  3022. // summary:
  3023. // Sets up CSS sprite for a foreground image.
  3024. if(iconNode && iconPos){
  3025. var arr = array.map(iconPos.split(/[ ,]/),function(item){return item-0});
  3026. var t = arr[0]; // top
  3027. var r = arr[1] + arr[2]; // right
  3028. var b = arr[0] + arr[3]; // bottom
  3029. var l = arr[1]; // left
  3030. domStyle.set(iconNode, {
  3031. clip: "rect("+t+"px "+r+"px "+b+"px "+l+"px)",
  3032. top: (iconNode.parentNode ? domStyle.get(iconNode, "top") : 0) - t + "px",
  3033. left: -l + "px"
  3034. });
  3035. }
  3036. };
  3037. // dojox.mobile.hideAddressBarWait: Number
  3038. // The time in milliseconds to wait before the fail-safe hiding address
  3039. // bar runs. The value must be larger than 800.
  3040. dm.hideAddressBarWait = typeof(config["mblHideAddressBarWait"]) === "number" ?
  3041. config["mblHideAddressBarWait"] : 1500;
  3042. dm.hide_1 = function(force){
  3043. // summary:
  3044. // Internal function to hide the address bar.
  3045. scrollTo(0, 1);
  3046. var h = dm.getScreenSize().h + "px";
  3047. if(has("android")){
  3048. if(force){
  3049. win.body().style.minHeight = h;
  3050. }
  3051. dm.resizeAll();
  3052. }else{
  3053. if(force || dm._h === h && h !== win.body().style.minHeight){
  3054. win.body().style.minHeight = h;
  3055. dm.resizeAll();
  3056. }
  3057. }
  3058. dm._h = h;
  3059. };
  3060. dm.hide_fs = function(){
  3061. // summary:
  3062. // Internal function to hide the address bar for fail-safe.
  3063. // description:
  3064. // Resets the height of the body, performs hiding the address
  3065. // bar, and calls resizeAll().
  3066. // This is for fail-safe, in case of failure to complete the
  3067. // address bar hiding in time.
  3068. var t = win.body().style.minHeight;
  3069. win.body().style.minHeight = (dm.getScreenSize().h * 2) + "px"; // to ensure enough height for scrollTo to work
  3070. scrollTo(0, 1);
  3071. setTimeout(function(){
  3072. dm.hide_1(1);
  3073. dm._hiding = false;
  3074. }, 1000);
  3075. };
  3076. dm.hideAddressBar = function(/*Event?*/evt){
  3077. // summary:
  3078. // Hides the address bar.
  3079. // description:
  3080. // Tries hiding of the address bar a couple of times to do it as
  3081. // quick as possible while ensuring resize is done after the hiding
  3082. // finishes.
  3083. if(dm.disableHideAddressBar || dm._hiding){ return; }
  3084. dm._hiding = true;
  3085. dm._h = 0;
  3086. win.body().style.minHeight = (dm.getScreenSize().h * 2) + "px"; // to ensure enough height for scrollTo to work
  3087. setTimeout(dm.hide_1, 0);
  3088. setTimeout(dm.hide_1, 200);
  3089. setTimeout(dm.hide_1, 800);
  3090. setTimeout(dm.hide_fs, dm.hideAddressBarWait);
  3091. };
  3092. dm.resizeAll = function(/*Event?*/evt, /*Widget?*/root){
  3093. // summary:
  3094. // Call the resize() method of all the top level resizable widgets.
  3095. // description:
  3096. // Find all widgets that do not have a parent or the parent does not
  3097. // have the resize() method, and call resize() for them.
  3098. // If a widget has a parent that has resize(), call of the widget's
  3099. // resize() is its parent's responsibility.
  3100. // evt:
  3101. // Native event object
  3102. // root:
  3103. // If specified, search the specified widget recursively for top level
  3104. // resizable widgets.
  3105. // root.resize() is always called regardless of whether root is a
  3106. // top level widget or not.
  3107. // If omitted, search the entire page.
  3108. if(dm.disableResizeAll){ return; }
  3109. connect.publish("/dojox/mobile/resizeAll", [evt, root]);
  3110. dm.updateOrient();
  3111. dm.detectScreenSize();
  3112. var isTopLevel = function(w){
  3113. var parent = w.getParent && w.getParent();
  3114. return !!((!parent || !parent.resize) && w.resize);
  3115. };
  3116. var resizeRecursively = function(w){
  3117. array.forEach(w.getChildren(), function(child){
  3118. if(isTopLevel(child)){ child.resize(); }
  3119. resizeRecursively(child);
  3120. });
  3121. };
  3122. if(root){
  3123. if(root.resize){ root.resize(); }
  3124. resizeRecursively(root);
  3125. }else{
  3126. array.forEach(array.filter(registry.toArray(), isTopLevel),
  3127. function(w){ w.resize(); });
  3128. }
  3129. };
  3130. dm.openWindow = function(url, target){
  3131. // summary:
  3132. // Opens a new browser window with the given url.
  3133. win.global.open(url, target || "_blank");
  3134. };
  3135. dm.createDomButton = function(/*DomNode*/refNode, /*Object?*/style, /*DomNode?*/toNode){
  3136. // summary:
  3137. // Creates a DOM button.
  3138. // description:
  3139. // DOM button is a simple graphical object that consists of one or
  3140. // more nested DIV elements with some CSS styling. It can be used
  3141. // in place of an icon image on ListItem, IconItem, and so on.
  3142. // The kind of DOM button to create is given as a class name of
  3143. // refNode. The number of DIVs to create is searched from the style
  3144. // sheets in the page. However, if the class name has a suffix that
  3145. // starts with an underscore, like mblDomButtonGoldStar_5, then the
  3146. // suffixed number is used instead. A class name for DOM button
  3147. // must starts with 'mblDomButton'.
  3148. // refNode:
  3149. // A node that has a DOM button class name.
  3150. // style:
  3151. // A hash object to set styles to the node.
  3152. // toNode:
  3153. // A root node to create a DOM button. If omitted, refNode is used.
  3154. if(!dm._domButtons){
  3155. if(has("webkit")){
  3156. var findDomButtons = function(sheet, dic){
  3157. // summary:
  3158. // Searches the style sheets for DOM buttons.
  3159. // description:
  3160. // Returns a key-value pair object whose keys are DOM
  3161. // button class names and values are the number of DOM
  3162. // elements they need.
  3163. var i, j;
  3164. if(!sheet){
  3165. var dic = {};
  3166. var ss = dojo.doc.styleSheets;
  3167. for (i = 0; i < ss.length; i++){
  3168. ss[i] && findDomButtons(ss[i], dic);
  3169. }
  3170. return dic;
  3171. }
  3172. var rules = sheet.cssRules || [];
  3173. for (i = 0; i < rules.length; i++){
  3174. var rule = rules[i];
  3175. if(rule.href && rule.styleSheet){
  3176. findDomButtons(rule.styleSheet, dic);
  3177. }else if(rule.selectorText){
  3178. var sels = rule.selectorText.split(/,/);
  3179. for (j = 0; j < sels.length; j++){
  3180. var sel = sels[j];
  3181. var n = sel.split(/>/).length - 1;
  3182. if(sel.match(/(mblDomButton\w+)/)){
  3183. var cls = RegExp.$1;
  3184. if(!dic[cls] || n > dic[cls]){
  3185. dic[cls] = n;
  3186. }
  3187. }
  3188. }
  3189. }
  3190. }
  3191. }
  3192. dm._domButtons = findDomButtons();
  3193. }else{
  3194. dm._domButtons = {};
  3195. }
  3196. }
  3197. var s = refNode.className;
  3198. var node = toNode || refNode;
  3199. if(s.match(/(mblDomButton\w+)/) && s.indexOf("/") === -1){
  3200. var btnClass = RegExp.$1;
  3201. var nDiv = 4;
  3202. if(s.match(/(mblDomButton\w+_(\d+))/)){
  3203. nDiv = RegExp.$2 - 0;
  3204. }else if(dm._domButtons[btnClass] !== undefined){
  3205. nDiv = dm._domButtons[btnClass];
  3206. }
  3207. var props = null;
  3208. if(has("bb") && config["mblBBBoxShadowWorkaround"] !== false){
  3209. // Removes box-shadow because BlackBerry incorrectly renders it.
  3210. props = {style:"-webkit-box-shadow:none"};
  3211. }
  3212. for(var i = 0, p = node; i < nDiv; i++){
  3213. p = p.firstChild || domConstruct.create("DIV", props, p);
  3214. }
  3215. if(toNode){
  3216. setTimeout(function(){
  3217. domClass.remove(refNode, btnClass);
  3218. }, 0);
  3219. domClass.add(toNode, btnClass);
  3220. }
  3221. }else if(s.indexOf(".") !== -1){ // file name
  3222. domConstruct.create("IMG", {src:s}, node);
  3223. }else{
  3224. return null;
  3225. }
  3226. domClass.add(node, "mblDomButton");
  3227. if(config["mblAndroidWorkaround"] !== false && has("android") >= 2.2){
  3228. // Android workaround for the issue that domButtons' -webkit-transform styles sometimes invalidated
  3229. // by applying -webkit-transform:translated3d(x,y,z) style programmatically to non-ancestor elements,
  3230. // which results in breaking domButtons.
  3231. domStyle.set(node, "webkitTransform", "translate3d(0,0,0)");
  3232. }
  3233. !!style && domStyle.set(node, style);
  3234. return node;
  3235. };
  3236. dm.createIcon = function(/*String*/icon, /*String*/iconPos, /*DomNode*/node, /*String?*/title, /*DomNode?*/parent){
  3237. // summary:
  3238. // Creates or updates an icon node
  3239. // description:
  3240. // If node exists, updates the existing node. Otherwise, creates a new one.
  3241. // icon:
  3242. // Path for an image, or DOM button class name.
  3243. if(icon && icon.indexOf("mblDomButton") === 0){
  3244. // DOM button
  3245. if(node && node.className.match(/(mblDomButton\w+)/)){
  3246. domClass.remove(node, RegExp.$1);
  3247. }else{
  3248. node = domConstruct.create("DIV");
  3249. }
  3250. node.title = title;
  3251. domClass.add(node, icon);
  3252. dm.createDomButton(node);
  3253. }else if(icon && icon !== "none"){
  3254. // Image
  3255. if(!node || node.nodeName !== "IMG"){
  3256. node = domConstruct.create("IMG", {
  3257. alt: title
  3258. });
  3259. }
  3260. node.src = (icon || "").replace("${theme}", dm.currentTheme);
  3261. dm.setupIcon(node, iconPos);
  3262. if(parent && iconPos){
  3263. var arr = iconPos.split(/[ ,]/);
  3264. domStyle.set(parent, {
  3265. width: arr[2] + "px",
  3266. height: arr[3] + "px"
  3267. });
  3268. }
  3269. }
  3270. if(parent){
  3271. parent.appendChild(node);
  3272. }
  3273. return node;
  3274. };
  3275. // flag for iphone flicker workaround
  3276. dm._iw = config["mblIosWorkaround"] !== false && has("iphone");
  3277. if(dm._iw){
  3278. dm._iwBgCover = domConstruct.create("div"); // Cover to hide flicker in the background
  3279. }
  3280. if(config.parseOnLoad){
  3281. ready(90, function(){
  3282. // avoid use of query
  3283. /*
  3284. var list = query('[lazy=true] [dojoType]', null);
  3285. list.forEach(function(node, index, nodeList){
  3286. node.setAttribute("__dojoType", node.getAttribute("dojoType"));
  3287. node.removeAttribute("dojoType");
  3288. });
  3289. */
  3290. var nodes = win.body().getElementsByTagName("*");
  3291. var i, len, s;
  3292. len = nodes.length;
  3293. for(i = 0; i < len; i++){
  3294. s = nodes[i].getAttribute("dojoType");
  3295. if(s){
  3296. if(nodes[i].parentNode.getAttribute("lazy") == "true"){
  3297. nodes[i].setAttribute("__dojoType", s);
  3298. nodes[i].removeAttribute("dojoType");
  3299. }
  3300. }
  3301. }
  3302. });
  3303. }
  3304. ready(function(){
  3305. dm.detectScreenSize(true);
  3306. if(config["mblApplyPageStyles"] !== false){
  3307. domClass.add(win.doc.documentElement, "mobile");
  3308. }
  3309. if(has("chrome")){
  3310. // dojox.mobile does not load uacss (only _compat does), but we need dj_chrome.
  3311. domClass.add(win.doc.documentElement, "dj_chrome");
  3312. }
  3313. if(config["mblAndroidWorkaround"] !== false && has("android") >= 2.2){ // workaround for android screen flicker problem
  3314. if(config["mblAndroidWorkaroundButtonStyle"] !== false){
  3315. // workaround to avoid buttons disappear due to the side-effect of the webkitTransform workaroud below
  3316. domConstruct.create("style", {innerHTML:"BUTTON,INPUT[type='button'],INPUT[type='submit'],INPUT[type='reset'],INPUT[type='file']::-webkit-file-upload-button{-webkit-appearance:none;}"}, win.doc.head, "first");
  3317. }
  3318. if(has("android") < 3){ // for Android 2.2.x and 2.3.x
  3319. domStyle.set(win.doc.documentElement, "webkitTransform", "translate3d(0,0,0)");
  3320. // workaround for auto-scroll issue when focusing input fields
  3321. connect.connect(null, "onfocus", null, function(e){
  3322. domStyle.set(win.doc.documentElement, "webkitTransform", "");
  3323. });
  3324. connect.connect(null, "onblur", null, function(e){
  3325. domStyle.set(win.doc.documentElement, "webkitTransform", "translate3d(0,0,0)");
  3326. });
  3327. }else{ // for Android 3.x
  3328. if(config["mblAndroid3Workaround"] !== false){
  3329. domStyle.set(win.doc.documentElement, {
  3330. webkitBackfaceVisibility: "hidden",
  3331. webkitPerspective: 8000
  3332. });
  3333. }
  3334. }
  3335. }
  3336. // You can disable hiding the address bar with the following djConfig.
  3337. // var djConfig = { mblHideAddressBar: false };
  3338. var f = dm.resizeAll;
  3339. if(config["mblHideAddressBar"] !== false &&
  3340. navigator.appVersion.indexOf("Mobile") != -1 ||
  3341. config["mblForceHideAddressBar"] === true){
  3342. dm.hideAddressBar();
  3343. if(config["mblAlwaysHideAddressBar"] === true){
  3344. f = dm.hideAddressBar;
  3345. }
  3346. }
  3347. connect.connect(null, (win.global.onorientationchange !== undefined && !has("android"))
  3348. ? "onorientationchange" : "onresize", null, f);
  3349. // avoid use of query
  3350. /*
  3351. var list = query('[__dojoType]', null);
  3352. list.forEach(function(node, index, nodeList){
  3353. node.setAttribute("dojoType", node.getAttribute("__dojoType"));
  3354. node.removeAttribute("__dojoType");
  3355. });
  3356. */
  3357. var nodes = win.body().getElementsByTagName("*");
  3358. var i, len = nodes.length, s;
  3359. for(i = 0; i < len; i++){
  3360. s = nodes[i].getAttribute("__dojoType");
  3361. if(s){
  3362. nodes[i].setAttribute("dojoType", s);
  3363. nodes[i].removeAttribute("__dojoType");
  3364. }
  3365. }
  3366. if(dojo.hash){
  3367. // find widgets under root recursively
  3368. var findWidgets = function(root){
  3369. if(!root){ return []; }
  3370. var arr = registry.findWidgets(root);
  3371. var widgets = arr;
  3372. for(var i = 0; i < widgets.length; i++){
  3373. arr = arr.concat(findWidgets(widgets[i].containerNode));
  3374. }
  3375. return arr;
  3376. };
  3377. connect.subscribe("/dojo/hashchange", null, function(value){
  3378. var view = dm.currentView;
  3379. if(!view){ return; }
  3380. var params = dm._params;
  3381. if(!params){ // browser back/forward button was pressed
  3382. var moveTo = value ? value : dm._defaultView.id;
  3383. var widgets = findWidgets(view.domNode);
  3384. var dir = 1, transition = "slide";
  3385. for(i = 0; i < widgets.length; i++){
  3386. var w = widgets[i];
  3387. if("#"+moveTo == w.moveTo){
  3388. // found a widget that has the given moveTo
  3389. transition = w.transition;
  3390. dir = (w instanceof dm.Heading) ? -1 : 1;
  3391. break;
  3392. }
  3393. }
  3394. params = [ moveTo, dir, transition ];
  3395. }
  3396. view.performTransition.apply(view, params);
  3397. dm._params = null;
  3398. });
  3399. }
  3400. win.body().style.visibility = "visible";
  3401. });
  3402. // To search _parentNode first. TODO:1.8 reconsider this redefinition.
  3403. registry.getEnclosingWidget = function(node){
  3404. while(node){
  3405. var id = node.getAttribute && node.getAttribute("widgetId");
  3406. if(id){
  3407. return registry.byId(id);
  3408. }
  3409. node = node._parentNode || node.parentNode;
  3410. }
  3411. return null;
  3412. };
  3413. return dm;
  3414. });
  3415. },
  3416. 'dojox/mobile/uacss':function(){
  3417. define("dojox/mobile/uacss", [
  3418. "dojo/_base/kernel",
  3419. "dojo/_base/lang",
  3420. "dojo/_base/window",
  3421. "dojox/mobile/sniff"
  3422. ], function(dojo, lang, win, has){
  3423. win.doc.documentElement.className += lang.trim([
  3424. has("bb") ? "dj_bb" : "",
  3425. has("android") ? "dj_android" : "",
  3426. has("iphone") ? "dj_iphone" : "",
  3427. has("ipod") ? "dj_ipod" : "",
  3428. has("ipad") ? "dj_ipad" : ""
  3429. ].join(" ").replace(/ +/g," "));
  3430. return dojo;
  3431. });
  3432. },
  3433. 'dojox/mobile/RoundRectCategory':function(){
  3434. define("dojox/mobile/RoundRectCategory", [
  3435. "dojo/_base/declare",
  3436. "dojo/_base/window",
  3437. "dijit/_Contained",
  3438. "dijit/_WidgetBase"
  3439. ], function(declare, win, Contained, WidgetBase){
  3440. /*=====
  3441. var Contained = dijit._Contained;
  3442. var WidgetBase = dijit._WidgetBase;
  3443. =====*/
  3444. // module:
  3445. // dojox/mobile/RoundRectCategory
  3446. // summary:
  3447. // A category header for a rounded rectangle list.
  3448. return declare("dojox.mobile.RoundRectCategory", [WidgetBase, Contained],{
  3449. // summary:
  3450. // A category header for a rounded rectangle list.
  3451. // label: String
  3452. // A label text for the widget.
  3453. label: "",
  3454. buildRendering: function(){
  3455. this.domNode = this.containerNode = this.srcNodeRef || win.doc.createElement("H2");
  3456. this.domNode.className = "mblRoundRectCategory";
  3457. if(!this.label){
  3458. this.label = this.domNode.innerHTML;
  3459. }
  3460. },
  3461. _setLabelAttr: function(/*String*/label){
  3462. this.label = label;
  3463. this.domNode.innerHTML = this._cv ? this._cv(label) : label;
  3464. }
  3465. });
  3466. });
  3467. },
  3468. 'dojox/mobile/ProgressIndicator':function(){
  3469. define("dojox/mobile/ProgressIndicator", [
  3470. "dojo/_base/config",
  3471. "dojo/_base/declare",
  3472. "dojo/dom-construct",
  3473. "dojo/dom-style",
  3474. "dojo/has"
  3475. ], function(config, declare, domConstruct, domStyle, has){
  3476. // module:
  3477. // dojox/mobile/ProgressIndicator
  3478. // summary:
  3479. // A progress indication widget.
  3480. var cls = declare("dojox.mobile.ProgressIndicator", null, {
  3481. // summary:
  3482. // A progress indication widget.
  3483. // description:
  3484. // ProgressIndicator is a round spinning graphical representation
  3485. // that indicates the current task is on-going.
  3486. // interval: Number
  3487. // The time interval in milliseconds for updating the spinning
  3488. // indicator.
  3489. interval: 100,
  3490. // colors: Array
  3491. // An array of indicator colors.
  3492. colors: [
  3493. "#C0C0C0", "#C0C0C0", "#C0C0C0", "#C0C0C0",
  3494. "#C0C0C0", "#C0C0C0", "#B8B9B8", "#AEAFAE",
  3495. "#A4A5A4", "#9A9A9A", "#8E8E8E", "#838383"
  3496. ],
  3497. constructor: function(){
  3498. this._bars = [];
  3499. this.domNode = domConstruct.create("DIV");
  3500. this.domNode.className = "mblProgContainer";
  3501. if(config["mblAndroidWorkaround"] !== false && has("android") >= 2.2 && has("android") < 3){
  3502. // workaround to avoid the side effects of the fixes for android screen flicker problem
  3503. domStyle.set(this.domNode, "webkitTransform", "translate3d(0,0,0)");
  3504. }
  3505. this.spinnerNode = domConstruct.create("DIV", null, this.domNode);
  3506. for(var i = 0; i < this.colors.length; i++){
  3507. var div = domConstruct.create("DIV", {className:"mblProg mblProg"+i}, this.spinnerNode);
  3508. this._bars.push(div);
  3509. }
  3510. },
  3511. start: function(){
  3512. // summary:
  3513. // Starts the ProgressIndicator spinning.
  3514. if(this.imageNode){
  3515. var img = this.imageNode;
  3516. var l = Math.round((this.domNode.offsetWidth - img.offsetWidth) / 2);
  3517. var t = Math.round((this.domNode.offsetHeight - img.offsetHeight) / 2);
  3518. img.style.margin = t+"px "+l+"px";
  3519. return;
  3520. }
  3521. var cntr = 0;
  3522. var _this = this;
  3523. var n = this.colors.length;
  3524. this.timer = setInterval(function(){
  3525. cntr--;
  3526. cntr = cntr < 0 ? n - 1 : cntr;
  3527. var c = _this.colors;
  3528. for(var i = 0; i < n; i++){
  3529. var idx = (cntr + i) % n;
  3530. _this._bars[i].style.backgroundColor = c[idx];
  3531. }
  3532. }, this.interval);
  3533. },
  3534. stop: function(){
  3535. // summary:
  3536. // Stops the ProgressIndicator spinning.
  3537. if(this.timer){
  3538. clearInterval(this.timer);
  3539. }
  3540. this.timer = null;
  3541. if(this.domNode.parentNode){
  3542. this.domNode.parentNode.removeChild(this.domNode);
  3543. }
  3544. },
  3545. setImage: function(/*String*/file){
  3546. // summary:
  3547. // Sets an indicator icon image file (typically animated GIF).
  3548. // If null is specified, restores the default spinner.
  3549. if(file){
  3550. this.imageNode = domConstruct.create("IMG", {src:file}, this.domNode);
  3551. this.spinnerNode.style.display = "none";
  3552. }else{
  3553. if(this.imageNode){
  3554. this.domNode.removeChild(this.imageNode);
  3555. this.imageNode = null;
  3556. }
  3557. this.spinnerNode.style.display = "";
  3558. }
  3559. }
  3560. });
  3561. cls._instance = null;
  3562. cls.getInstance = function(){
  3563. if(!cls._instance){
  3564. cls._instance = new cls();
  3565. }
  3566. return cls._instance;
  3567. };
  3568. return cls;
  3569. });
  3570. },
  3571. 'dojox/mobile/EdgeToEdgeList':function(){
  3572. define("dojox/mobile/EdgeToEdgeList", [
  3573. "dojo/_base/declare",
  3574. "./RoundRectList"
  3575. ], function(declare, RoundRectList){
  3576. /*=====
  3577. var RoundRectList = dojox.mobile.RoundRectList;
  3578. =====*/
  3579. // module:
  3580. // dojox/mobile/EdgeToEdgeCategory
  3581. // summary:
  3582. // An edge-to-edge layout list.
  3583. return declare("dojox.mobile.EdgeToEdgeList", RoundRectList, {
  3584. // summary:
  3585. // An edge-to-edge layout list.
  3586. // description:
  3587. // EdgeToEdgeList is an edge-to-edge layout list, which displays
  3588. // all items in equally sized rows. Each item must be
  3589. // dojox.mobile.ListItem.
  3590. buildRendering: function(){
  3591. this.inherited(arguments);
  3592. this.domNode.className = "mblEdgeToEdgeList";
  3593. }
  3594. });
  3595. });
  3596. },
  3597. 'dojox/mobile/EdgeToEdgeCategory':function(){
  3598. define("dojox/mobile/EdgeToEdgeCategory", [
  3599. "dojo/_base/declare",
  3600. "./RoundRectCategory"
  3601. ], function(declare, RoundRectCategory){
  3602. /*=====
  3603. var RoundRectCategory = dojox.mobile.RoundRectCategory;
  3604. =====*/
  3605. // module:
  3606. // dojox/mobile/EdgeToEdgeCategory
  3607. // summary:
  3608. // A category header for an edge-to-edge list.
  3609. return declare("dojox.mobile.EdgeToEdgeCategory", RoundRectCategory, {
  3610. // summary:
  3611. // A category header for an edge-to-edge list.
  3612. buildRendering: function(){
  3613. this.inherited(arguments);
  3614. this.domNode.className = "mblEdgeToEdgeCategory";
  3615. }
  3616. });
  3617. });
  3618. },
  3619. 'dojox/mobile/ToolBarButton':function(){
  3620. define("dojox/mobile/ToolBarButton", [
  3621. "dojo/_base/declare",
  3622. "dojo/_base/window",
  3623. "dojo/dom-class",
  3624. "dojo/dom-construct",
  3625. "dojo/dom-style",
  3626. "./common",
  3627. "./_ItemBase"
  3628. ], function(declare, win, domClass, domConstruct, domStyle, common, ItemBase){
  3629. /*=====
  3630. var ItemBase = dojox.mobile._ItemBase;
  3631. =====*/
  3632. // module:
  3633. // dojox/mobile/ToolBarButton
  3634. // summary:
  3635. // A button widget that is placed in the Heading widget.
  3636. return declare("dojox.mobile.ToolBarButton", ItemBase, {
  3637. // summary:
  3638. // A button widget that is placed in the Heading widget.
  3639. // description:
  3640. // ToolBarButton is a button that is placed in the Heading
  3641. // widget. It is a subclass of dojox.mobile._ItemBase just like
  3642. // ListItem or IconItem. So, unlike Button, it has basically the
  3643. // same capability as ListItem or IconItem, such as icon support,
  3644. // transition, etc.
  3645. // selected: Boolean
  3646. // If true, the button is in the selected status.
  3647. selected: false,
  3648. // btnClass: String
  3649. // Deprecated.
  3650. btnClass: "",
  3651. /* internal properties */
  3652. _defaultColor: "mblColorDefault",
  3653. _selColor: "mblColorDefaultSel",
  3654. buildRendering: function(){
  3655. this.domNode = this.containerNode = this.srcNodeRef || win.doc.createElement("div");
  3656. this.inheritParams();
  3657. domClass.add(this.domNode, "mblToolBarButton mblArrowButtonText");
  3658. var color;
  3659. if(this.selected){
  3660. color = this._selColor;
  3661. }else if(this.domNode.className.indexOf("mblColor") == -1){
  3662. color = this._defaultColor;
  3663. }
  3664. domClass.add(this.domNode, color);
  3665. if(!this.label){
  3666. this.label = this.domNode.innerHTML;
  3667. }
  3668. if(this.icon && this.icon != "none"){
  3669. this.iconNode = domConstruct.create("div", {className:"mblToolBarButtonIcon"}, this.domNode);
  3670. common.createIcon(this.icon, this.iconPos, null, this.alt, this.iconNode);
  3671. if(this.iconPos){
  3672. domClass.add(this.iconNode.firstChild, "mblToolBarButtonSpriteIcon");
  3673. }
  3674. }else{
  3675. if(common.createDomButton(this.domNode)){
  3676. domClass.add(this.domNode, "mblToolBarButtonDomButton");
  3677. }else{
  3678. domClass.add(this.domNode, "mblToolBarButtonText");
  3679. }
  3680. }
  3681. this.connect(this.domNode, "onclick", "onClick");
  3682. },
  3683. select: function(){
  3684. // summary:
  3685. // Makes this widget in the selected state.
  3686. domClass.toggle(this.domNode, this._selColor, !arguments[0]);
  3687. this.selected = !arguments[0];
  3688. },
  3689. deselect: function(){
  3690. // summary:
  3691. // Makes this widget in the deselected state.
  3692. this.select(true);
  3693. },
  3694. onClick: function(e){
  3695. this.setTransitionPos(e);
  3696. this.defaultClickAction();
  3697. },
  3698. _setBtnClassAttr: function(/*String*/btnClass){
  3699. var node = this.domNode;
  3700. if(node.className.match(/(mblDomButton\w+)/)){
  3701. domClass.remove(node, RegExp.$1);
  3702. }
  3703. domClass.add(node, btnClass);
  3704. if(common.createDomButton(this.domNode)){
  3705. domClass.add(this.domNode, "mblToolBarButtonDomButton");
  3706. }
  3707. },
  3708. _setLabelAttr: function(/*String*/text){
  3709. this.label = text;
  3710. this.domNode.innerHTML = this._cv ? this._cv(text) : text;
  3711. }
  3712. });
  3713. });
  3714. },
  3715. 'dojox/mobile/_ItemBase':function(){
  3716. define("dojox/mobile/_ItemBase", [
  3717. "dojo/_base/kernel",
  3718. "dojo/_base/config",
  3719. "dojo/_base/declare",
  3720. "dijit/registry", // registry.getEnclosingWidget
  3721. "dijit/_Contained",
  3722. "dijit/_Container",
  3723. "dijit/_WidgetBase",
  3724. "./TransitionEvent",
  3725. "./View"
  3726. ], function(kernel, config, declare, registry, Contained, Container, WidgetBase, TransitionEvent, View){
  3727. /*=====
  3728. var Contained = dijit._Contained;
  3729. var Container = dijit._Container;
  3730. var WidgetBase = dijit._WidgetBase;
  3731. var TransitionEvent = dojox.mobile.TransitionEvent;
  3732. var View = dojox.mobile.View;
  3733. =====*/
  3734. // module:
  3735. // dojox/mobile/_ItemBase
  3736. // summary:
  3737. // A base class for item classes (e.g. ListItem, IconItem, etc.)
  3738. return declare("dojox.mobile._ItemBase", [WidgetBase, Container, Contained],{
  3739. // summary:
  3740. // A base class for item classes (e.g. ListItem, IconItem, etc.)
  3741. // description:
  3742. // _ItemBase is a base class for widgets that have capability to
  3743. // make a view transition when clicked.
  3744. // icon: String
  3745. // An icon image to display. The value can be either a path for an
  3746. // image file or a class name of a DOM button. If icon is not
  3747. // specified, the iconBase parameter of the parent widget is used.
  3748. icon: "",
  3749. // iconPos: String
  3750. // The position of an aggregated icon. IconPos is comma separated
  3751. // values like top,left,width,height (ex. "0,0,29,29"). If iconPos
  3752. // is not specified, the iconPos parameter of the parent widget is
  3753. // used.
  3754. iconPos: "", // top,left,width,height (ex. "0,0,29,29")
  3755. // alt: String
  3756. // An alt text for the icon image.
  3757. alt: "",
  3758. // href: String
  3759. // A URL of another web page to go to.
  3760. href: "",
  3761. // hrefTarget: String
  3762. // A target that specifies where to open a page specified by
  3763. // href. The value will be passed to the 2nd argument of
  3764. // window.open().
  3765. hrefTarget: "",
  3766. // moveTo: String
  3767. // The id of the transition destination view which resides in the
  3768. // current page.
  3769. //
  3770. // If the value has a hash sign ('#') before the id (e.g. #view1)
  3771. // and the dojo.hash module is loaded by the user application, the
  3772. // view transition updates the hash in the browser URL so that the
  3773. // user can bookmark the destination view. In this case, the user
  3774. // can also use the browser's back/forward button to navigate
  3775. // through the views in the browser history.
  3776. //
  3777. // If null, transitions to a blank view.
  3778. // If '#', returns immediately without transition.
  3779. moveTo: "",
  3780. // scene: String
  3781. // The name of a scene. Used from dojox.mobile.app.
  3782. scene: "",
  3783. // clickable: Boolean
  3784. // If true, this item becomes clickable even if a transition
  3785. // destination (moveTo, etc.) is not specified.
  3786. clickable: false,
  3787. // url: String
  3788. // A URL of an html fragment page or JSON data that represents a
  3789. // new view content. The view content is loaded with XHR and
  3790. // inserted in the current page. Then a view transition occurs to
  3791. // the newly created view. The view is cached so that subsequent
  3792. // requests would not load the content again.
  3793. url: "",
  3794. // urlTarget: String
  3795. // Node id under which a new view will be created according to the
  3796. // url parameter. If not specified, The new view will be created as
  3797. // a sibling of the current view.
  3798. urlTarget: "",
  3799. // transition: String
  3800. // A type of animated transition effect. You can choose from the
  3801. // standard transition types, "slide", "fade", "flip", or from the
  3802. // extended transition types, "cover", "coverv", "dissolve",
  3803. // "reveal", "revealv", "scaleIn", "scaleOut", "slidev",
  3804. // "swirl", "zoomIn", "zoomOut". If "none" is specified, transition
  3805. // occurs immediately without animation.
  3806. transition: "",
  3807. // transitionDir: Number
  3808. // The transition direction. If 1, transition forward. If -1,
  3809. // transition backward. For example, the slide transition slides
  3810. // the view from right to left when dir == 1, and from left to
  3811. // right when dir == -1.
  3812. transitionDir: 1,
  3813. // transitionOptions: Object
  3814. // A hash object that holds transition options.
  3815. transitionOptions: null,
  3816. // callback: Function|String
  3817. // A callback function that is called when the transition has been
  3818. // finished. A function reference, or name of a function in
  3819. // context.
  3820. callback: null,
  3821. // sync: Boolean
  3822. // If true, XHR for the view content specified with the url
  3823. // parameter is performed synchronously. If false, it is done
  3824. // asynchronously and the progress indicator is displayed while
  3825. // loading the content. This parameter is effective only when the
  3826. // url parameter is used.
  3827. sync: true,
  3828. // label: String
  3829. // A label of the item. If the label is not specified, innerHTML is
  3830. // used as a label.
  3831. label: "",
  3832. // toggle: Boolean
  3833. // If true, the item acts like a toggle button.
  3834. toggle: false,
  3835. // _duration: Number
  3836. // Duration of selection, milliseconds.
  3837. _duration: 800,
  3838. inheritParams: function(){
  3839. var parent = this.getParent();
  3840. if(parent){
  3841. if(!this.transition){ this.transition = parent.transition; }
  3842. if(this.icon && parent.iconBase &&
  3843. parent.iconBase.charAt(parent.iconBase.length - 1) === '/'){
  3844. this.icon = parent.iconBase + this.icon;
  3845. }
  3846. if(!this.icon){ this.icon = parent.iconBase; }
  3847. if(!this.iconPos){ this.iconPos = parent.iconPos; }
  3848. }
  3849. },
  3850. select: function(){
  3851. // summary:
  3852. // Makes this widget in the selected state.
  3853. // description:
  3854. // Subclass must implement.
  3855. },
  3856. deselect: function(){
  3857. // summary:
  3858. // Makes this widget in the deselected state.
  3859. // description:
  3860. // Subclass must implement.
  3861. },
  3862. defaultClickAction: function(e){
  3863. if(this.toggle){
  3864. if(this.selected){
  3865. this.deselect();
  3866. }else{
  3867. this.select();
  3868. }
  3869. }else if(!this.selected){
  3870. this.select();
  3871. if(!this.selectOne){
  3872. var _this = this;
  3873. setTimeout(function(){
  3874. _this.deselect();
  3875. }, this._duration);
  3876. }
  3877. var transOpts;
  3878. if(this.moveTo || this.href || this.url || this.scene){
  3879. transOpts = {moveTo: this.moveTo, href: this.href, url: this.url, scene: this.scene, transition: this.transition, transitionDir: this.transitionDir};
  3880. }else if(this.transitionOptions){
  3881. transOpts = this.transitionOptions;
  3882. }
  3883. if(transOpts){
  3884. return new TransitionEvent(this.domNode,transOpts,e).dispatch();
  3885. }
  3886. }
  3887. },
  3888. getParent: function(){
  3889. // summary:
  3890. // Gets the parent widget.
  3891. // description:
  3892. // Almost equivalent to _Contained#getParent, but this method
  3893. // does not cause a script error even if this widget has no
  3894. // parent yet.
  3895. var ref = this.srcNodeRef || this.domNode;
  3896. return ref && ref.parentNode ? registry.getEnclosingWidget(ref.parentNode) : null;
  3897. },
  3898. setTransitionPos: function(e){
  3899. // summary:
  3900. // Stores the clicked position for later use.
  3901. // description:
  3902. // Some of the transition animations (e.g. ScaleIn) needs the
  3903. // clicked position.
  3904. var w = this;
  3905. while(true){
  3906. w = w.getParent();
  3907. if(!w || w instanceof View){ break; }
  3908. }
  3909. if(w){
  3910. w.clickedPosX = e.clientX;
  3911. w.clickedPosY = e.clientY;
  3912. }
  3913. },
  3914. transitionTo: function(moveTo, href, url, scene){
  3915. // summary:
  3916. // Performs a view transition.
  3917. // description:
  3918. // Given a transition destination, this method performs a view
  3919. // transition. This method is typically called when this item
  3920. // is clicked.
  3921. if(config.isDebug){
  3922. var alreadyCalledHash = arguments.callee._ach || (arguments.callee._ach = {}),
  3923. caller = (arguments.callee.caller || "unknown caller").toString();
  3924. if(!alreadyCalledHash[caller]){
  3925. kernel.deprecated(this.declaredClass + "::transitionTo() is deprecated." +
  3926. caller, "", "2.0");
  3927. alreadyCalledHash[caller] = true;
  3928. }
  3929. }
  3930. new TransitionEvent(this.domNode, {moveTo: moveTo, href: href, url: url, scene: scene,
  3931. transition: this.transition, transitionDir: this.transitionDir}).dispatch();
  3932. }
  3933. });
  3934. });
  3935. },
  3936. 'dijit/_Contained':function(){
  3937. define("dijit/_Contained", [
  3938. "dojo/_base/declare", // declare
  3939. "./registry" // registry.getEnclosingWidget(), registry.byNode()
  3940. ], function(declare, registry){
  3941. // module:
  3942. // dijit/_Contained
  3943. // summary:
  3944. // Mixin for widgets that are children of a container widget
  3945. return declare("dijit._Contained", null, {
  3946. // summary:
  3947. // Mixin for widgets that are children of a container widget
  3948. //
  3949. // example:
  3950. // | // make a basic custom widget that knows about it's parents
  3951. // | declare("my.customClass",[dijit._Widget,dijit._Contained],{});
  3952. _getSibling: function(/*String*/ which){
  3953. // summary:
  3954. // Returns next or previous sibling
  3955. // which:
  3956. // Either "next" or "previous"
  3957. // tags:
  3958. // private
  3959. var node = this.domNode;
  3960. do{
  3961. node = node[which+"Sibling"];
  3962. }while(node && node.nodeType != 1);
  3963. return node && registry.byNode(node); // dijit._Widget
  3964. },
  3965. getPreviousSibling: function(){
  3966. // summary:
  3967. // Returns null if this is the first child of the parent,
  3968. // otherwise returns the next element sibling to the "left".
  3969. return this._getSibling("previous"); // dijit._Widget
  3970. },
  3971. getNextSibling: function(){
  3972. // summary:
  3973. // Returns null if this is the last child of the parent,
  3974. // otherwise returns the next element sibling to the "right".
  3975. return this._getSibling("next"); // dijit._Widget
  3976. },
  3977. getIndexInParent: function(){
  3978. // summary:
  3979. // Returns the index of this widget within its container parent.
  3980. // It returns -1 if the parent does not exist, or if the parent
  3981. // is not a dijit._Container
  3982. var p = this.getParent();
  3983. if(!p || !p.getIndexOfChild){
  3984. return -1; // int
  3985. }
  3986. return p.getIndexOfChild(this); // int
  3987. }
  3988. });
  3989. });
  3990. },
  3991. 'dojox/mobile/_base':function(){
  3992. define("dojox/mobile/_base", [
  3993. "./common",
  3994. "./View",
  3995. "./Heading",
  3996. "./RoundRect",
  3997. "./RoundRectCategory",
  3998. "./EdgeToEdgeCategory",
  3999. "./RoundRectList",
  4000. "./EdgeToEdgeList",
  4001. "./ListItem",
  4002. "./Switch",
  4003. "./ToolBarButton",
  4004. "./ProgressIndicator"
  4005. ], function(common, View, Heading, RoundRect, RoundRectCategory, EdgeToEdgeCategory, RoundRectList, EdgeToEdgeList, ListItem, Switch, ToolBarButton, ProgressIndicator){
  4006. // module:
  4007. // dojox/mobile/_base
  4008. // summary:
  4009. // Includes the basic dojox.mobile modules
  4010. return common;
  4011. });
  4012. },
  4013. 'dijit/main':function(){
  4014. define("dijit/main", [
  4015. "dojo/_base/kernel"
  4016. ], function(dojo){
  4017. // module:
  4018. // dijit
  4019. // summary:
  4020. // The dijit package main module
  4021. return dojo.dijit;
  4022. });
  4023. },
  4024. 'dijit/_Container':function(){
  4025. define("dijit/_Container", [
  4026. "dojo/_base/array", // array.forEach array.indexOf
  4027. "dojo/_base/declare", // declare
  4028. "dojo/dom-construct", // domConstruct.place
  4029. "./registry" // registry.byNode()
  4030. ], function(array, declare, domConstruct, registry){
  4031. // module:
  4032. // dijit/_Container
  4033. // summary:
  4034. // Mixin for widgets that contain a set of widget children.
  4035. return declare("dijit._Container", null, {
  4036. // summary:
  4037. // Mixin for widgets that contain a set of widget children.
  4038. // description:
  4039. // Use this mixin for widgets that needs to know about and
  4040. // keep track of their widget children. Suitable for widgets like BorderContainer
  4041. // and TabContainer which contain (only) a set of child widgets.
  4042. //
  4043. // It's not suitable for widgets like ContentPane
  4044. // which contains mixed HTML (plain DOM nodes in addition to widgets),
  4045. // and where contained widgets are not necessarily directly below
  4046. // this.containerNode. In that case calls like addChild(node, position)
  4047. // wouldn't make sense.
  4048. buildRendering: function(){
  4049. this.inherited(arguments);
  4050. if(!this.containerNode){
  4051. // all widgets with descendants must set containerNode
  4052. this.containerNode = this.domNode;
  4053. }
  4054. },
  4055. addChild: function(/*dijit._Widget*/ widget, /*int?*/ insertIndex){
  4056. // summary:
  4057. // Makes the given widget a child of this widget.
  4058. // description:
  4059. // Inserts specified child widget's dom node as a child of this widget's
  4060. // container node, and possibly does other processing (such as layout).
  4061. var refNode = this.containerNode;
  4062. if(insertIndex && typeof insertIndex == "number"){
  4063. var children = this.getChildren();
  4064. if(children && children.length >= insertIndex){
  4065. refNode = children[insertIndex-1].domNode;
  4066. insertIndex = "after";
  4067. }
  4068. }
  4069. domConstruct.place(widget.domNode, refNode, insertIndex);
  4070. // If I've been started but the child widget hasn't been started,
  4071. // start it now. Make sure to do this after widget has been
  4072. // inserted into the DOM tree, so it can see that it's being controlled by me,
  4073. // so it doesn't try to size itself.
  4074. if(this._started && !widget._started){
  4075. widget.startup();
  4076. }
  4077. },
  4078. removeChild: function(/*Widget|int*/ widget){
  4079. // summary:
  4080. // Removes the passed widget instance from this widget but does
  4081. // not destroy it. You can also pass in an integer indicating
  4082. // the index within the container to remove
  4083. if(typeof widget == "number"){
  4084. widget = this.getChildren()[widget];
  4085. }
  4086. if(widget){
  4087. var node = widget.domNode;
  4088. if(node && node.parentNode){
  4089. node.parentNode.removeChild(node); // detach but don't destroy
  4090. }
  4091. }
  4092. },
  4093. hasChildren: function(){
  4094. // summary:
  4095. // Returns true if widget has children, i.e. if this.containerNode contains something.
  4096. return this.getChildren().length > 0; // Boolean
  4097. },
  4098. _getSiblingOfChild: function(/*dijit._Widget*/ child, /*int*/ dir){
  4099. // summary:
  4100. // Get the next or previous widget sibling of child
  4101. // dir:
  4102. // if 1, get the next sibling
  4103. // if -1, get the previous sibling
  4104. // tags:
  4105. // private
  4106. var node = child.domNode,
  4107. which = (dir>0 ? "nextSibling" : "previousSibling");
  4108. do{
  4109. node = node[which];
  4110. }while(node && (node.nodeType != 1 || !registry.byNode(node)));
  4111. return node && registry.byNode(node); // dijit._Widget
  4112. },
  4113. getIndexOfChild: function(/*dijit._Widget*/ child){
  4114. // summary:
  4115. // Gets the index of the child in this container or -1 if not found
  4116. return array.indexOf(this.getChildren(), child); // int
  4117. }
  4118. });
  4119. });
  4120. }}});
  4121. define("dojox/mobile", [
  4122. ".",
  4123. "dojo/_base/lang",
  4124. "dojox/mobile/_base"
  4125. ], function(dojox, lang, base){
  4126. lang.getObject("mobile", true, dojox);
  4127. return dojox.mobile;
  4128. });