summaryrefslogtreecommitdiff
path: root/js/dojo-1.7.2/dojox/mobile/ViewController.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/dojo-1.7.2/dojox/mobile/ViewController.js')
-rw-r--r--js/dojo-1.7.2/dojox/mobile/ViewController.js264
1 files changed, 264 insertions, 0 deletions
diff --git a/js/dojo-1.7.2/dojox/mobile/ViewController.js b/js/dojo-1.7.2/dojox/mobile/ViewController.js
new file mode 100644
index 0000000..c9f2c42
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/mobile/ViewController.js
@@ -0,0 +1,264 @@
+//>>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 <body>
+ 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 <div dojoType="dojox.mobile.View">
+ break;
+ }
+ }
+ if(!view){
+ console.log("dojox.mobile.ViewController#_parse: invalid view content");
+ return;
+ }
+ view.style.visibility = "hidden";
+ target.insertBefore(container, refNode);
+ var ws = dojo.parser.parse(container);
+ array.forEach(ws, function(w){
+ if(w && !w._started && w.startup){
+ w.startup();
+ }
+ });
+
+ // allows multiple root nodes in the fragment,
+ // but transition will be performed to the 1st view.
+ for(i = 0, len = container.childNodes.length; i < len; i++){
+ target.insertBefore(container.firstChild, refNode); // reparent
+ }
+ target.removeChild(container);
+
+ registry.byNode(view)._visible = true;
+ }else if(text.charAt(0) === "{"){ // json
+ container = domConstruct.create("DIV");
+ target.insertBefore(container, refNode);
+ this._ws = [];
+ view = this._instantiate(eval('('+text+')'), container);
+ for(i = 0; i < this._ws.length; i++){
+ var w = this._ws[i];
+ w.startup && !w._started && (!w.getParent || !w.getParent()) && w.startup();
+ }
+ this._ws = null;
+ }
+ view.style.display = "none";
+ view.style.visibility = "visible";
+ return dojo.hash ? "#" + view.id : view.id;
+ },
+
+ _instantiate: function(/*Object*/obj, /*DomNode*/node, /*Widget*/parent){
+ // summary:
+ // Given the evaluated json data, does the same thing as what
+ // the parser does.
+ var widget;
+ for(var key in obj){
+ if(key.charAt(0) == "@"){ continue; }
+ var cls = lang.getObject(key);
+ if(!cls){ continue; }
+ var params = {};
+ var proto = cls.prototype;
+ var objs = lang.isArray(obj[key]) ? obj[key] : [obj[key]];
+ for(var i = 0; i < objs.length; i++){
+ for(var prop in objs[i]){
+ if(prop.charAt(0) == "@"){
+ var val = objs[i][prop];
+ prop = prop.substring(1);
+ if(typeof proto[prop] == "string"){
+ params[prop] = val;
+ }else if(typeof proto[prop] == "number"){
+ params[prop] = val - 0;
+ }else if(typeof proto[prop] == "boolean"){
+ params[prop] = (val != "false");
+ }else if(typeof proto[prop] == "object"){
+ params[prop] = eval("(" + val + ")");
+ }
+ }
+ }
+ widget = new cls(params, node);
+ if(node){ // to call View's startup()
+ widget._visible = true;
+ this._ws.push(widget);
+ }
+ if(parent && parent.addChild){
+ parent.addChild(widget);
+ }
+ this._instantiate(objs[i], null, widget);
+ }
+ }
+ return widget && widget.domNode;
+ }
+ });
+ new Controller(); // singleton
+ return Controller;
+});
+