/*
Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
/*
This is an optimized version of Dojo, built for deployment and not for
development. To get sources and documentation, please visit:
http://dojotoolkit.org
*/
//>>built
require({cache:{
'dojo/uacss':function(){
define(["./dom-geometry", "./_base/lang", "./ready", "./_base/sniff", "./_base/window"],
function(geometry, lang, ready, has, baseWindow){
// module:
// dojo/uacss
// summary:
// Applies pre-set CSS classes to the top-level HTML node, based on:
// - browser (ex: dj_ie)
// - browser version (ex: dj_ie6)
// - box model (ex: dj_contentBox)
// - text direction (ex: dijitRtl)
//
// In addition, browser, browser version, and box model are
// combined with an RTL flag when browser text is RTL. ex: dj_ie-rtl.
var
html = baseWindow.doc.documentElement,
ie = has("ie"),
opera = has("opera"),
maj = Math.floor,
ff = has("ff"),
boxModel = geometry.boxModel.replace(/-/,''),
classes = {
"dj_ie": ie,
"dj_ie6": maj(ie) == 6,
"dj_ie7": maj(ie) == 7,
"dj_ie8": maj(ie) == 8,
"dj_ie9": maj(ie) == 9,
"dj_quirks": has("quirks"),
"dj_iequirks": ie && has("quirks"),
// NOTE: Opera not supported by dijit
"dj_opera": opera,
"dj_khtml": has("khtml"),
"dj_webkit": has("webkit"),
"dj_safari": has("safari"),
"dj_chrome": has("chrome"),
"dj_gecko": has("mozilla"),
"dj_ff3": maj(ff) == 3
}; // no dojo unsupported browsers
classes["dj_" + boxModel] = true;
// apply browser, browser version, and box model class names
var classStr = "";
for(var clz in classes){
if(classes[clz]){
classStr += clz + " ";
}
}
html.className = lang.trim(html.className + " " + classStr);
// If RTL mode, then add dj_rtl flag plus repeat existing classes with -rtl extension.
// We can't run the code below until the
tag has loaded (so we can check for dir=rtl).
// priority is 90 to run ahead of parser priority of 100
ready(90, function(){
if(!geometry.isBodyLtr()){
var rtlClassStr = "dj_rtl dijitRtl " + classStr.replace(/ /g, "-rtl ");
html.className = lang.trim(html.className + " " + rtlClassStr + "dj_rtl dijitRtl " + classStr.replace(/ /g, "-rtl "));
}
});
return has;
});
},
'dojox/mobile/app/_Widget':function(){
// wrapped by build app
define(["dijit","dojo","dojox","dojo/require!dijit/_WidgetBase"], function(dijit,dojo,dojox){
dojo.provide("dojox.mobile.app._Widget");
dojo.experimental("dojox.mobile.app._Widget");
dojo.require("dijit._WidgetBase");
dojo.declare("dojox.mobile.app._Widget", dijit._WidgetBase, {
// summary:
// The base mobile app widget.
getScroll: function(){
// summary:
// Returns the scroll position.
return {
x: dojo.global.scrollX,
y: dojo.global.scrollY
};
},
connect: function(target, event, fn){
if(event.toLowerCase() == "dblclick"
|| event.toLowerCase() == "ondblclick"){
if(dojo.global["Mojo"]){
// Handle webOS tap event
return this.connect(target, Mojo.Event.tap, fn);
}
}
return this.inherited(arguments);
}
});
});
},
'dojox/mobile/app/ImageThumbView':function(){
// wrapped by build app
define(["dijit","dojo","dojox","dojo/require!dijit/_WidgetBase,dojo/string"], function(dijit,dojo,dojox){
dojo.provide("dojox.mobile.app.ImageThumbView");
dojo.experimental("dojox.mobile.app.ImageThumbView");
dojo.require("dijit._WidgetBase");
dojo.require("dojo.string");
dojo.declare("dojox.mobile.app.ImageThumbView", dijit._WidgetBase, {
// summary:
// An image thumbnail gallery
// items: Array
// The data items from which the image urls are retrieved.
// If an item is a string, it is expected to be a URL. Otherwise
// by default it is expected to have a 'url' member. This can
// be configured using the 'urlParam' attribute on this widget.
items: [],
// urlParam: String
// The paramter name used to retrieve an image url from a JSON object
urlParam: "url",
labelParam: null,
itemTemplate: '
' +
'' +
'
' +
'' +
'
' +
'
',
minPadding: 4,
maxPerRow: 3,
maxRows: -1,
baseClass: "mblImageThumbView",
thumbSize: "medium",
animationEnabled: true,
selectedIndex: -1,
cache: null,
cacheMustMatch: false,
clickEvent: "onclick",
cacheBust: false,
disableHide: false,
constructor: function(params, node){
},
postCreate: function(){
this.inherited(arguments);
var _this = this;
var hoverCls = "mblThumbHover";
this.addThumb = dojo.hitch(this, this.addThumb);
this.handleImgLoad = dojo.hitch(this, this.handleImgLoad);
this.hideCached = dojo.hitch(this, this.hideCached);
this._onLoadImages = {};
this.cache = [];
this.visibleImages = [];
this._cacheCounter = 0;
this.connect(this.domNode, this.clickEvent, function(event){
var itemNode = _this._getItemNodeFromEvent(event);
if(itemNode && !itemNode._cached){
_this.onSelect(itemNode._item, itemNode._index, _this.items);
dojo.query(".selected", this.domNode).removeClass("selected");
dojo.addClass(itemNode, "selected");
}
});
dojo.addClass(this.domNode, this.thumbSize);
this.resize();
this.render();
},
onSelect: function(item, index, items){
// summary:
// Dummy function that is triggered when an image is selected.
},
_setAnimationEnabledAttr: function(value){
this.animationEnabled = value;
dojo[value ? "addClass" : "removeClass"](this.domNode, "animated");
},
_setItemsAttr: function(items){
this.items = items || [];
var urls = {};
var i;
for(i = 0; i < this.items.length; i++){
urls[this.items[i][this.urlParam]] = 1;
}
var clearedUrls = [];
for(var url in this._onLoadImages){
if(!urls[url] && this._onLoadImages[url]._conn){
dojo.disconnect(this._onLoadImages[url]._conn);
this._onLoadImages[url].src = null;
clearedUrls.push(url);
}
}
for(i = 0; i < clearedUrls.length; i++){
delete this._onLoadImages[url];
}
this.render();
},
_getItemNode: function(node){
while(node && !dojo.hasClass(node, "mblThumb") && node != this.domNode){
node = node.parentNode;
}
return (node == this.domNode) ? null : node;
},
_getItemNodeFromEvent: function(event){
if(event.touches && event.touches.length > 0){
event = event.touches[0];
}
return this._getItemNode(event.target);
},
resize: function(){
this._thumbSize = null;
this._size = dojo.contentBox(this.domNode);
this.disableHide = true;
this.render();
this.disableHide = false;
},
hideCached: function(){
// summary:
// Hides all cached nodes, so that they're no invisible and overlaying
// other screen elements.
for(var i = 0; i < this.cache.length; i++){
if (this.cache[i]) {
dojo.style(this.cache[i], "display", "none");
}
}
},
render: function(){
var i;
var url;
var item;
var thumb;
while(this.visibleImages && this.visibleImages.length > 0){
thumb = this.visibleImages.pop();
this.cache.push(thumb);
if (!this.disableHide) {
dojo.addClass(thumb, "hidden");
}
thumb._cached = true;
}
if(this.cache && this.cache.length > 0){
setTimeout(this.hideCached, 1000);
}
if(!this.items || this.items.length == 0){
return;
}
for(i = 0; i < this.items.length; i++){
item = this.items[i];
url = (dojo.isString(item) ? item : item[this.urlParam]);
this.addThumb(item, url, i);
if(this.maxRows > 0 && (i + 1) / this.maxPerRow >= this.maxRows){
break;
}
}
if(!this._thumbSize){
return;
}
var column = 0;
var row = -1;
var totalThumbWidth = this._thumbSize.w + (this.padding * 2);
var totalThumbHeight = this._thumbSize.h + (this.padding * 2);
var nodes = this.thumbNodes =
dojo.query(".mblThumb", this.domNode);
var pos = 0;
nodes = this.visibleImages;
for(i = 0; i < nodes.length; i++){
if(nodes[i]._cached){
continue;
}
if(pos % this.maxPerRow == 0){
row ++;
}
column = pos % this.maxPerRow;
this.place(
nodes[i],
(column * totalThumbWidth) + this.padding, // x position
(row * totalThumbHeight) + this.padding // y position
);
if(!nodes[i]._loading){
dojo.removeClass(nodes[i], "hidden");
}
if(pos == this.selectedIndex){
dojo[pos == this.selectedIndex ? "addClass" : "removeClass"]
(nodes[i], "selected");
}
pos++;
}
var numRows = Math.ceil(pos / this.maxPerRow);
this._numRows = numRows;
this.setContainerHeight((numRows * (this._thumbSize.h + this.padding * 2)));
},
setContainerHeight: function(amount){
dojo.style(this.domNode, "height", amount + "px");
},
addThumb: function(item, url, index){
var thumbDiv;
var cacheHit = false;
if(this.cache.length > 0){
// Reuse a previously created node if possible
var found = false;
// Search for an image with the same url first
for(var i = 0; i < this.cache.length; i++){
if(this.cache[i]._url == url){
thumbDiv = this.cache.splice(i, 1)[0];
found = true;
break
}
}
// if no image with the same url is found, just take the last one
if(!thumbDiv && !this.cacheMustMatch){
thumbDiv = this.cache.pop();
dojo.removeClass(thumbDiv, "selected");
} else {
cacheHit = true;
}
}
if(!thumbDiv){
// Create a new thumb
thumbDiv = dojo.create("div", {
"class": "mblThumb hidden",
innerHTML: dojo.string.substitute(this.itemTemplate, {
url: url
}, null, this)
}, this.domNode);
}
if(this.labelParam) {
var labelNode = dojo.query(".mblThumbLabel", thumbDiv)[0];
if(!labelNode) {
labelNode = dojo.create("div", {
"class": "mblThumbLabel"
}, thumbDiv);
}
labelNode.innerHTML = item[this.labelParam] || "";
}
dojo.style(thumbDiv, "display", "");
if (!this.disableHide) {
dojo.addClass(thumbDiv, "hidden");
}
if (!cacheHit) {
var loader = dojo.create("img", {});
loader._thumbDiv = thumbDiv;
loader._conn = dojo.connect(loader, "onload", this.handleImgLoad);
loader._url = url;
thumbDiv._loading = true;
this._onLoadImages[url] = loader;
if (loader) {
loader.src = url;
}
}
this.visibleImages.push(thumbDiv);
thumbDiv._index = index;
thumbDiv._item = item;
thumbDiv._url = url;
thumbDiv._cached = false;
if(!this._thumbSize){
this._thumbSize = dojo.marginBox(thumbDiv);
if(this._thumbSize.h == 0){
this._thumbSize.h = 100;
this._thumbSize.w = 100;
}
if(this.labelParam){
this._thumbSize.h += 8;
}
this.calcPadding();
}
},
handleImgLoad: function(event){
var img = event.target;
dojo.disconnect(img._conn);
dojo.removeClass(img._thumbDiv, "hidden");
img._thumbDiv._loading = false;
img._conn = null;
var url = img._url;
if(this.cacheBust){
url += (url.indexOf("?") > -1 ? "&" : "?")
+ "cacheBust=" + (new Date()).getTime() + "_" + (this._cacheCounter++);
}
dojo.query(".mblThumbSrc", img._thumbDiv)
.style("backgroundImage", "url(" + url + ")");
delete this._onLoadImages[img._url];
},
calcPadding: function(){
var width = this._size.w;
var thumbWidth = this._thumbSize.w;
var imgBounds = thumbWidth + this.minPadding;
this.maxPerRow = Math.floor(width / imgBounds);
this.padding = Math.floor((width - (thumbWidth * this.maxPerRow)) / (this.maxPerRow * 2));
},
place: function(node, x, y){
dojo.style(node, {
"-webkit-transform" :"translate(" + x + "px," + y + "px)"
});
},
destroy: function(){
// Stop the loading of any more images
var img;
var counter = 0;
for (var url in this._onLoadImages){
img = this._onLoadImages[url];
if (img) {
img.src = null;
counter++;
}
}
this.inherited(arguments);
}
});
});
},
'dojox/mobile/TransitionEvent':function(){
define("dojox/mobile/TransitionEvent", [
"dojo/_base/declare",
"dojo/_base/Deferred",
"dojo/_base/lang",
"dojo/on",
"./transition"
], function(declare, Deferred, lang, on, transitDeferred){
return declare("dojox.mobile.TransitionEvent", null, {
constructor: function(target, transitionOptions, triggerEvent){
this.transitionOptions=transitionOptions;
this.target = target;
this.triggerEvent=triggerEvent||null;
},
dispatch: function(){
var opts = {bubbles:true, cancelable:true, detail: this.transitionOptions, triggerEvent: this.triggerEvent};
//console.log("Target: ", this.target, " opts: ", opts);
var evt = on.emit(this.target,"startTransition", opts);
//console.log('evt: ', evt);
if(evt){
Deferred.when(transitDeferred, lang.hitch(this, function(transition){
Deferred.when(transition.call(this, evt), lang.hitch(this, function(results){
this.endTransition(results);
}));
}));
}
},
endTransition: function(results){
on.emit(this.target, "endTransition" , {detail: results.transitionOptions});
}
});
});
},
'dojox/mobile/ViewController':function(){
define([
"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
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;
});
},
'dojox/mobile/ToolBarButton':function(){
define("dojox/mobile/ToolBarButton", [
"dojo/_base/declare",
"dojo/_base/window",
"dojo/dom-class",
"dojo/dom-construct",
"dojo/dom-style",
"./common",
"./_ItemBase"
], function(declare, win, domClass, domConstruct, domStyle, common, ItemBase){
/*=====
var ItemBase = dojox.mobile._ItemBase;
=====*/
// module:
// dojox/mobile/ToolBarButton
// summary:
// A button widget that is placed in the Heading widget.
return declare("dojox.mobile.ToolBarButton", ItemBase, {
// summary:
// A button widget that is placed in the Heading widget.
// description:
// ToolBarButton is a button that is placed in the Heading
// widget. It is a subclass of dojox.mobile._ItemBase just like
// ListItem or IconItem. So, unlike Button, it has basically the
// same capability as ListItem or IconItem, such as icon support,
// transition, etc.
// selected: Boolean
// If true, the button is in the selected status.
selected: false,
// btnClass: String
// Deprecated.
btnClass: "",
/* internal properties */
_defaultColor: "mblColorDefault",
_selColor: "mblColorDefaultSel",
buildRendering: function(){
this.domNode = this.containerNode = this.srcNodeRef || win.doc.createElement("div");
this.inheritParams();
domClass.add(this.domNode, "mblToolBarButton mblArrowButtonText");
var color;
if(this.selected){
color = this._selColor;
}else if(this.domNode.className.indexOf("mblColor") == -1){
color = this._defaultColor;
}
domClass.add(this.domNode, color);
if(!this.label){
this.label = this.domNode.innerHTML;
}
if(this.icon && this.icon != "none"){
this.iconNode = domConstruct.create("div", {className:"mblToolBarButtonIcon"}, this.domNode);
common.createIcon(this.icon, this.iconPos, null, this.alt, this.iconNode);
if(this.iconPos){
domClass.add(this.iconNode.firstChild, "mblToolBarButtonSpriteIcon");
}
}else{
if(common.createDomButton(this.domNode)){
domClass.add(this.domNode, "mblToolBarButtonDomButton");
}else{
domClass.add(this.domNode, "mblToolBarButtonText");
}
}
this.connect(this.domNode, "onclick", "onClick");
},
select: function(){
// summary:
// Makes this widget in the selected state.
domClass.toggle(this.domNode, this._selColor, !arguments[0]);
this.selected = !arguments[0];
},
deselect: function(){
// summary:
// Makes this widget in the deselected state.
this.select(true);
},
onClick: function(e){
this.setTransitionPos(e);
this.defaultClickAction();
},
_setBtnClassAttr: function(/*String*/btnClass){
var node = this.domNode;
if(node.className.match(/(mblDomButton\w+)/)){
domClass.remove(node, RegExp.$1);
}
domClass.add(node, btnClass);
if(common.createDomButton(this.domNode)){
domClass.add(this.domNode, "mblToolBarButtonDomButton");
}
},
_setLabelAttr: function(/*String*/text){
this.label = text;
this.domNode.innerHTML = this._cv ? this._cv(text) : text;
}
});
});
},
'dojox/mobile/_ItemBase':function(){
define("dojox/mobile/_ItemBase", [
"dojo/_base/kernel",
"dojo/_base/config",
"dojo/_base/declare",
"dijit/registry", // registry.getEnclosingWidget
"dijit/_Contained",
"dijit/_Container",
"dijit/_WidgetBase",
"./TransitionEvent",
"./View"
], function(kernel, config, declare, registry, Contained, Container, WidgetBase, TransitionEvent, View){
/*=====
var Contained = dijit._Contained;
var Container = dijit._Container;
var WidgetBase = dijit._WidgetBase;
var TransitionEvent = dojox.mobile.TransitionEvent;
var View = dojox.mobile.View;
=====*/
// module:
// dojox/mobile/_ItemBase
// summary:
// A base class for item classes (e.g. ListItem, IconItem, etc.)
return declare("dojox.mobile._ItemBase", [WidgetBase, Container, Contained],{
// summary:
// A base class for item classes (e.g. ListItem, IconItem, etc.)
// description:
// _ItemBase is a base class for widgets that have capability to
// make a view transition when clicked.
// icon: String
// An icon image to display. The value can be either a path for an
// image file or a class name of a DOM button. If icon is not
// specified, the iconBase parameter of the parent widget is used.
icon: "",
// iconPos: String
// The position of an aggregated icon. IconPos is comma separated
// values like top,left,width,height (ex. "0,0,29,29"). If iconPos
// is not specified, the iconPos parameter of the parent widget is
// used.
iconPos: "", // top,left,width,height (ex. "0,0,29,29")
// alt: String
// An alt text for the icon image.
alt: "",
// href: String
// A URL of another web page to go to.
href: "",
// hrefTarget: String
// A target that specifies where to open a page specified by
// href. The value will be passed to the 2nd argument of
// window.open().
hrefTarget: "",
// 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.
moveTo: "",
// scene: String
// The name of a scene. Used from dojox.mobile.app.
scene: "",
// clickable: Boolean
// If true, this item becomes clickable even if a transition
// destination (moveTo, etc.) is not specified.
clickable: false,
// url: String
// A URL of an html fragment page or JSON data that represents a
// new view content. The view content is loaded with XHR and
// inserted in the current page. Then a view transition occurs to
// the newly created view. The view is cached so that subsequent
// requests would not load the content again.
url: "",
// urlTarget: String
// Node id under which a new view will be created according to the
// url parameter. If not specified, The new view will be created as
// a sibling of the current view.
urlTarget: "",
// 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.
transition: "",
// transitionDir: 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.
transitionDir: 1,
// transitionOptions: Object
// A hash object that holds transition options.
transitionOptions: null,
// callback: Function|String
// A callback function that is called when the transition has been
// finished. A function reference, or name of a function in
// context.
callback: null,
// sync: Boolean
// If true, XHR for the view content specified with the url
// parameter is performed synchronously. If false, it is done
// asynchronously and the progress indicator is displayed while
// loading the content. This parameter is effective only when the
// url parameter is used.
sync: true,
// label: String
// A label of the item. If the label is not specified, innerHTML is
// used as a label.
label: "",
// toggle: Boolean
// If true, the item acts like a toggle button.
toggle: false,
// _duration: Number
// Duration of selection, milliseconds.
_duration: 800,
inheritParams: function(){
var parent = this.getParent();
if(parent){
if(!this.transition){ this.transition = parent.transition; }
if(this.icon && parent.iconBase &&
parent.iconBase.charAt(parent.iconBase.length - 1) === '/'){
this.icon = parent.iconBase + this.icon;
}
if(!this.icon){ this.icon = parent.iconBase; }
if(!this.iconPos){ this.iconPos = parent.iconPos; }
}
},
select: function(){
// summary:
// Makes this widget in the selected state.
// description:
// Subclass must implement.
},
deselect: function(){
// summary:
// Makes this widget in the deselected state.
// description:
// Subclass must implement.
},
defaultClickAction: function(e){
if(this.toggle){
if(this.selected){
this.deselect();
}else{
this.select();
}
}else if(!this.selected){
this.select();
if(!this.selectOne){
var _this = this;
setTimeout(function(){
_this.deselect();
}, this._duration);
}
var transOpts;
if(this.moveTo || this.href || this.url || this.scene){
transOpts = {moveTo: this.moveTo, href: this.href, url: this.url, scene: this.scene, transition: this.transition, transitionDir: this.transitionDir};
}else if(this.transitionOptions){
transOpts = this.transitionOptions;
}
if(transOpts){
return new TransitionEvent(this.domNode,transOpts,e).dispatch();
}
}
},
getParent: function(){
// summary:
// Gets the parent widget.
// description:
// Almost equivalent to _Contained#getParent, but this method
// does not cause a script error even if this widget has no
// parent yet.
var ref = this.srcNodeRef || this.domNode;
return ref && ref.parentNode ? registry.getEnclosingWidget(ref.parentNode) : null;
},
setTransitionPos: function(e){
// summary:
// Stores the clicked position for later use.
// description:
// Some of the transition animations (e.g. ScaleIn) needs the
// clicked position.
var w = this;
while(true){
w = w.getParent();
if(!w || w instanceof View){ break; }
}
if(w){
w.clickedPosX = e.clientX;
w.clickedPosY = e.clientY;
}
},
transitionTo: function(moveTo, href, url, scene){
// summary:
// Performs a view transition.
// description:
// Given a transition destination, this method performs a view
// transition. This method is typically called when this item
// is clicked.
if(config.isDebug){
var alreadyCalledHash = arguments.callee._ach || (arguments.callee._ach = {}),
caller = (arguments.callee.caller || "unknown caller").toString();
if(!alreadyCalledHash[caller]){
kernel.deprecated(this.declaredClass + "::transitionTo() is deprecated." +
caller, "", "2.0");
alreadyCalledHash[caller] = true;
}
}
new TransitionEvent(this.domNode, {moveTo: moveTo, href: href, url: url, scene: scene,
transition: this.transition, transitionDir: this.transitionDir}).dispatch();
}
});
});
},
'dijit/hccss':function(){
define("dijit/hccss", [
"require", // require.toUrl
"dojo/_base/config", // config.blankGif
"dojo/dom-class", // domClass.add domConstruct.create domStyle.getComputedStyle
"dojo/dom-construct", // domClass.add domConstruct.create domStyle.getComputedStyle
"dojo/dom-style", // domClass.add domConstruct.create domStyle.getComputedStyle
"dojo/ready", // ready
"dojo/_base/sniff", // has("ie") has("mozilla")
"dojo/_base/window" // win.body
], function(require, config, domClass, domConstruct, domStyle, ready, has, win){
// module:
// dijit/hccss
// summary:
// Test if computer is in high contrast mode, and sets dijit_a11y flag on if it is.
if(has("ie") || has("mozilla")){ // NOTE: checking in Safari messes things up
// priority is 90 to run ahead of parser priority of 100
ready(90, function(){
// summary:
// Detects if we are in high-contrast mode or not
// create div for testing if high contrast mode is on or images are turned off
var div = domConstruct.create("div",{
id: "a11yTestNode",
style:{
cssText:'border: 1px solid;'
+ 'border-color:red green;'
+ 'position: absolute;'
+ 'height: 5px;'
+ 'top: -999px;'
+ 'background-image: url("' + (config.blankGif || require.toUrl("dojo/resources/blank.gif")) + '");'
}
}, win.body());
// test it
var cs = domStyle.getComputedStyle(div);
if(cs){
var bkImg = cs.backgroundImage;
var needsA11y = (cs.borderTopColor == cs.borderRightColor) || (bkImg != null && (bkImg == "none" || bkImg == "url(invalid-url:)" ));
if(needsA11y){
domClass.add(win.body(), "dijit_a11y");
}
if(has("ie")){
div.outerHTML = ""; // prevent mixed-content warning, see http://support.microsoft.com/kb/925014
}else{
win.body().removeChild(div);
}
}
});
}
});
},
'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/form/_TextBoxMixin':function(){
define("dijit/form/_TextBoxMixin", [
"dojo/_base/array", // array.forEach
"dojo/_base/declare", // declare
"dojo/dom", // dom.byId
"dojo/_base/event", // event.stop
"dojo/keys", // keys.ALT keys.CAPS_LOCK keys.CTRL keys.META keys.SHIFT
"dojo/_base/lang", // lang.mixin
".." // for exporting dijit._setSelectionRange, dijit.selectInputText
], function(array, declare, dom, event, keys, lang, dijit){
// module:
// dijit/form/_TextBoxMixin
// summary:
// A mixin for textbox form input widgets
var _TextBoxMixin = declare("dijit.form._TextBoxMixin", null, {
// summary:
// A mixin for textbox form input widgets
// trim: Boolean
// Removes leading and trailing whitespace if true. Default is false.
trim: false,
// uppercase: Boolean
// Converts all characters to uppercase if true. Default is false.
uppercase: false,
// lowercase: Boolean
// Converts all characters to lowercase if true. Default is false.
lowercase: false,
// propercase: Boolean
// Converts the first character of each word to uppercase if true.
propercase: false,
// maxLength: String
// HTML INPUT tag maxLength declaration.
maxLength: "",
// selectOnClick: [const] Boolean
// If true, all text will be selected when focused with mouse
selectOnClick: false,
// placeHolder: String
// Defines a hint to help users fill out the input field (as defined in HTML 5).
// This should only contain plain text (no html markup).
placeHolder: "",
_getValueAttr: function(){
// summary:
// Hook so get('value') works as we like.
// description:
// For `dijit.form.TextBox` this basically returns the value of the .
//
// For `dijit.form.MappedTextBox` subclasses, which have both
// a "displayed value" and a separate "submit value",
// This treats the "displayed value" as the master value, computing the
// submit value from it via this.parse().
return this.parse(this.get('displayedValue'), this.constraints);
},
_setValueAttr: function(value, /*Boolean?*/ priorityChange, /*String?*/ formattedValue){
// summary:
// Hook so set('value', ...) works.
//
// description:
// Sets the value of the widget to "value" which can be of
// any type as determined by the widget.
//
// value:
// The visual element value is also set to a corresponding,
// but not necessarily the same, value.
//
// formattedValue:
// If specified, used to set the visual element value,
// otherwise a computed visual value is used.
//
// priorityChange:
// If true, an onChange event is fired immediately instead of
// waiting for the next blur event.
var filteredValue;
if(value !== undefined){
// TODO: this is calling filter() on both the display value and the actual value.
// I added a comment to the filter() definition about this, but it should be changed.
filteredValue = this.filter(value);
if(typeof formattedValue != "string"){
if(filteredValue !== null && ((typeof filteredValue != "number") || !isNaN(filteredValue))){
formattedValue = this.filter(this.format(filteredValue, this.constraints));
}else{ formattedValue = ''; }
}
}
if(formattedValue != null && formattedValue != undefined && ((typeof formattedValue) != "number" || !isNaN(formattedValue)) && this.textbox.value != formattedValue){
this.textbox.value = formattedValue;
this._set("displayedValue", this.get("displayedValue"));
}
if(this.textDir == "auto"){
this.applyTextDir(this.focusNode, formattedValue);
}
this.inherited(arguments, [filteredValue, priorityChange]);
},
// displayedValue: String
// For subclasses like ComboBox where the displayed value
// (ex: Kentucky) and the serialized value (ex: KY) are different,
// this represents the displayed value.
//
// Setting 'displayedValue' through set('displayedValue', ...)
// updates 'value', and vice-versa. Otherwise 'value' is updated
// from 'displayedValue' periodically, like onBlur etc.
//
// TODO: move declaration to MappedTextBox?
// Problem is that ComboBox references displayedValue,
// for benefit of FilteringSelect.
displayedValue: "",
_getDisplayedValueAttr: function(){
// summary:
// Hook so get('displayedValue') works.
// description:
// Returns the displayed value (what the user sees on the screen),
// after filtering (ie, trimming spaces etc.).
//
// For some subclasses of TextBox (like ComboBox), the displayed value
// is different from the serialized value that's actually
// sent to the server (see dijit.form.ValidationTextBox.serialize)
// TODO: maybe we should update this.displayedValue on every keystroke so that we don't need
// this method
// TODO: this isn't really the displayed value when the user is typing
return this.filter(this.textbox.value);
},
_setDisplayedValueAttr: function(/*String*/ value){
// summary:
// Hook so set('displayedValue', ...) works.
// description:
// Sets the value of the visual element to the string "value".
// The widget value is also set to a corresponding,
// but not necessarily the same, value.
if(value === null || value === undefined){ value = '' }
else if(typeof value != "string"){ value = String(value) }
this.textbox.value = value;
// sets the serialized value to something corresponding to specified displayedValue
// (if possible), and also updates the textbox.value, for example converting "123"
// to "123.00"
this._setValueAttr(this.get('value'), undefined);
this._set("displayedValue", this.get('displayedValue'));
// textDir support
if(this.textDir == "auto"){
this.applyTextDir(this.focusNode, value);
}
},
format: function(value /*=====, constraints =====*/){
// summary:
// Replaceable function to convert a value to a properly formatted string.
// value: String
// constraints: Object
// tags:
// protected extension
return ((value == null || value == undefined) ? "" : (value.toString ? value.toString() : value));
},
parse: function(value /*=====, constraints =====*/){
// summary:
// Replaceable function to convert a formatted string to a value
// value: String
// constraints: Object
// tags:
// protected extension
return value; // String
},
_refreshState: function(){
// summary:
// After the user types some characters, etc., this method is
// called to check the field for validity etc. The base method
// in `dijit.form.TextBox` does nothing, but subclasses override.
// tags:
// protected
},
/*=====
onInput: function(event){
// summary:
// Connect to this function to receive notifications of various user data-input events.
// Return false to cancel the event and prevent it from being processed.
// event:
// keydown | keypress | cut | paste | input
// tags:
// callback
},
=====*/
onInput: function(){},
__skipInputEvent: false,
_onInput: function(){
// summary:
// Called AFTER the input event has happened
// set text direction according to textDir that was defined in creation
if(this.textDir == "auto"){
this.applyTextDir(this.focusNode, this.focusNode.value);
}
this._refreshState();
// In case someone is watch()'ing for changes to displayedValue
this._set("displayedValue", this.get("displayedValue"));
},
postCreate: function(){
// setting the value here is needed since value="" in the template causes "undefined"
// and setting in the DOM (instead of the JS object) helps with form reset actions
this.textbox.setAttribute("value", this.textbox.value); // DOM and JS values should be the same
this.inherited(arguments);
// normalize input events to reduce spurious event processing
// onkeydown: do not forward modifier keys
// set charOrCode to numeric keycode
// onkeypress: do not forward numeric charOrCode keys (already sent through onkeydown)
// onpaste & oncut: set charOrCode to 229 (IME)
// oninput: if primary event not already processed, set charOrCode to 229 (IME), else do not forward
var handleEvent = function(e){
var charCode = e.charOrCode || e.keyCode || 229;
if(e.type == "keydown"){
switch(charCode){ // ignore "state" keys
case keys.SHIFT:
case keys.ALT:
case keys.CTRL:
case keys.META:
case keys.CAPS_LOCK:
return;
default:
if(charCode >= 65 && charCode <= 90){ return; } // keydown for A-Z can be processed with keypress
}
}
if(e.type == "keypress" && typeof charCode != "string"){ return; }
if(e.type == "input"){
if(this.__skipInputEvent){ // duplicate event
this.__skipInputEvent = false;
return;
}
}else{
this.__skipInputEvent = true;
}
// create fake event to set charOrCode and to know if preventDefault() was called
var faux = lang.mixin({}, e, {
charOrCode: charCode,
wasConsumed: false,
preventDefault: function(){
faux.wasConsumed = true;
e.preventDefault();
},
stopPropagation: function(){ e.stopPropagation(); }
});
// give web page author a chance to consume the event
if(this.onInput(faux) === false){
event.stop(faux); // return false means stop
}
if(faux.wasConsumed){ return; } // if preventDefault was called
setTimeout(lang.hitch(this, "_onInput", faux), 0); // widget notification after key has posted
};
array.forEach([ "onkeydown", "onkeypress", "onpaste", "oncut", "oninput" ], function(event){
this.connect(this.textbox, event, handleEvent);
}, this);
},
_blankValue: '', // if the textbox is blank, what value should be reported
filter: function(val){
// summary:
// Auto-corrections (such as trimming) that are applied to textbox
// value on blur or form submit.
// description:
// For MappedTextBox subclasses, this is called twice
// - once with the display value
// - once the value as set/returned by set('value', ...)
// and get('value'), ex: a Number for NumberTextBox.
//
// In the latter case it does corrections like converting null to NaN. In
// the former case the NumberTextBox.filter() method calls this.inherited()
// to execute standard trimming code in TextBox.filter().
//
// TODO: break this into two methods in 2.0
//
// tags:
// protected extension
if(val === null){ return this._blankValue; }
if(typeof val != "string"){ return val; }
if(this.trim){
val = lang.trim(val);
}
if(this.uppercase){
val = val.toUpperCase();
}
if(this.lowercase){
val = val.toLowerCase();
}
if(this.propercase){
val = val.replace(/[^\s]+/g, function(word){
return word.substring(0,1).toUpperCase() + word.substring(1);
});
}
return val;
},
_setBlurValue: function(){
this._setValueAttr(this.get('value'), true);
},
_onBlur: function(e){
if(this.disabled){ return; }
this._setBlurValue();
this.inherited(arguments);
if(this._selectOnClickHandle){
this.disconnect(this._selectOnClickHandle);
}
},
_isTextSelected: function(){
return this.textbox.selectionStart == this.textbox.selectionEnd;
},
_onFocus: function(/*String*/ by){
if(this.disabled || this.readOnly){ return; }
// Select all text on focus via click if nothing already selected.
// Since mouse-up will clear the selection need to defer selection until after mouse-up.
// Don't do anything on focus by tabbing into the widget since there's no associated mouse-up event.
if(this.selectOnClick && by == "mouse"){
this._selectOnClickHandle = this.connect(this.domNode, "onmouseup", function(){
// Only select all text on first click; otherwise users would have no way to clear
// the selection.
this.disconnect(this._selectOnClickHandle);
// Check if the user selected some text manually (mouse-down, mouse-move, mouse-up)
// and if not, then select all the text
if(this._isTextSelected()){
_TextBoxMixin.selectInputText(this.textbox);
}
});
}
// call this.inherited() before refreshState(), since this.inherited() will possibly scroll the viewport
// (to scroll the TextBox into view), which will affect how _refreshState() positions the tooltip
this.inherited(arguments);
this._refreshState();
},
reset: function(){
// Overrides dijit._FormWidget.reset().
// Additionally resets the displayed textbox value to ''
this.textbox.value = '';
this.inherited(arguments);
},
_setTextDirAttr: function(/*String*/ textDir){
// summary:
// Setter for textDir.
// description:
// Users shouldn't call this function; they should be calling
// set('textDir', value)
// tags:
// private
// only if new textDir is different from the old one
// and on widgets creation.
if(!this._created
|| this.textDir != textDir){
this._set("textDir", textDir);
// so the change of the textDir will take place immediately.
this.applyTextDir(this.focusNode, this.focusNode.value);
}
}
});
_TextBoxMixin._setSelectionRange = dijit._setSelectionRange = function(/*DomNode*/ element, /*Number?*/ start, /*Number?*/ stop){
if(element.setSelectionRange){
element.setSelectionRange(start, stop);
}
};
_TextBoxMixin.selectInputText = dijit.selectInputText = function(/*DomNode*/ element, /*Number?*/ start, /*Number?*/ stop){
// summary:
// Select text in the input element argument, from start (default 0), to stop (default end).
// TODO: use functions in _editor/selection.js?
element = dom.byId(element);
if(isNaN(start)){ start = 0; }
if(isNaN(stop)){ stop = element.value ? element.value.length : 0; }
try{
element.focus();
_TextBoxMixin._setSelectionRange(element, start, stop);
}catch(e){ /* squelch random errors (esp. on IE) from unexpected focus changes or DOM nodes being hidden */ }
};
return _TextBoxMixin;
});
},
'dojox/mobile/parser':function(){
define([
"dojo/_base/kernel",
"dojo/_base/config",
"dojo/_base/lang",
"dojo/_base/window",
"dojo/ready"
], function(dojo, config, lang, win, ready){
// module:
// dojox/mobile/parser
// summary:
// A lightweight parser.
var dm = lang.getObject("dojox.mobile", true);
var parser = new function(){
// summary:
// A lightweight parser.
// description:
// dojox.mobile.parser is an extremely small subset of
// dojo.parser. It has no extended features over dojo.parser, so
// there is no reason you have to use dojox.mobile.parser instead
// of dojo.parser. However, if dojox.mobile.parser's capability is
// enough for your application, use of it could reduce the total
// code size.
this.instantiate = function(/* Array */nodes, /* Object? */mixin, /* Object? */args){
// summary:
// Function for instantiating a list of widget nodes.
// nodes:
// The list of DOMNodes to walk and instantiate widgets on.
mixin = mixin || {};
args = args || {};
var i, ws = [];
if(nodes){
for(i = 0; i < nodes.length; i++){
var n = nodes[i];
var cls = lang.getObject(n.getAttribute("dojoType") || n.getAttribute("data-dojo-type"));
var proto = cls.prototype;
var params = {}, prop, v, t;
lang.mixin(params, eval('({'+(n.getAttribute("data-dojo-props")||"")+'})'));
lang.mixin(params, args.defaults);
lang.mixin(params, mixin);
for(prop in proto){
v = n.getAttributeNode(prop);
v = v && v.nodeValue;
t = typeof proto[prop];
if(!v && (t !== "boolean" || v !== "")){ continue; }
if(t === "string"){
params[prop] = v;
}else if(t === "number"){
params[prop] = v - 0;
}else if(t === "boolean"){
params[prop] = (v !== "false");
}else if(t === "object"){
params[prop] = eval("(" + v + ")");
}
}
params["class"] = n.className;
params.style = n.style && n.style.cssText;
v = n.getAttribute("data-dojo-attach-point");
if(v){ params.dojoAttachPoint = v; }
v = n.getAttribute("data-dojo-attach-event");
if(v){ params.dojoAttachEvent = v; }
var instance = new cls(params, n);
ws.push(instance);
var jsId = n.getAttribute("jsId") || n.getAttribute("data-dojo-id");
if(jsId){
lang.setObject(jsId, instance);
}
}
for(i = 0; i < ws.length; i++){
var w = ws[i];
!args.noStart && w.startup && !w._started && w.startup();
}
}
return ws;
};
this.parse = function(rootNode, args){
// summary:
// Function to handle parsing for widgets in the current document.
// It is not as powerful as the full parser, but it will handle basic
// use cases fine.
// rootNode:
// The root node in the document to parse from
if(!rootNode){
rootNode = win.body();
}else if(!args && rootNode.rootNode){
// Case where 'rootNode' is really a params object.
args = rootNode;
rootNode = rootNode.rootNode;
}
var nodes = rootNode.getElementsByTagName("*");
var i, list = [];
for(i = 0; i < nodes.length; i++){
var n = nodes[i];
if(n.getAttribute("dojoType") || n.getAttribute("data-dojo-type")){
list.push(n);
}
}
var mixin = args && args.template ? {template: true} : null;
return this.instantiate(list, mixin, args);
};
}();
if(config.parseOnLoad){
ready(100, parser, "parse");
}
dm.parser = parser; // for backward compatibility
dojo.parser = parser; // in case user application calls dojo.parser
return parser;
});
},
'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
}
});
});
},
'dojox/mobile/app/SceneController':function(){
// wrapped by build app
define(["dijit","dojo","dojox","dojo/require!dojox/mobile/_base"], function(dijit,dojo,dojox){
dojo.provide("dojox.mobile.app.SceneController");
dojo.experimental("dojox.mobile.app.SceneController");
dojo.require("dojox.mobile._base");
(function(){
var app = dojox.mobile.app;
var templates = {};
dojo.declare("dojox.mobile.app.SceneController", dojox.mobile.View, {
stageController: null,
keepScrollPos: false,
init: function(sceneName, params){
// summary:
// Initializes the scene by loading the HTML template and code, if it has
// not already been loaded
this.sceneName = sceneName;
this.params = params;
var templateUrl = app.resolveTemplate(sceneName);
this._deferredInit = new dojo.Deferred();
if(templates[sceneName]){
// If the template has been cached, do not load it again.
this._setContents(templates[sceneName]);
}else{
// Otherwise load the template
dojo.xhrGet({
url: templateUrl,
handleAs: "text"
}).addCallback(dojo.hitch(this, this._setContents));
}
return this._deferredInit;
},
_setContents: function(templateHtml){
// summary:
// Sets the content of the View, and invokes either the loading or
// initialization of the scene assistant.
templates[this.sceneName] = templateHtml;
this.domNode.innerHTML = "
" + templateHtml + "
";
var sceneAssistantName = "";
var nameParts = this.sceneName.split("-");
for(var i = 0; i < nameParts.length; i++){
sceneAssistantName += nameParts[i].substring(0, 1).toUpperCase()
+ nameParts[i].substring(1);
}
sceneAssistantName += "Assistant";
this.sceneAssistantName = sceneAssistantName;
var _this = this;
dojox.mobile.app.loadResourcesForScene(this.sceneName, function(){
console.log("All resources for ",_this.sceneName," loaded");
var assistant;
if(typeof(dojo.global[sceneAssistantName]) != "undefined"){
_this._initAssistant();
}else{
var assistantUrl = app.resolveAssistant(_this.sceneName);
dojo.xhrGet({
url: assistantUrl,
handleAs: "text"
}).addCallback(function(text){
try{
dojo.eval(text);
}catch(e){
console.log("Error initializing code for scene " + _this.sceneName
+ '. Please check for syntax errors');
throw e;
}
_this._initAssistant();
});
}
});
},
_initAssistant: function(){
// summary:
// Initializes the scene assistant. At this point, the View is
// populated with the HTML template, and the scene assistant type
// is declared.
console.log("Instantiating the scene assistant " + this.sceneAssistantName);
var cls = dojo.getObject(this.sceneAssistantName);
if(!cls){
throw Error("Unable to resolve scene assistant "
+ this.sceneAssistantName);
}
this.assistant = new cls(this.params);
this.assistant.controller = this;
this.assistant.domNode = this.domNode.firstChild;
this.assistant.setup();
this._deferredInit.callback();
},
query: function(selector, node){
// summary:
// Queries for DOM nodes within either the node passed in as an argument
// or within this view.
return dojo.query(selector, node || this.domNode)
},
parse: function(node){
var widgets = this._widgets =
dojox.mobile.parser.parse(node || this.domNode, {
controller: this
});
// Tell all widgets what their controller is.
for(var i = 0; i < widgets.length; i++){
widgets[i].set("controller", this);
}
},
getWindowSize: function(){
// TODO, this needs cross browser testing
return {
w: dojo.global.innerWidth,
h: dojo.global.innerHeight
}
},
showAlertDialog: function(props){
var size = dojo.marginBox(this.assistant.domNode);
var dialog = new dojox.mobile.app.AlertDialog(
dojo.mixin(props, {controller: this}));
this.assistant.domNode.appendChild(dialog.domNode);
console.log("Appended " , dialog.domNode, " to ", this.assistant.domNode);
dialog.show();
},
popupSubMenu: function(info){
var widget = new dojox.mobile.app.ListSelector({
controller: this,
destroyOnHide: true,
onChoose: info.onChoose
});
this.assistant.domNode.appendChild(widget.domNode);
widget.set("data", info.choices);
widget.show(info.fromNode);
}
});
})();
});
},
'dojox/mobile/app/_base':function(){
// wrapped by build app
define(["dijit","dojo","dojox","dojo/require!dijit/_base,dijit/_WidgetBase,dojox/mobile,dojox/mobile/parser,dojox/mobile/Button,dojox/mobile/app/_event,dojox/mobile/app/_Widget,dojox/mobile/app/StageController,dojox/mobile/app/SceneController,dojox/mobile/app/SceneAssistant,dojox/mobile/app/AlertDialog,dojox/mobile/app/List,dojox/mobile/app/ListSelector,dojox/mobile/app/TextBox,dojox/mobile/app/ImageView,dojox/mobile/app/ImageThumbView"], function(dijit,dojo,dojox){
dojo.provide("dojox.mobile.app._base");
dojo.experimental("dojox.mobile.app._base");
dojo.require("dijit._base");
dojo.require("dijit._WidgetBase");
dojo.require("dojox.mobile");
dojo.require("dojox.mobile.parser");
dojo.require("dojox.mobile.Button");
dojo.require("dojox.mobile.app._event");
dojo.require("dojox.mobile.app._Widget");
dojo.require("dojox.mobile.app.StageController");
dojo.require("dojox.mobile.app.SceneController");
dojo.require("dojox.mobile.app.SceneAssistant");
dojo.require("dojox.mobile.app.AlertDialog");
dojo.require("dojox.mobile.app.List");
dojo.require("dojox.mobile.app.ListSelector");
dojo.require("dojox.mobile.app.TextBox");
dojo.require("dojox.mobile.app.ImageView");
dojo.require("dojox.mobile.app.ImageThumbView");
(function(){
var stageController;
var appInfo;
var jsDependencies = [
"dojox.mobile",
"dojox.mobile.parser"
];
var loadedResources = {};
var loadingDependencies;
var rootNode;
var sceneResources = [];
// Load the required resources asynchronously, since not all mobile OSes
// support dojo.require and sync XHR
function loadResources(resources, callback){
// summary:
// Loads one or more JavaScript files asynchronously. When complete,
// the first scene is pushed onto the stack.
// resources:
// An array of module names, e.g. 'dojox.mobile.AlertDialog'
var resource;
var url;
do {
resource = resources.pop();
if (resource.source) {
url = resource.source;
}else if (resource.module) {
url= dojo.moduleUrl(resource.module)+".js";
}else {
console.log("Error: invalid JavaScript resource " + dojo.toJson(resource));
return;
}
}while (resources.length > 0 && loadedResources[url]);
if(resources.length < 1 && loadedResources[url]){
// All resources have already been loaded
callback();
return;
}
dojo.xhrGet({
url: url,
sync: false
}).addCallbacks(function(text){
dojo["eval"](text);
loadedResources[url] = true;
if(resources.length > 0){
loadResources(resources, callback);
}else{
callback();
}
},
function(){
console.log("Failed to load resource " + url);
});
}
var pushFirstScene = function(){
// summary:
// Pushes the first scene onto the stack.
stageController = new dojox.mobile.app.StageController(rootNode);
var defaultInfo = {
id: "com.test.app",
version: "1.0.0",
initialScene: "main"
};
// If the application info has been defined, as it should be,
// use it.
if(dojo.global["appInfo"]){
dojo.mixin(defaultInfo, dojo.global["appInfo"]);
}
appInfo = dojox.mobile.app.info = defaultInfo;
// Set the document title from the app info title if it exists
if(appInfo.title){
var titleNode = dojo.query("head title")[0] ||
dojo.create("title", {},dojo.query("head")[0]);
document.title = appInfo.title;
}
stageController.pushScene(appInfo.initialScene);
};
var initBackButton = function(){
var hasNativeBack = false;
if(dojo.global.BackButton){
// Android phonegap support
BackButton.override();
dojo.connect(document, 'backKeyDown', function(e) {
dojo.publish("/dojox/mobile/app/goback");
});
hasNativeBack = true;
}else if(dojo.global.Mojo){
// TODO: add webOS support
}
if(hasNativeBack){
dojo.addClass(dojo.body(), "mblNativeBack");
}
};
dojo.mixin(dojox.mobile.app, {
init: function(node){
// summary:
// Initializes the mobile app. Creates the
rootNode = node || dojo.body();
dojox.mobile.app.STAGE_CONTROLLER_ACTIVE = true;
dojo.subscribe("/dojox/mobile/app/goback", function(){
stageController.popScene();
});
dojo.subscribe("/dojox/mobile/app/alert", function(params){
dojox.mobile.app.getActiveSceneController().showAlertDialog(params);
});
dojo.subscribe("/dojox/mobile/app/pushScene", function(sceneName, params){
stageController.pushScene(sceneName, params || {});
});
// Get the list of files to load per scene/view
dojo.xhrGet({
url: "view-resources.json",
load: function(data){
var resources = [];
if(data){
// Should be an array
sceneResources = data = dojo.fromJson(data);
// Get the list of files to load that have no scene
// specified, and therefore should be loaded on
// startup
for(var i = 0; i < data.length; i++){
if(!data[i].scene){
resources.push(data[i]);
}
}
}
if(resources.length > 0){
loadResources(resources, pushFirstScene);
}else{
pushFirstScene();
}
},
error: pushFirstScene
});
initBackButton();
},
getActiveSceneController: function(){
// summary:
// Gets the controller for the active scene.
return stageController.getActiveSceneController();
},
getStageController: function(){
// summary:
// Gets the stage controller.
return stageController;
},
loadResources: function(resources, callback){
loadResources(resources, callback);
},
loadResourcesForScene: function(sceneName, callback){
var resources = [];
// Get the list of files to load that have no scene
// specified, and therefore should be loaded on
// startup
for(var i = 0; i < sceneResources.length; i++){
if(sceneResources[i].scene == sceneName){
resources.push(sceneResources[i]);
}
}
if(resources.length > 0){
loadResources(resources, callback);
}else{
callback();
}
},
resolveTemplate: function(sceneName){
// summary:
// Given the name of a scene, returns the path to it's template
// file. For example, for a scene named 'main', the file
// returned is 'app/views/main/main-scene.html'
// This function can be overridden if it is desired to have
// a different name to file mapping.
return "app/views/" + sceneName + "/" + sceneName + "-scene.html";
},
resolveAssistant: function(sceneName){
// summary:
// Given the name of a scene, returns the path to it's assistant
// file. For example, for a scene named 'main', the file
// returned is 'app/assistants/main-assistant.js'
// This function can be overridden if it is desired to have
// a different name to file mapping.
return "app/assistants/" + sceneName + "-assistant.js";
}
});
})();
});
},
'dijit/_base/scroll':function(){
define("dijit/_base/scroll", [
"dojo/window", // windowUtils.scrollIntoView
".." // export symbol to dijit
], function(windowUtils, dijit){
// module:
// dijit/_base/scroll
// summary:
// Back compatibility module, new code should use windowUtils directly instead of using this module.
dijit.scrollIntoView = function(/*DomNode*/ node, /*Object?*/ pos){
// summary:
// Scroll the passed node into view, if it is not already.
// Deprecated, use `windowUtils.scrollIntoView` instead.
windowUtils.scrollIntoView(node, pos);
};
});
},
'dojo/fx':function(){
define([
"./_base/lang",
"./Evented",
"./_base/kernel",
"./_base/array",
"./_base/connect",
"./_base/fx",
"./dom",
"./dom-style",
"./dom-geometry",
"./ready",
"require" // for context sensitive loading of Toggler
], function(lang, Evented, dojo, arrayUtil, connect, baseFx, dom, domStyle, geom, ready, require) {
// module:
// dojo/fx
// summary:
// TODOC
/*=====
dojo.fx = {
// summary: Effects library on top of Base animations
};
var coreFx = dojo.fx;
=====*/
// For back-compat, remove in 2.0.
if(!dojo.isAsync){
ready(0, function(){
var requires = ["./fx/Toggler"];
require(requires); // use indirection so modules not rolled into a build
});
}
var coreFx = dojo.fx = {};
var _baseObj = {
_fire: function(evt, args){
if(this[evt]){
this[evt].apply(this, args||[]);
}
return this;
}
};
var _chain = function(animations){
this._index = -1;
this._animations = animations||[];
this._current = this._onAnimateCtx = this._onEndCtx = null;
this.duration = 0;
arrayUtil.forEach(this._animations, function(a){
this.duration += a.duration;
if(a.delay){ this.duration += a.delay; }
}, this);
};
_chain.prototype = new Evented();
lang.extend(_chain, {
_onAnimate: function(){
this._fire("onAnimate", arguments);
},
_onEnd: function(){
connect.disconnect(this._onAnimateCtx);
connect.disconnect(this._onEndCtx);
this._onAnimateCtx = this._onEndCtx = null;
if(this._index + 1 == this._animations.length){
this._fire("onEnd");
}else{
// switch animations
this._current = this._animations[++this._index];
this._onAnimateCtx = connect.connect(this._current, "onAnimate", this, "_onAnimate");
this._onEndCtx = connect.connect(this._current, "onEnd", this, "_onEnd");
this._current.play(0, true);
}
},
play: function(/*int?*/ delay, /*Boolean?*/ gotoStart){
if(!this._current){ this._current = this._animations[this._index = 0]; }
if(!gotoStart && this._current.status() == "playing"){ return this; }
var beforeBegin = connect.connect(this._current, "beforeBegin", this, function(){
this._fire("beforeBegin");
}),
onBegin = connect.connect(this._current, "onBegin", this, function(arg){
this._fire("onBegin", arguments);
}),
onPlay = connect.connect(this._current, "onPlay", this, function(arg){
this._fire("onPlay", arguments);
connect.disconnect(beforeBegin);
connect.disconnect(onBegin);
connect.disconnect(onPlay);
});
if(this._onAnimateCtx){
connect.disconnect(this._onAnimateCtx);
}
this._onAnimateCtx = connect.connect(this._current, "onAnimate", this, "_onAnimate");
if(this._onEndCtx){
connect.disconnect(this._onEndCtx);
}
this._onEndCtx = connect.connect(this._current, "onEnd", this, "_onEnd");
this._current.play.apply(this._current, arguments);
return this;
},
pause: function(){
if(this._current){
var e = connect.connect(this._current, "onPause", this, function(arg){
this._fire("onPause", arguments);
connect.disconnect(e);
});
this._current.pause();
}
return this;
},
gotoPercent: function(/*Decimal*/percent, /*Boolean?*/ andPlay){
this.pause();
var offset = this.duration * percent;
this._current = null;
arrayUtil.some(this._animations, function(a){
if(a.duration <= offset){
this._current = a;
return true;
}
offset -= a.duration;
return false;
});
if(this._current){
this._current.gotoPercent(offset / this._current.duration, andPlay);
}
return this;
},
stop: function(/*boolean?*/ gotoEnd){
if(this._current){
if(gotoEnd){
for(; this._index + 1 < this._animations.length; ++this._index){
this._animations[this._index].stop(true);
}
this._current = this._animations[this._index];
}
var e = connect.connect(this._current, "onStop", this, function(arg){
this._fire("onStop", arguments);
connect.disconnect(e);
});
this._current.stop();
}
return this;
},
status: function(){
return this._current ? this._current.status() : "stopped";
},
destroy: function(){
if(this._onAnimateCtx){ connect.disconnect(this._onAnimateCtx); }
if(this._onEndCtx){ connect.disconnect(this._onEndCtx); }
}
});
lang.extend(_chain, _baseObj);
coreFx.chain = /*===== dojo.fx.chain = =====*/ function(/*dojo.Animation[]*/ animations){
// summary:
// Chain a list of `dojo.Animation`s to run in sequence
//
// description:
// Return a `dojo.Animation` which will play all passed
// `dojo.Animation` instances in sequence, firing its own
// synthesized events simulating a single animation. (eg:
// onEnd of this animation means the end of the chain,
// not the individual animations within)
//
// example:
// Once `node` is faded out, fade in `otherNode`
// | dojo.fx.chain([
// | dojo.fadeIn({ node:node }),
// | dojo.fadeOut({ node:otherNode })
// | ]).play();
//
return new _chain(animations); // dojo.Animation
};
var _combine = function(animations){
this._animations = animations||[];
this._connects = [];
this._finished = 0;
this.duration = 0;
arrayUtil.forEach(animations, function(a){
var duration = a.duration;
if(a.delay){ duration += a.delay; }
if(this.duration < duration){ this.duration = duration; }
this._connects.push(connect.connect(a, "onEnd", this, "_onEnd"));
}, this);
this._pseudoAnimation = new baseFx.Animation({curve: [0, 1], duration: this.duration});
var self = this;
arrayUtil.forEach(["beforeBegin", "onBegin", "onPlay", "onAnimate", "onPause", "onStop", "onEnd"],
function(evt){
self._connects.push(connect.connect(self._pseudoAnimation, evt,
function(){ self._fire(evt, arguments); }
));
}
);
};
lang.extend(_combine, {
_doAction: function(action, args){
arrayUtil.forEach(this._animations, function(a){
a[action].apply(a, args);
});
return this;
},
_onEnd: function(){
if(++this._finished > this._animations.length){
this._fire("onEnd");
}
},
_call: function(action, args){
var t = this._pseudoAnimation;
t[action].apply(t, args);
},
play: function(/*int?*/ delay, /*Boolean?*/ gotoStart){
this._finished = 0;
this._doAction("play", arguments);
this._call("play", arguments);
return this;
},
pause: function(){
this._doAction("pause", arguments);
this._call("pause", arguments);
return this;
},
gotoPercent: function(/*Decimal*/percent, /*Boolean?*/ andPlay){
var ms = this.duration * percent;
arrayUtil.forEach(this._animations, function(a){
a.gotoPercent(a.duration < ms ? 1 : (ms / a.duration), andPlay);
});
this._call("gotoPercent", arguments);
return this;
},
stop: function(/*boolean?*/ gotoEnd){
this._doAction("stop", arguments);
this._call("stop", arguments);
return this;
},
status: function(){
return this._pseudoAnimation.status();
},
destroy: function(){
arrayUtil.forEach(this._connects, connect.disconnect);
}
});
lang.extend(_combine, _baseObj);
coreFx.combine = /*===== dojo.fx.combine = =====*/ function(/*dojo.Animation[]*/ animations){
// summary:
// Combine a list of `dojo.Animation`s to run in parallel
//
// description:
// Combine an array of `dojo.Animation`s to run in parallel,
// providing a new `dojo.Animation` instance encompasing each
// animation, firing standard animation events.
//
// example:
// Fade out `node` while fading in `otherNode` simultaneously
// | dojo.fx.combine([
// | dojo.fadeIn({ node:node }),
// | dojo.fadeOut({ node:otherNode })
// | ]).play();
//
// example:
// When the longest animation ends, execute a function:
// | var anim = dojo.fx.combine([
// | dojo.fadeIn({ node: n, duration:700 }),
// | dojo.fadeOut({ node: otherNode, duration: 300 })
// | ]);
// | dojo.connect(anim, "onEnd", function(){
// | // overall animation is done.
// | });
// | anim.play(); // play the animation
//
return new _combine(animations); // dojo.Animation
};
coreFx.wipeIn = /*===== dojo.fx.wipeIn = =====*/ function(/*Object*/ args){
// summary:
// Expand a node to it's natural height.
//
// description:
// Returns an animation that will expand the
// node defined in 'args' object from it's current height to
// it's natural height (with no scrollbar).
// Node must have no margin/border/padding.
//
// args: Object
// A hash-map of standard `dojo.Animation` constructor properties
// (such as easing: node: duration: and so on)
//
// example:
// | dojo.fx.wipeIn({
// | node:"someId"
// | }).play()
var node = args.node = dom.byId(args.node), s = node.style, o;
var anim = baseFx.animateProperty(lang.mixin({
properties: {
height: {
// wrapped in functions so we wait till the last second to query (in case value has changed)
start: function(){
// start at current [computed] height, but use 1px rather than 0
// because 0 causes IE to display the whole panel
o = s.overflow;
s.overflow = "hidden";
if(s.visibility == "hidden" || s.display == "none"){
s.height = "1px";
s.display = "";
s.visibility = "";
return 1;
}else{
var height = domStyle.get(node, "height");
return Math.max(height, 1);
}
},
end: function(){
return node.scrollHeight;
}
}
}
}, args));
var fini = function(){
s.height = "auto";
s.overflow = o;
};
connect.connect(anim, "onStop", fini);
connect.connect(anim, "onEnd", fini);
return anim; // dojo.Animation
};
coreFx.wipeOut = /*===== dojo.fx.wipeOut = =====*/ function(/*Object*/ args){
// summary:
// Shrink a node to nothing and hide it.
//
// description:
// Returns an animation that will shrink node defined in "args"
// from it's current height to 1px, and then hide it.
//
// args: Object
// A hash-map of standard `dojo.Animation` constructor properties
// (such as easing: node: duration: and so on)
//
// example:
// | dojo.fx.wipeOut({ node:"someId" }).play()
var node = args.node = dom.byId(args.node), s = node.style, o;
var anim = baseFx.animateProperty(lang.mixin({
properties: {
height: {
end: 1 // 0 causes IE to display the whole panel
}
}
}, args));
connect.connect(anim, "beforeBegin", function(){
o = s.overflow;
s.overflow = "hidden";
s.display = "";
});
var fini = function(){
s.overflow = o;
s.height = "auto";
s.display = "none";
};
connect.connect(anim, "onStop", fini);
connect.connect(anim, "onEnd", fini);
return anim; // dojo.Animation
};
coreFx.slideTo = /*===== dojo.fx.slideTo = =====*/ function(/*Object*/ args){
// summary:
// Slide a node to a new top/left position
//
// description:
// Returns an animation that will slide "node"
// defined in args Object from its current position to
// the position defined by (args.left, args.top).
//
// args: Object
// A hash-map of standard `dojo.Animation` constructor properties
// (such as easing: node: duration: and so on). Special args members
// are `top` and `left`, which indicate the new position to slide to.
//
// example:
// | .slideTo({ node: node, left:"40", top:"50", units:"px" }).play()
var node = args.node = dom.byId(args.node),
top = null, left = null;
var init = (function(n){
return function(){
var cs = domStyle.getComputedStyle(n);
var pos = cs.position;
top = (pos == 'absolute' ? n.offsetTop : parseInt(cs.top) || 0);
left = (pos == 'absolute' ? n.offsetLeft : parseInt(cs.left) || 0);
if(pos != 'absolute' && pos != 'relative'){
var ret = geom.position(n, true);
top = ret.y;
left = ret.x;
n.style.position="absolute";
n.style.top=top+"px";
n.style.left=left+"px";
}
};
})(node);
init();
var anim = baseFx.animateProperty(lang.mixin({
properties: {
top: args.top || 0,
left: args.left || 0
}
}, args));
connect.connect(anim, "beforeBegin", anim, init);
return anim; // dojo.Animation
};
return coreFx;
});
},
'dijit/_base':function(){
define("dijit/_base", [
".",
"./a11y", // used to be in dijit/_base/manager
"./WidgetSet", // used to be in dijit/_base/manager
"./_base/focus",
"./_base/manager",
"./_base/place",
"./_base/popup",
"./_base/scroll",
"./_base/sniff",
"./_base/typematic",
"./_base/wai",
"./_base/window"
], function(dijit){
// module:
// dijit/_base
// summary:
// Includes all the modules in dijit/_base
return dijit._base;
});
},
'dojox/mobile/sniff':function(){
define("dojox/mobile/sniff", [
"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/ProgressIndicator':function(){
define("dojox/mobile/ProgressIndicator", [
"dojo/_base/config",
"dojo/_base/declare",
"dojo/dom-construct",
"dojo/dom-style",
"dojo/has"
], function(config, declare, domConstruct, domStyle, has){
// module:
// dojox/mobile/ProgressIndicator
// summary:
// A progress indication widget.
var cls = declare("dojox.mobile.ProgressIndicator", null, {
// summary:
// A progress indication widget.
// description:
// ProgressIndicator is a round spinning graphical representation
// that indicates the current task is on-going.
// interval: Number
// The time interval in milliseconds for updating the spinning
// indicator.
interval: 100,
// colors: Array
// An array of indicator colors.
colors: [
"#C0C0C0", "#C0C0C0", "#C0C0C0", "#C0C0C0",
"#C0C0C0", "#C0C0C0", "#B8B9B8", "#AEAFAE",
"#A4A5A4", "#9A9A9A", "#8E8E8E", "#838383"
],
constructor: function(){
this._bars = [];
this.domNode = domConstruct.create("DIV");
this.domNode.className = "mblProgContainer";
if(config["mblAndroidWorkaround"] !== false && has("android") >= 2.2 && has("android") < 3){
// workaround to avoid the side effects of the fixes for android screen flicker problem
domStyle.set(this.domNode, "webkitTransform", "translate3d(0,0,0)");
}
this.spinnerNode = domConstruct.create("DIV", null, this.domNode);
for(var i = 0; i < this.colors.length; i++){
var div = domConstruct.create("DIV", {className:"mblProg mblProg"+i}, this.spinnerNode);
this._bars.push(div);
}
},
start: function(){
// summary:
// Starts the ProgressIndicator spinning.
if(this.imageNode){
var img = this.imageNode;
var l = Math.round((this.domNode.offsetWidth - img.offsetWidth) / 2);
var t = Math.round((this.domNode.offsetHeight - img.offsetHeight) / 2);
img.style.margin = t+"px "+l+"px";
return;
}
var cntr = 0;
var _this = this;
var n = this.colors.length;
this.timer = setInterval(function(){
cntr--;
cntr = cntr < 0 ? n - 1 : cntr;
var c = _this.colors;
for(var i = 0; i < n; i++){
var idx = (cntr + i) % n;
_this._bars[i].style.backgroundColor = c[idx];
}
}, this.interval);
},
stop: function(){
// summary:
// Stops the ProgressIndicator spinning.
if(this.timer){
clearInterval(this.timer);
}
this.timer = null;
if(this.domNode.parentNode){
this.domNode.parentNode.removeChild(this.domNode);
}
},
setImage: function(/*String*/file){
// summary:
// Sets an indicator icon image file (typically animated GIF).
// If null is specified, restores the default spinner.
if(file){
this.imageNode = domConstruct.create("IMG", {src:file}, this.domNode);
this.spinnerNode.style.display = "none";
}else{
if(this.imageNode){
this.domNode.removeChild(this.imageNode);
this.imageNode = null;
}
this.spinnerNode.style.display = "";
}
}
});
cls._instance = null;
cls.getInstance = function(){
if(!cls._instance){
cls._instance = new cls();
}
return cls._instance;
};
return cls;
});
},
'dijit/form/_FormWidgetMixin':function(){
define("dijit/form/_FormWidgetMixin", [
"dojo/_base/array", // array.forEach
"dojo/_base/declare", // declare
"dojo/dom-attr", // domAttr.set
"dojo/dom-style", // domStyle.get
"dojo/_base/lang", // lang.hitch lang.isArray
"dojo/mouse", // mouse.isLeft
"dojo/_base/sniff", // has("webkit")
"dojo/_base/window", // win.body
"dojo/window", // winUtils.scrollIntoView
"../a11y" // a11y.hasDefaultTabStop
], function(array, declare, domAttr, domStyle, lang, mouse, has, win, winUtils, a11y){
// module:
// dijit/form/_FormWidgetMixin
// summary:
// Mixin for widgets corresponding to native HTML elements such as or