//>>built define("dojox/mobile/ViewController", [ "dojo/_base/kernel", "dojo/_base/array", "dojo/_base/connect", "dojo/_base/declare", "dojo/_base/lang", "dojo/_base/window", "dojo/dom", "dojo/dom-class", "dojo/dom-construct", // "dojo/hash", // optionally prereq'ed "dojo/on", "dojo/ready", "dijit/registry", // registry.byId "./ProgressIndicator", "./TransitionEvent" ], function(dojo, array, connect, declare, lang, win, dom, domClass, domConstruct, on, ready, registry, ProgressIndicator, TransitionEvent){ // module: // dojox/mobile/ViewController // summary: // A singleton class that controlls view transition. var dm = lang.getObject("dojox.mobile", true); var Controller = declare("dojox.mobile.ViewController", null, { // summary: // A singleton class that controlls view transition. // description: // This class listens to the "startTransition" events and performs // view transitions. If the transition destination is an external // view specified with the url parameter, retrieves the view // content and parses it to create a new target view. constructor: function(){ this.viewMap={}; this.currentView=null; this.defaultView=null; ready(lang.hitch(this, function(){ on(win.body(), "startTransition", lang.hitch(this, "onStartTransition")); })); }, findCurrentView: function(moveTo,src){ // summary: // Searches for the currently showing view. if(moveTo){ var w = registry.byId(moveTo); if(w && w.getShowingView){ return w.getShowingView(); } } if(dm.currentView){ return dm.currentView; //TODO:1.8 may not return an expected result especially when views are nested } //TODO:1.8 probably never reaches here w = src; while(true){ w = w.getParent(); if(!w){ return null; } if(domClass.contains(w.domNode, "mblView")){ break; } } return w; }, onStartTransition: function(evt){ // summary: // A handler that performs view transition. evt.preventDefault(); if(!evt.detail || (evt.detail && !evt.detail.moveTo && !evt.detail.href && !evt.detail.url && !evt.detail.scene)){ return; } 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 if(!w || (evt.detail && evt.detail.moveTo && w === registry.byId(evt.detail.moveTo))){ return; } if(evt.detail.href){ var t = registry.byId(evt.target.id).hrefTarget; if(t){ dm.openWindow(evt.detail.href, t); }else{ w.performTransition(null, evt.detail.transitionDir, evt.detail.transition, evt.target, function(){location.href = evt.detail.href;}); } return; } else if(evt.detail.scene){ connect.publish("/dojox/mobile/app/pushScene", [evt.detail.scene]); return; } var moveTo = evt.detail.moveTo; if(evt.detail.url){ var id; if(dm._viewMap && dm._viewMap[evt.detail.url]){ // external view has already been loaded id = dm._viewMap[evt.detail.url]; }else{ // get the specified external view and append it to the
var text = this._text; if(!text){ if(registry.byId(evt.target.id).sync){ // We do not add explicit dependency on dojo/_base/xhr to this module // to be able to create a build that does not contain dojo/_base/xhr. // User applications that do sync loading here need to explicitly // require dojo/_base/xhr up front. dojo.xhrGet({url:evt.detail.url, sync:true, load:function(result){ text = lang.trim(result); }}); }else{ var s = "dojo/_base/xhr"; // assign to a variable so as not to be picked up by the build tool require([s], lang.hitch(this, function(xhr){ var prog = ProgressIndicator.getInstance(); win.body().appendChild(prog.domNode); prog.start(); var obj = xhr.get({ url: evt.detail.url, handleAs: "text" }); obj.addCallback(lang.hitch(this, function(response, ioArgs){ prog.stop(); if(response){ this._text = response; new TransitionEvent(evt.target, { transition: evt.detail.transition, transitionDir: evt.detail.transitionDir, moveTo: moveTo, href: evt.detail.href, url: evt.detail.url, scene: evt.detail.scene}, evt.detail) .dispatch(); } })); obj.addErrback(function(error){ prog.stop(); console.log("Failed to load "+evt.detail.url+"\n"+(error.description||error)); }); })); return; } } this._text = null; id = this._parse(text, registry.byId(evt.target.id).urlTarget); if(!dm._viewMap){ dm._viewMap = []; } dm._viewMap[evt.detail.url] = id; } moveTo = id; w = this.findCurrentView(moveTo,registry.byId(evt.target.id)) || w; // the current view widget } w.performTransition(moveTo, evt.detail.transitionDir, evt.detail.transition, null, null); }, _parse: function(text, id){ // summary: // Parses the given view content. // description: // If the content is html fragment, constructs dom tree with it // and runs the parser. If the content is json data, passes it // to _instantiate(). var container, view, i, j, len; var currentView = this.findCurrentView(); var target = registry.byId(id) && registry.byId(id).containerNode || dom.byId(id) || currentView && currentView.domNode.parentNode || win.body(); // if a fixed bottom bar exists, a new view should be placed before it. var refNode = null; for(j = target.childNodes.length - 1; j >= 0; j--){ var c = target.childNodes[j]; if(c.nodeType === 1){ if(c.getAttribute("fixed") === "bottom"){ refNode = c; } break; } } if(text.charAt(0) === "<"){ // html markup container = domConstruct.create("DIV", {innerHTML: text}); for(i = 0; i < container.childNodes.length; i++){ var n = container.childNodes[i]; if(n.nodeType === 1){ view = n; // expecting