require({cache:{ 'dojox/main':function(){ define("dojox/main", ["dojo/_base/kernel"], function(dojo) { // module: // dojox/main // summary: // The dojox package main module; dojox package is somewhat unusual in that the main module currently just provides an empty object. return dojo.dojox; }); }, 'dojox/mobile/_base':function(){ define([ "./common", "./View", "./Heading", "./RoundRect", "./RoundRectCategory", "./EdgeToEdgeCategory", "./RoundRectList", "./EdgeToEdgeList", "./ListItem", "./Switch", "./ToolBarButton", "./ProgressIndicator" ], function(common, View, Heading, RoundRect, RoundRectCategory, EdgeToEdgeCategory, RoundRectList, EdgeToEdgeList, ListItem, Switch, ToolBarButton, ProgressIndicator){ // module: // dojox/mobile/_base // summary: // Includes the basic dojox.mobile modules return common; }); }, 'dojox/mobile/common':function(){ define([ "dojo/_base/kernel", // to test dojo.hash "dojo/_base/array", "dojo/_base/config", "dojo/_base/connect", "dojo/_base/lang", "dojo/_base/window", "dojo/dom-class", "dojo/dom-construct", "dojo/dom-style", // "dojo/hash", // optionally prereq'ed "dojo/ready", "dijit/registry", // registry.toArray "./sniff", "./uacss" ], function(dojo, array, config, connect, lang, win, domClass, domConstruct, domStyle, ready, registry, has, uacss){ var dm = lang.getObject("dojox.mobile", true); /*===== var dm = dojox.mobile; =====*/ // module: // dojox/mobile/common // summary: // A common module for dojox.mobile. // description: // This module includes common utility functions that are used by // dojox.mobile widgets. Also, it provides functions that are commonly // necessary for mobile web applications, such as the hide address bar // function. dm.getScreenSize = function(){ // summary: // Returns the dimensions of the browser window. return { h: win.global.innerHeight || win.doc.documentElement.clientHeight, w: win.global.innerWidth || win.doc.documentElement.clientWidth }; }; dm.updateOrient = function(){ // summary: // Updates the orientation specific css classes, 'dj_portrait' and // 'dj_landscape'. var dim = dm.getScreenSize(); domClass.replace(win.doc.documentElement, dim.h > dim.w ? "dj_portrait" : "dj_landscape", dim.h > dim.w ? "dj_landscape" : "dj_portrait"); }; dm.updateOrient(); dm.tabletSize = 500; dm.detectScreenSize = function(/*Boolean?*/force){ // summary: // Detects the screen size and determines if the screen is like // phone or like tablet. If the result is changed, // it sets either of the following css class to // - 'dj_phone' // - 'dj_tablet' // and it publishes either of the following events. // - '/dojox/mobile/screenSize/phone' // - '/dojox/mobile/screenSize/tablet' var dim = dm.getScreenSize(); var sz = Math.min(dim.w, dim.h); var from, to; if(sz >= dm.tabletSize && (force || (!this._sz || this._sz < dm.tabletSize))){ from = "phone"; to = "tablet"; }else if(sz < dm.tabletSize && (force || (!this._sz || this._sz >= dm.tabletSize))){ from = "tablet"; to = "phone"; } if(to){ domClass.replace(win.doc.documentElement, "dj_"+to, "dj_"+from); connect.publish("/dojox/mobile/screenSize/"+to, [dim]); } this._sz = sz; }; dm.detectScreenSize(); dm.setupIcon = function(/*DomNode*/iconNode, /*String*/iconPos){ // summary: // Sets up CSS sprite for a foreground image. if(iconNode && iconPos){ var arr = array.map(iconPos.split(/[ ,]/),function(item){return item-0}); var t = arr[0]; // top var r = arr[1] + arr[2]; // right var b = arr[0] + arr[3]; // bottom var l = arr[1]; // left domStyle.set(iconNode, { clip: "rect("+t+"px "+r+"px "+b+"px "+l+"px)", top: (iconNode.parentNode ? domStyle.get(iconNode, "top") : 0) - t + "px", left: -l + "px" }); } }; // dojox.mobile.hideAddressBarWait: Number // The time in milliseconds to wait before the fail-safe hiding address // bar runs. The value must be larger than 800. dm.hideAddressBarWait = typeof(config["mblHideAddressBarWait"]) === "number" ? config["mblHideAddressBarWait"] : 1500; dm.hide_1 = function(force){ // summary: // Internal function to hide the address bar. scrollTo(0, 1); var h = dm.getScreenSize().h + "px"; if(has("android")){ if(force){ win.body().style.minHeight = h; } dm.resizeAll(); }else{ if(force || dm._h === h && h !== win.body().style.minHeight){ win.body().style.minHeight = h; dm.resizeAll(); } } dm._h = h; }; dm.hide_fs = function(){ // summary: // Internal function to hide the address bar for fail-safe. // description: // Resets the height of the body, performs hiding the address // bar, and calls resizeAll(). // This is for fail-safe, in case of failure to complete the // address bar hiding in time. var t = win.body().style.minHeight; win.body().style.minHeight = (dm.getScreenSize().h * 2) + "px"; // to ensure enough height for scrollTo to work scrollTo(0, 1); setTimeout(function(){ dm.hide_1(1); dm._hiding = false; }, 1000); }; dm.hideAddressBar = function(/*Event?*/evt){ // summary: // Hides the address bar. // description: // Tries hiding of the address bar a couple of times to do it as // quick as possible while ensuring resize is done after the hiding // finishes. if(dm.disableHideAddressBar || dm._hiding){ return; } dm._hiding = true; dm._h = 0; win.body().style.minHeight = (dm.getScreenSize().h * 2) + "px"; // to ensure enough height for scrollTo to work setTimeout(dm.hide_1, 0); setTimeout(dm.hide_1, 200); setTimeout(dm.hide_1, 800); setTimeout(dm.hide_fs, dm.hideAddressBarWait); }; dm.resizeAll = function(/*Event?*/evt, /*Widget?*/root){ // summary: // Call the resize() method of all the top level resizable widgets. // description: // Find all widgets that do not have a parent or the parent does not // have the resize() method, and call resize() for them. // If a widget has a parent that has resize(), call of the widget's // resize() is its parent's responsibility. // evt: // Native event object // root: // If specified, search the specified widget recursively for top level // resizable widgets. // root.resize() is always called regardless of whether root is a // top level widget or not. // If omitted, search the entire page. if(dm.disableResizeAll){ return; } connect.publish("/dojox/mobile/resizeAll", [evt, root]); dm.updateOrient(); dm.detectScreenSize(); var isTopLevel = function(w){ var parent = w.getParent && w.getParent(); return !!((!parent || !parent.resize) && w.resize); }; var resizeRecursively = function(w){ array.forEach(w.getChildren(), function(child){ if(isTopLevel(child)){ child.resize(); } resizeRecursively(child); }); }; if(root){ if(root.resize){ root.resize(); } resizeRecursively(root); }else{ array.forEach(array.filter(registry.toArray(), isTopLevel), function(w){ w.resize(); }); } }; dm.openWindow = function(url, target){ // summary: // Opens a new browser window with the given url. win.global.open(url, target || "_blank"); }; dm.createDomButton = function(/*DomNode*/refNode, /*Object?*/style, /*DomNode?*/toNode){ // summary: // Creates a DOM button. // description: // DOM button is a simple graphical object that consists of one or // more nested DIV elements with some CSS styling. It can be used // in place of an icon image on ListItem, IconItem, and so on. // The kind of DOM button to create is given as a class name of // refNode. The number of DIVs to create is searched from the style // sheets in the page. However, if the class name has a suffix that // starts with an underscore, like mblDomButtonGoldStar_5, then the // suffixed number is used instead. A class name for DOM button // must starts with 'mblDomButton'. // refNode: // A node that has a DOM button class name. // style: // A hash object to set styles to the node. // toNode: // A root node to create a DOM button. If omitted, refNode is used. if(!dm._domButtons){ if(has("webkit")){ var findDomButtons = function(sheet, dic){ // summary: // Searches the style sheets for DOM buttons. // description: // Returns a key-value pair object whose keys are DOM // button class names and values are the number of DOM // elements they need. var i, j; if(!sheet){ var dic = {}; var ss = dojo.doc.styleSheets; for (i = 0; i < ss.length; i++){ ss[i] && findDomButtons(ss[i], dic); } return dic; } var rules = sheet.cssRules || []; for (i = 0; i < rules.length; i++){ var rule = rules[i]; if(rule.href && rule.styleSheet){ findDomButtons(rule.styleSheet, dic); }else if(rule.selectorText){ var sels = rule.selectorText.split(/,/); for (j = 0; j < sels.length; j++){ var sel = sels[j]; var n = sel.split(/>/).length - 1; if(sel.match(/(mblDomButton\w+)/)){ var cls = RegExp.$1; if(!dic[cls] || n > dic[cls]){ dic[cls] = n; } } } } } } dm._domButtons = findDomButtons(); }else{ dm._domButtons = {}; } } var s = refNode.className; var node = toNode || refNode; if(s.match(/(mblDomButton\w+)/) && s.indexOf("/") === -1){ var btnClass = RegExp.$1; var nDiv = 4; if(s.match(/(mblDomButton\w+_(\d+))/)){ nDiv = RegExp.$2 - 0; }else if(dm._domButtons[btnClass] !== undefined){ nDiv = dm._domButtons[btnClass]; } var props = null; if(has("bb") && config["mblBBBoxShadowWorkaround"] !== false){ // Removes box-shadow because BlackBerry incorrectly renders it. props = {style:"-webkit-box-shadow:none"}; } for(var i = 0, p = node; i < nDiv; i++){ p = p.firstChild || domConstruct.create("DIV", props, p); } if(toNode){ setTimeout(function(){ domClass.remove(refNode, btnClass); }, 0); domClass.add(toNode, btnClass); } }else if(s.indexOf(".") !== -1){ // file name domConstruct.create("IMG", {src:s}, node); }else{ return null; } domClass.add(node, "mblDomButton"); if(config["mblAndroidWorkaround"] !== false && has("android") >= 2.2){ // Android workaround for the issue that domButtons' -webkit-transform styles sometimes invalidated // by applying -webkit-transform:translated3d(x,y,z) style programmatically to non-ancestor elements, // which results in breaking domButtons. domStyle.set(node, "webkitTransform", "translate3d(0,0,0)"); } !!style && domStyle.set(node, style); return node; }; dm.createIcon = function(/*String*/icon, /*String*/iconPos, /*DomNode*/node, /*String?*/title, /*DomNode?*/parent){ // summary: // Creates or updates an icon node // description: // If node exists, updates the existing node. Otherwise, creates a new one. // icon: // Path for an image, or DOM button class name. if(icon && icon.indexOf("mblDomButton") === 0){ // DOM button if(node && node.className.match(/(mblDomButton\w+)/)){ domClass.remove(node, RegExp.$1); }else{ node = domConstruct.create("DIV"); } node.title = title; domClass.add(node, icon); dm.createDomButton(node); }else if(icon && icon !== "none"){ // Image if(!node || node.nodeName !== "IMG"){ node = domConstruct.create("IMG", { alt: title }); } node.src = (icon || "").replace("${theme}", dm.currentTheme); dm.setupIcon(node, iconPos); if(parent && iconPos){ var arr = iconPos.split(/[ ,]/); domStyle.set(parent, { width: arr[2] + "px", height: arr[3] + "px" }); } } if(parent){ parent.appendChild(node); } return node; }; // flag for iphone flicker workaround dm._iw = config["mblIosWorkaround"] !== false && has("iphone"); if(dm._iw){ dm._iwBgCover = domConstruct.create("div"); // Cover to hide flicker in the background } if(config.parseOnLoad){ ready(90, function(){ // avoid use of query /* var list = query('[lazy=true] [dojoType]', null); list.forEach(function(node, index, nodeList){ node.setAttribute("__dojoType", node.getAttribute("dojoType")); node.removeAttribute("dojoType"); }); */ var nodes = win.body().getElementsByTagName("*"); var i, len, s; len = nodes.length; for(i = 0; i < len; i++){ s = nodes[i].getAttribute("dojoType"); if(s){ if(nodes[i].parentNode.getAttribute("lazy") == "true"){ nodes[i].setAttribute("__dojoType", s); nodes[i].removeAttribute("dojoType"); } } } }); } ready(function(){ dm.detectScreenSize(true); if(config["mblApplyPageStyles"] !== false){ domClass.add(win.doc.documentElement, "mobile"); } if(has("chrome")){ // dojox.mobile does not load uacss (only _compat does), but we need dj_chrome. domClass.add(win.doc.documentElement, "dj_chrome"); } if(config["mblAndroidWorkaround"] !== false && has("android") >= 2.2){ // workaround for android screen flicker problem if(config["mblAndroidWorkaroundButtonStyle"] !== false){ // workaround to avoid buttons disappear due to the side-effect of the webkitTransform workaroud below 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"); } if(has("android") < 3){ // for Android 2.2.x and 2.3.x domStyle.set(win.doc.documentElement, "webkitTransform", "translate3d(0,0,0)"); // workaround for auto-scroll issue when focusing input fields connect.connect(null, "onfocus", null, function(e){ domStyle.set(win.doc.documentElement, "webkitTransform", ""); }); connect.connect(null, "onblur", null, function(e){ domStyle.set(win.doc.documentElement, "webkitTransform", "translate3d(0,0,0)"); }); }else{ // for Android 3.x if(config["mblAndroid3Workaround"] !== false){ domStyle.set(win.doc.documentElement, { webkitBackfaceVisibility: "hidden", webkitPerspective: 8000 }); } } } // You can disable hiding the address bar with the following djConfig. // var djConfig = { mblHideAddressBar: false }; var f = dm.resizeAll; if(config["mblHideAddressBar"] !== false && navigator.appVersion.indexOf("Mobile") != -1 || config["mblForceHideAddressBar"] === true){ dm.hideAddressBar(); if(config["mblAlwaysHideAddressBar"] === true){ f = dm.hideAddressBar; } } connect.connect(null, (win.global.onorientationchange !== undefined && !has("android")) ? "onorientationchange" : "onresize", null, f); // avoid use of query /* var list = query('[__dojoType]', null); list.forEach(function(node, index, nodeList){ node.setAttribute("dojoType", node.getAttribute("__dojoType")); node.removeAttribute("__dojoType"); }); */ var nodes = win.body().getElementsByTagName("*"); var i, len = nodes.length, s; for(i = 0; i < len; i++){ s = nodes[i].getAttribute("__dojoType"); if(s){ nodes[i].setAttribute("dojoType", s); nodes[i].removeAttribute("__dojoType"); } } if(dojo.hash){ // find widgets under root recursively var findWidgets = function(root){ if(!root){ return []; } var arr = registry.findWidgets(root); var widgets = arr; for(var i = 0; i < widgets.length; i++){ arr = arr.concat(findWidgets(widgets[i].containerNode)); } return arr; }; connect.subscribe("/dojo/hashchange", null, function(value){ var view = dm.currentView; if(!view){ return; } var params = dm._params; if(!params){ // browser back/forward button was pressed var moveTo = value ? value : dm._defaultView.id; var widgets = findWidgets(view.domNode); var dir = 1, transition = "slide"; for(i = 0; i < widgets.length; i++){ var w = widgets[i]; if("#"+moveTo == w.moveTo){ // found a widget that has the given moveTo transition = w.transition; dir = (w instanceof dm.Heading) ? -1 : 1; break; } } params = [ moveTo, dir, transition ]; } view.performTransition.apply(view, params); dm._params = null; }); } win.body().style.visibility = "visible"; }); // To search _parentNode first. TODO:1.8 reconsider this redefinition. registry.getEnclosingWidget = function(node){ while(node){ var id = node.getAttribute && node.getAttribute("widgetId"); if(id){ return registry.byId(id); } node = node._parentNode || node.parentNode; } return null; }; return dm; }); }, 'dijit/registry':function(){ define("dijit/registry", [ "dojo/_base/array", // array.forEach array.map "dojo/_base/sniff", // has("ie") "dojo/_base/unload", // unload.addOnWindowUnload "dojo/_base/window", // win.body "." // dijit._scopeName ], function(array, has, unload, win, dijit){ // module: // dijit/registry // summary: // Registry of existing widget on page, plus some utility methods. // Must be accessed through AMD api, ex: // require(["dijit/registry"], function(registry){ registry.byId("foo"); }) var _widgetTypeCtr = {}, hash = {}; var registry = { // summary: // A set of widgets indexed by id length: 0, add: function(/*dijit._Widget*/ widget){ // summary: // Add a widget to the registry. If a duplicate ID is detected, a error is thrown. // // widget: dijit._Widget // Any dijit._Widget subclass. if(hash[widget.id]){ throw new Error("Tried to register widget with id==" + widget.id + " but that id is already registered"); } hash[widget.id] = widget; this.length++; }, remove: function(/*String*/ id){ // summary: // Remove a widget from the registry. Does not destroy the widget; simply // removes the reference. if(hash[id]){ delete hash[id]; this.length--; } }, byId: function(/*String|Widget*/ id){ // summary: // Find a widget by it's id. // If passed a widget then just returns the widget. return typeof id == "string" ? hash[id] : id; // dijit._Widget }, byNode: function(/*DOMNode*/ node){ // summary: // Returns the widget corresponding to the given DOMNode return hash[node.getAttribute("widgetId")]; // dijit._Widget }, toArray: function(){ // summary: // Convert registry into a true Array // // example: // Work with the widget .domNodes in a real Array // | array.map(dijit.registry.toArray(), function(w){ return w.domNode; }); var ar = []; for(var id in hash){ ar.push(hash[id]); } return ar; // dijit._Widget[] }, getUniqueId: function(/*String*/widgetType){ // summary: // Generates a unique id for a given widgetType var id; do{ id = widgetType + "_" + (widgetType in _widgetTypeCtr ? ++_widgetTypeCtr[widgetType] : _widgetTypeCtr[widgetType] = 0); }while(hash[id]); return dijit._scopeName == "dijit" ? id : dijit._scopeName + "_" + id; // String }, findWidgets: function(/*DomNode*/ root){ // summary: // Search subtree under root returning widgets found. // Doesn't search for nested widgets (ie, widgets inside other widgets). var outAry = []; function getChildrenHelper(root){ for(var node = root.firstChild; node; node = node.nextSibling){ if(node.nodeType == 1){ var widgetId = node.getAttribute("widgetId"); if(widgetId){ var widget = hash[widgetId]; if(widget){ // may be null on page w/multiple dojo's loaded outAry.push(widget); } }else{ getChildrenHelper(node); } } } } getChildrenHelper(root); return outAry; }, _destroyAll: function(){ // summary: // Code to destroy all widgets and do other cleanup on page unload // Clean up focus manager lingering references to widgets and nodes dijit._curFocus = null; dijit._prevFocus = null; dijit._activeStack = []; // Destroy all the widgets, top down array.forEach(registry.findWidgets(win.body()), function(widget){ // Avoid double destroy of widgets like Menu that are attached to
// even though they are logically children of other widgets. if(!widget._destroyed){ if(widget.destroyRecursive){ widget.destroyRecursive(); }else if(widget.destroy){ widget.destroy(); } } }); }, getEnclosingWidget: function(/*DOMNode*/ node){ // summary: // Returns the widget whose DOM tree contains the specified DOMNode, or null if // the node is not contained within the DOM tree of any widget while(node){ var id = node.getAttribute && node.getAttribute("widgetId"); if(id){ return hash[id]; } node = node.parentNode; } return null; }, // In case someone needs to access hash. // Actually, this is accessed from WidgetSet back-compatibility code _hash: hash }; /*===== dijit.registry = { // summary: // A list of widgets on a page. }; =====*/ dijit.registry = registry; return registry; }); }, 'dijit/main':function(){ define("dijit/main", [ "dojo/_base/kernel" ], function(dojo){ // module: // dijit // summary: // The dijit package main module return dojo.dijit; }); }, 'dojox/mobile/sniff':function(){ define([ "dojo/_base/window", "dojo/_base/sniff" ], function(win, has){ var ua = navigator.userAgent; // BlackBerry (OS 6 or later only) has.add("bb", ua.indexOf("BlackBerry") >= 0 && parseFloat(ua.split("Version/")[1]) || undefined, undefined, true); // Android has.add("android", parseFloat(ua.split("Android ")[1]) || undefined, undefined, true); // iPhone, iPod, or iPad // If iPod or iPad is detected, in addition to has("ipod") or has("ipad"), // has("iphone") will also have iOS version number. if(ua.match(/(iPhone|iPod|iPad)/)){ var p = RegExp.$1.replace(/P/, 'p'); var v = ua.match(/OS ([\d_]+)/) ? RegExp.$1 : "1"; var os = parseFloat(v.replace(/_/, '.').replace(/_/g, '')); has.add(p, os, undefined, true); has.add("iphone", os, undefined, true); } if(has("webkit")){ has.add("touch", (typeof win.doc.documentElement.ontouchstart != "undefined" && navigator.appVersion.indexOf("Mobile") != -1) || !!has("android"), undefined, true); } return has; }); }, 'dojox/mobile/uacss':function(){ define([ "dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/window", "dojox/mobile/sniff" ], function(dojo, lang, win, has){ win.doc.documentElement.className += lang.trim([ has("bb") ? "dj_bb" : "", has("android") ? "dj_android" : "", has("iphone") ? "dj_iphone" : "", has("ipod") ? "dj_ipod" : "", has("ipad") ? "dj_ipad" : "" ].join(" ").replace(/ +/g," ")); return dojo; }); }, 'dojox/mobile/View':function(){ define([ "dojo/_base/kernel", // to test dojo.hash "dojo/_base/array", "dojo/_base/config", "dojo/_base/connect", "dojo/_base/declare", "dojo/_base/lang", "dojo/_base/sniff", "dojo/_base/window", "dojo/_base/Deferred", "dojo/dom", "dojo/dom-class", "dojo/dom-geometry", "dojo/dom-style", // "dojo/hash", // optionally prereq'ed "dijit/registry", // registry.byNode "dijit/_Contained", "dijit/_Container", "dijit/_WidgetBase", "./ViewController", // to load ViewController for you (no direct references) "./transition" ], function(dojo, array, config, connect, declare, lang, has, win, Deferred, dom, domClass, domGeometry, domStyle, registry, Contained, Container, WidgetBase, ViewController, transitDeferred){ /*===== var Contained = dijit._Contained; var Container = dijit._Container; var WidgetBase = dijit._WidgetBase; var ViewController = dojox.mobile.ViewController; =====*/ // module: // dojox/mobile/View // summary: // A widget that represents a view that occupies the full screen var dm = lang.getObject("dojox.mobile", true); return declare("dojox.mobile.View", [WidgetBase, Container, Contained], { // summary: // A widget that represents a view that occupies the full screen // description: // View acts as a container for any HTML and/or widgets. An entire // HTML page can have multiple View widgets and the user can // navigate through the views back and forth without page // transitions. // selected: Boolean // If true, the view is displayed at startup time. selected: false, // keepScrollPos: Boolean // If true, the scroll position is kept between views. keepScrollPos: true, constructor: function(params, node){ if(node){ dom.byId(node).style.visibility = "hidden"; } this._aw = has("android") >= 2.2 && has("android") < 3; // flag for android animation workaround }, buildRendering: function(){ this.domNode = this.containerNode = this.srcNodeRef || win.doc.createElement("DIV"); this.domNode.className = "mblView"; this.connect(this.domNode, "webkitAnimationEnd", "onAnimationEnd"); this.connect(this.domNode, "webkitAnimationStart", "onAnimationStart"); if(!config['mblCSS3Transition']){ this.connect(this.domNode, "webkitTransitionEnd", "onAnimationEnd"); } var id = location.href.match(/#(\w+)([^\w=]|$)/) ? RegExp.$1 : null; this._visible = this.selected && !id || this.id == id; if(this.selected){ dm._defaultView = this; } }, startup: function(){ if(this._started){ return; } var siblings = []; var children = this.domNode.parentNode.childNodes; var visible = false; // check if a visible view exists for(var i = 0; i < children.length; i++){ var c = children[i]; if(c.nodeType === 1 && domClass.contains(c, "mblView")){ siblings.push(c); visible = visible || registry.byNode(c)._visible; } } var _visible = this._visible; // if no visible view exists, make the first view visible if(siblings.length === 1 || (!visible && siblings[0] === this.domNode)){ _visible = true; } var _this = this; setTimeout(function(){ // necessary to render the view correctly if(!_visible){ _this.domNode.style.display = "none"; }else{ dm.currentView = _this; //TODO:1.8 reconsider this. currentView may not have a currently showing view when views are nested. _this.onStartView(); connect.publish("/dojox/mobile/startView", [_this]); } if(_this.domNode.style.visibility != "visible"){ // this check is to avoid screen flickers _this.domNode.style.visibility = "visible"; } var parent = _this.getParent && _this.getParent(); if(!parent || !parent.resize){ // top level widget _this.resize(); } }, has("ie") ? 100 : 0); // give IE a little time to complete drawing this.inherited(arguments); }, resize: function(){ // summary: // Calls resize() of each child widget. array.forEach(this.getChildren(), function(child){ if(child.resize){ child.resize(); } }); }, onStartView: function(){ // summary: // Stub function to connect to from your application. // description: // Called only when this view is shown at startup time. }, onBeforeTransitionIn: function(moveTo, dir, transition, context, method){ // summary: // Stub function to connect to from your application. // description: // Called before the arriving transition occurs. }, onAfterTransitionIn: function(moveTo, dir, transition, context, method){ // summary: // Stub function to connect to from your application. // description: // Called after the arriving transition occurs. }, onBeforeTransitionOut: function(moveTo, dir, transition, context, method){ // summary: // Stub function to connect to from your application. // description: // Called before the leaving transition occurs. }, onAfterTransitionOut: function(moveTo, dir, transition, context, method){ // summary: // Stub function to connect to from your application. // description: // Called after the leaving transition occurs. }, _saveState: function(moveTo, dir, transition, context, method){ this._context = context; this._method = method; if(transition == "none"){ transition = null; } this._moveTo = moveTo; this._dir = dir; this._transition = transition; this._arguments = lang._toArray(arguments); this._args = []; if(context || method){ for(var i = 5; i < arguments.length; i++){ this._args.push(arguments[i]); } } }, _fixViewState: function(/*DomNode*/toNode){ // summary: // Sanity check for view transition states. // description: // Sometimes uninitialization of Views fails after making view transition, // and that results in failure of subsequent view transitions. // This function does the uninitialization for all the sibling views. var nodes = this.domNode.parentNode.childNodes; for(var i = 0; i < nodes.length; i++){ var n = nodes[i]; if(n.nodeType === 1 && domClass.contains(n, "mblView")){ n.className = "mblView"; //TODO: Should remove classes one by one. This would clear user defined classes or even mblScrollableView. } } toNode.className = "mblView"; // just in case toNode is a sibling of an ancestor. }, convertToId: function(moveTo){ if(typeof(moveTo) == "string"){ // removes a leading hash mark (#) and params if exists // ex. "#bar&myParam=0003" -> "bar" moveTo.match(/^#?([^&?]+)/); return RegExp.$1; } return moveTo; }, performTransition: function(/*String*/moveTo, /*Number*/dir, /*String*/transition, /*Object|null*/context, /*String|Function*/method /*optional args*/){ // summary: // Function to perform the various types of view transitions, such as fade, slide, and flip. // moveTo: String // The id of the transition destination view which resides in // the current page. // If the value has a hash sign ('#') before the id // (e.g. #view1) and the dojo.hash module is loaded by the user // application, the view transition updates the hash in the // browser URL so that the user can bookmark the destination // view. In this case, the user can also use the browser's // back/forward button to navigate through the views in the // browser history. // If null, transitions to a blank view. // If '#', returns immediately without transition. // dir: Number // The transition direction. If 1, transition forward. If -1, transition backward. // For example, the slide transition slides the view from right to left when dir == 1, // and from left to right when dir == -1. // transition: String // A type of animated transition effect. You can choose from // the standard transition types, "slide", "fade", "flip", or // from the extended transition types, "cover", "coverv", // "dissolve", "reveal", "revealv", "scaleIn", // "scaleOut", "slidev", "swirl", "zoomIn", "zoomOut". If // "none" is specified, transition occurs immediately without // animation. // context: Object // The object that the callback function will receive as "this". // method: String|Function // A callback function that is called when the transition has been finished. // A function reference, or name of a function in context. // tags: // public // // example: // Transition backward to a view whose id is "foo" with the slide animation. // | performTransition("foo", -1, "slide"); // // example: // Transition forward to a blank view, and then open another page. // | performTransition(null, 1, "slide", null, function(){location.href = href;}); if(moveTo === "#"){ return; } if(dojo.hash){ if(typeof(moveTo) == "string" && moveTo.charAt(0) == '#' && !dm._params){ dm._params = []; for(var i = 0; i < arguments.length; i++){ dm._params.push(arguments[i]); } dojo.hash(moveTo); return; } } this._saveState.apply(this, arguments); var toNode; if(moveTo){ toNode = this.convertToId(moveTo); }else{ if(!this._dummyNode){ this._dummyNode = win.doc.createElement("DIV"); win.body().appendChild(this._dummyNode); } toNode = this._dummyNode; } var fromNode = this.domNode; var fromTop = fromNode.offsetTop; toNode = this.toNode = dom.byId(toNode); if(!toNode){ console.log("dojox.mobile.View#performTransition: destination view not found: "+moveTo); return; } toNode.style.visibility = this._aw ? "visible" : "hidden"; toNode.style.display = ""; this._fixViewState(toNode); var toWidget = registry.byNode(toNode); if(toWidget){ // Now that the target view became visible, it's time to run resize() if(config["mblAlwaysResizeOnTransition"] || !toWidget._resized){ dm.resizeAll(null, toWidget); toWidget._resized = true; } if(transition && transition != "none"){ // Temporarily add padding to align with the fromNode while transition toWidget.containerNode.style.paddingTop = fromTop + "px"; } toWidget.movedFrom = fromNode.id; } this.onBeforeTransitionOut.apply(this, arguments); connect.publish("/dojox/mobile/beforeTransitionOut", [this].concat(lang._toArray(arguments))); if(toWidget){ // perform view transition keeping the scroll position if(this.keepScrollPos && !this.getParent()){ var scrollTop = win.body().scrollTop || win.doc.documentElement.scrollTop || win.global.pageYOffset || 0; fromNode._scrollTop = scrollTop; var toTop = (dir == 1) ? 0 : (toNode._scrollTop || 0); toNode.style.top = "0px"; if(scrollTop > 1 || toTop !== 0){ fromNode.style.top = toTop - scrollTop + "px"; if(config["mblHideAddressBar"] !== false){ setTimeout(function(){ // iPhone needs setTimeout win.global.scrollTo(0, (toTop || 1)); }, 0); } } }else{ toNode.style.top = "0px"; } toWidget.onBeforeTransitionIn.apply(toWidget, arguments); connect.publish("/dojox/mobile/beforeTransitionIn", [toWidget].concat(lang._toArray(arguments))); } if(!this._aw){ toNode.style.display = "none"; toNode.style.visibility = "visible"; } if(dm._iw && dm.scrollable){ // Workaround for iPhone flicker issue (only when scrollable.js is loaded) var ss = dm.getScreenSize(); // Show cover behind the view. // cover's z-index is set to -10000, lower than z-index value specified in transition css. win.body().appendChild(dm._iwBgCover); domStyle.set(dm._iwBgCover, { position: "absolute", top: "0px", left: "0px", height: (ss.h + 1) + "px", // "+1" means the height of scrollTo(0,1) width: ss.w + "px", backgroundColor: domStyle.get(win.body(), "background-color"), zIndex: -10000, display: "" }); // Show toNode behind the cover. domStyle.set(toNode, { position: "absolute", zIndex: -10001, visibility: "visible", display: "" }); // setTimeout seems to be necessary to avoid flicker. // Also the duration of setTimeout should be long enough to avoid flicker. // 0 is not effective. 50 sometimes causes flicker. setTimeout(lang.hitch(this, function(){ this._doTransition(fromNode, toNode, transition, dir); }), 80); }else{ this._doTransition(fromNode, toNode, transition, dir); } }, _toCls: function(s){ // convert from transition name to corresponding class name // ex. "slide" -> "mblSlide" return "mbl"+s.charAt(0).toUpperCase() + s.substring(1); }, _doTransition: function(fromNode, toNode, transition, dir){ var rev = (dir == -1) ? " mblReverse" : ""; if(dm._iw && dm.scrollable){ // Workaround for iPhone flicker issue (only when scrollable.js is loaded) // Show toNode after flicker ends domStyle.set(toNode, { position: "", zIndex: "" }); // Remove cover win.body().removeChild(dm._iwBgCover); }else if(!this._aw){ toNode.style.display = ""; } if(!transition || transition == "none"){ this.domNode.style.display = "none"; this.invokeCallback(); }else if(config['mblCSS3Transition']){ //get dojox/css3/transit first Deferred.when(transitDeferred, lang.hitch(this, function(transit){ //follow the style of .mblView.mblIn in View.css //need to set the toNode to absolute position var toPosition = domStyle.get(toNode, "position"); domStyle.set(toNode, "position", "absolute"); Deferred.when(transit(fromNode, toNode, {transition: transition, reverse: (dir===-1)?true:false}),lang.hitch(this,function(){ domStyle.set(toNode, "position", toPosition); this.invokeCallback(); })); })); }else{ var s = this._toCls(transition); domClass.add(fromNode, s + " mblOut" + rev); domClass.add(toNode, s + " mblIn" + rev); setTimeout(function(){ domClass.add(fromNode, "mblTransition"); domClass.add(toNode, "mblTransition"); }, 100); // set transform origin var fromOrigin = "50% 50%"; var toOrigin = "50% 50%"; var scrollTop, posX, posY; if(transition.indexOf("swirl") != -1 || transition.indexOf("zoom") != -1){ if(this.keepScrollPos && !this.getParent()){ scrollTop = win.body().scrollTop || win.doc.documentElement.scrollTop || win.global.pageYOffset || 0; }else{ scrollTop = -domGeometry.position(fromNode, true).y; } posY = win.global.innerHeight / 2 + scrollTop; fromOrigin = "50% " + posY + "px"; toOrigin = "50% " + posY + "px"; }else if(transition.indexOf("scale") != -1){ var viewPos = domGeometry.position(fromNode, true); posX = ((this.clickedPosX !== undefined) ? this.clickedPosX : win.global.innerWidth / 2) - viewPos.x; if(this.keepScrollPos && !this.getParent()){ scrollTop = win.body().scrollTop || win.doc.documentElement.scrollTop || win.global.pageYOffset || 0; }else{ scrollTop = -viewPos.y; } posY = ((this.clickedPosY !== undefined) ? this.clickedPosY : win.global.innerHeight / 2) + scrollTop; fromOrigin = posX + "px " + posY + "px"; toOrigin = posX + "px " + posY + "px"; } domStyle.set(fromNode, {webkitTransformOrigin:fromOrigin}); domStyle.set(toNode, {webkitTransformOrigin:toOrigin}); } dm.currentView = registry.byNode(toNode); }, onAnimationStart: function(e){ }, onAnimationEnd: function(e){ var name = e.animationName || e.target.className; if(name.indexOf("Out") === -1 && name.indexOf("In") === -1 && name.indexOf("Shrink") === -1){ return; } var isOut = false; if(domClass.contains(this.domNode, "mblOut")){ isOut = true; this.domNode.style.display = "none"; domClass.remove(this.domNode, [this._toCls(this._transition), "mblIn", "mblOut", "mblReverse"]); }else{ // Reset the temporary padding this.containerNode.style.paddingTop = ""; } domStyle.set(this.domNode, {webkitTransformOrigin:""}); if(name.indexOf("Shrink") !== -1){ var li = e.target; li.style.display = "none"; domClass.remove(li, "mblCloseContent"); } if(isOut){ this.invokeCallback(); } // this.domNode may be destroyed as a result of invoking the callback, // so check for that before accessing it. this.domNode && (this.domNode.className = "mblView"); // clear the clicked position this.clickedPosX = this.clickedPosY = undefined; }, invokeCallback: function(){ this.onAfterTransitionOut.apply(this, this._arguments); connect.publish("/dojox/mobile/afterTransitionOut", [this].concat(this._arguments)); var toWidget = registry.byNode(this.toNode); if(toWidget){ toWidget.onAfterTransitionIn.apply(toWidget, this._arguments); connect.publish("/dojox/mobile/afterTransitionIn", [toWidget].concat(this._arguments)); toWidget.movedFrom = undefined; } var c = this._context, m = this._method; if(!c && !m){ return; } if(!m){ m = c; c = null; } c = c || win.global; if(typeof(m) == "string"){ c[m].apply(c, this._args); }else{ m.apply(c, this._args); } }, getShowingView: function(){ // summary: // Find the currently showing view from my sibling views. // description: // Note that dojox.mobile.currentView is the last shown view. // If the page consists of a splitter, there are multiple showing views. var nodes = this.domNode.parentNode.childNodes; for(var i = 0; i < nodes.length; i++){ var n = nodes[i]; if(n.nodeType === 1 && domClass.contains(n, "mblView") && domStyle.get(n, "display") !== "none"){ return registry.byNode(n); } } return null; }, show: function(){ // summary: // Shows this view without a transition animation. var view = this.getShowingView(); if(view){ view.domNode.style.display = "none"; // from-style } this.domNode.style.display = ""; // to-style dm.currentView = this; } }); }); }, 'dijit/_Contained':function(){ define("dijit/_Contained", [ "dojo/_base/declare", // declare "./registry" // registry.getEnclosingWidget(), registry.byNode() ], function(declare, registry){ // module: // dijit/_Contained // summary: // Mixin for widgets that are children of a container widget return declare("dijit._Contained", null, { // summary: // Mixin for widgets that are children of a container widget // // example: // | // make a basic custom widget that knows about it's parents // | declare("my.customClass",[dijit._Widget,dijit._Contained],{}); _getSibling: function(/*String*/ which){ // summary: // Returns next or previous sibling // which: // Either "next" or "previous" // tags: // private var node = this.domNode; do{ node = node[which+"Sibling"]; }while(node && node.nodeType != 1); return node && registry.byNode(node); // dijit._Widget }, getPreviousSibling: function(){ // summary: // Returns null if this is the first child of the parent, // otherwise returns the next element sibling to the "left". return this._getSibling("previous"); // dijit._Widget }, getNextSibling: function(){ // summary: // Returns null if this is the last child of the parent, // otherwise returns the next element sibling to the "right". return this._getSibling("next"); // dijit._Widget }, getIndexInParent: function(){ // summary: // Returns the index of this widget within its container parent. // It returns -1 if the parent does not exist, or if the parent // is not a dijit._Container var p = this.getParent(); if(!p || !p.getIndexOfChild){ return -1; // int } return p.getIndexOfChild(this); // int } }); }); }, 'dijit/_Container':function(){ define("dijit/_Container", [ "dojo/_base/array", // array.forEach array.indexOf "dojo/_base/declare", // declare "dojo/dom-construct", // domConstruct.place "./registry" // registry.byNode() ], function(array, declare, domConstruct, registry){ // module: // dijit/_Container // summary: // Mixin for widgets that contain a set of widget children. return declare("dijit._Container", null, { // summary: // Mixin for widgets that contain a set of widget children. // description: // Use this mixin for widgets that needs to know about and // keep track of their widget children. Suitable for widgets like BorderContainer // and TabContainer which contain (only) a set of child widgets. // // It's not suitable for widgets like ContentPane // which contains mixed HTML (plain DOM nodes in addition to widgets), // and where contained widgets are not necessarily directly below // this.containerNode. In that case calls like addChild(node, position) // wouldn't make sense. buildRendering: function(){ this.inherited(arguments); if(!this.containerNode){ // all widgets with descendants must set containerNode this.containerNode = this.domNode; } }, addChild: function(/*dijit._Widget*/ widget, /*int?*/ insertIndex){ // summary: // Makes the given widget a child of this widget. // description: // Inserts specified child widget's dom node as a child of this widget's // container node, and possibly does other processing (such as layout). var refNode = this.containerNode; if(insertIndex && typeof insertIndex == "number"){ var children = this.getChildren(); if(children && children.length >= insertIndex){ refNode = children[insertIndex-1].domNode; insertIndex = "after"; } } domConstruct.place(widget.domNode, refNode, insertIndex); // If I've been started but the child widget hasn't been started, // start it now. Make sure to do this after widget has been // inserted into the DOM tree, so it can see that it's being controlled by me, // so it doesn't try to size itself. if(this._started && !widget._started){ widget.startup(); } }, removeChild: function(/*Widget|int*/ widget){ // summary: // Removes the passed widget instance from this widget but does // not destroy it. You can also pass in an integer indicating // the index within the container to remove if(typeof widget == "number"){ widget = this.getChildren()[widget]; } if(widget){ var node = widget.domNode; if(node && node.parentNode){ node.parentNode.removeChild(node); // detach but don't destroy } } }, hasChildren: function(){ // summary: // Returns true if widget has children, i.e. if this.containerNode contains something. return this.getChildren().length > 0; // Boolean }, _getSiblingOfChild: function(/*dijit._Widget*/ child, /*int*/ dir){ // summary: // Get the next or previous widget sibling of child // dir: // if 1, get the next sibling // if -1, get the previous sibling // tags: // private var node = child.domNode, which = (dir>0 ? "nextSibling" : "previousSibling"); do{ node = node[which]; }while(node && (node.nodeType != 1 || !registry.byNode(node))); return node && registry.byNode(node); // dijit._Widget }, getIndexOfChild: function(/*dijit._Widget*/ child){ // summary: // Gets the index of the child in this container or -1 if not found return array.indexOf(this.getChildren(), child); // int } }); }); }, 'dijit/_WidgetBase':function(){ define("dijit/_WidgetBase", [ "require", // require.toUrl "dojo/_base/array", // array.forEach array.map "dojo/aspect", "dojo/_base/config", // config.blankGif "dojo/_base/connect", // connect.connect "dojo/_base/declare", // declare "dojo/dom", // dom.byId "dojo/dom-attr", // domAttr.set domAttr.remove "dojo/dom-class", // domClass.add domClass.replace "dojo/dom-construct", // domConstruct.create domConstruct.destroy domConstruct.place "dojo/dom-geometry", // isBodyLtr "dojo/dom-style", // domStyle.set, domStyle.get "dojo/_base/kernel", "dojo/_base/lang", // mixin(), isArray(), etc. "dojo/on", "dojo/ready", "dojo/Stateful", // Stateful "dojo/topic", "dojo/_base/window", // win.doc.createTextNode "./registry" // registry.getUniqueId(), registry.findWidgets() ], function(require, array, aspect, config, connect, declare, dom, domAttr, domClass, domConstruct, domGeometry, domStyle, kernel, lang, on, ready, Stateful, topic, win, registry){ /*===== var Stateful = dojo.Stateful; =====*/ // module: // dijit/_WidgetBase // summary: // Future base class for all Dijit widgets. // For back-compat, remove in 2.0. if(!kernel.isAsync){ ready(0, function(){ var requires = ["dijit/_base/manager"]; require(requires); // use indirection so modules not rolled into a build }); } // Nested hash listing attributes for each tag, all strings in lowercase. // ex: {"div": {"style": true, "tabindex" true}, "form": { ... var tagAttrs = {}; function getAttrs(obj){ var ret = {}; for(var attr in obj){ ret[attr.toLowerCase()] = true; } return ret; } function nonEmptyAttrToDom(attr){ // summary: // Returns a setter function that copies the attribute to this.domNode, // or removes the attribute from this.domNode, depending on whether the // value is defined or not. return function(val){ domAttr[val ? "set" : "remove"](this.domNode, attr, val); this._set(attr, val); }; } function isEqual(a, b){ // summary: // Function that determines whether two values are identical, // taking into account that NaN is not normally equal to itself // in JS. return a === b || (/* a is NaN */ a !== a && /* b is NaN */ b !== b); } return declare("dijit._WidgetBase", Stateful, { // summary: // Future base class for all Dijit widgets. // description: // Future base class for all Dijit widgets. // _Widget extends this class adding support for various features needed by desktop. // // Provides stubs for widget lifecycle methods for subclasses to extend, like postMixInProperties(), buildRendering(), // postCreate(), startup(), and destroy(), and also public API methods like set(), get(), and watch(). // // Widgets can provide custom setters/getters for widget attributes, which are called automatically by set(name, value). // For an attribute XXX, define methods _setXXXAttr() and/or _getXXXAttr(). // // _setXXXAttr can also be a string/hash/array mapping from a widget attribute XXX to the widget's DOMNodes: // // - DOM node attribute // | _setFocusAttr: {node: "focusNode", type: "attribute"} // | _setFocusAttr: "focusNode" (shorthand) // | _setFocusAttr: "" (shorthand, maps to this.domNode) // Maps this.focus to this.focusNode.focus, or (last example) this.domNode.focus // // - DOM node innerHTML // | _setTitleAttr: { node: "titleNode", type: "innerHTML" } // Maps this.title to this.titleNode.innerHTML // // - DOM node innerText // | _setTitleAttr: { node: "titleNode", type: "innerText" } // Maps this.title to this.titleNode.innerText // // - DOM node CSS class // | _setMyClassAttr: { node: "domNode", type: "class" } // Maps this.myClass to this.domNode.className // // If the value of _setXXXAttr is an array, then each element in the array matches one of the // formats of the above list. // // If the custom setter is null, no action is performed other than saving the new value // in the widget (in this). // // If no custom setter is defined for an attribute, then it will be copied // to this.focusNode (if the widget defines a focusNode), or this.domNode otherwise. // That's only done though for attributes that match DOMNode attributes (title, // alt, aria-labelledby, etc.) // id: [const] String // A unique, opaque ID string that can be assigned by users or by the // system. If the developer passes an ID which is known not to be // unique, the specified ID is ignored and the system-generated ID is // used instead. id: "", _setIdAttr: "domNode", // to copy to this.domNode even for auto-generated id's // lang: [const] String // Rarely used. Overrides the default Dojo locale used to render this widget, // as defined by the [HTML LANG](http://www.w3.org/TR/html401/struct/dirlang.html#adef-lang) attribute. // Value must be among the list of locales specified during by the Dojo bootstrap, // formatted according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt) (like en-us). lang: "", // set on domNode even when there's a focus node. but don't set lang="", since that's invalid. _setLangAttr: nonEmptyAttrToDom("lang"), // dir: [const] String // Bi-directional support, as defined by the [HTML DIR](http://www.w3.org/TR/html401/struct/dirlang.html#adef-dir) // attribute. Either left-to-right "ltr" or right-to-left "rtl". If undefined, widgets renders in page's // default direction. dir: "", // set on domNode even when there's a focus node. but don't set dir="", since that's invalid. _setDirAttr: nonEmptyAttrToDom("dir"), // to set on domNode even when there's a focus node // textDir: String // Bi-directional support, the main variable which is responsible for the direction of the text. // The text direction can be different than the GUI direction by using this parameter in creation // of a widget. // Allowed values: // 1. "ltr" // 2. "rtl" // 3. "auto" - contextual the direction of a text defined by first strong letter. // By default is as the page direction. textDir: "", // class: String // HTML class attribute "class": "", _setClassAttr: { node: "domNode", type: "class" }, // style: String||Object // HTML style attributes as cssText string or name/value hash style: "", // title: String // HTML title attribute. // // For form widgets this specifies a tooltip to display when hovering over // the widget (just like the native HTML title attribute). // // For TitlePane or for when this widget is a child of a TabContainer, AccordionContainer, // etc., it's used to specify the tab label, accordion pane title, etc. title: "", // tooltip: String // When this widget's title attribute is used to for a tab label, accordion pane title, etc., // this specifies the tooltip to appear when the mouse is hovered over that text. tooltip: "", // baseClass: [protected] String // Root CSS class of the widget (ex: dijitTextBox), used to construct CSS classes to indicate // widget state. baseClass: "", // srcNodeRef: [readonly] DomNode // pointer to original DOM node srcNodeRef: null, // domNode: [readonly] DomNode // This is our visible representation of the widget! Other DOM // Nodes may by assigned to other properties, usually through the // template system's data-dojo-attach-point syntax, but the domNode // property is the canonical "top level" node in widget UI. domNode: null, // containerNode: [readonly] DomNode // Designates where children of the source DOM node will be placed. // "Children" in this case refers to both DOM nodes and widgets. // For example, for myWidget: // // |