/* Copyright (c) 2004-2012, 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 */ if(!dojo._hasResource["dojox.mobile._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. dojo._hasResource["dojox.mobile._base"] = true; dojo.provide("dojox.mobile._base"); dojo.require("dijit._WidgetBase"); dojo.isBB = (navigator.userAgent.indexOf("BlackBerry") != -1) && !dojo.isWebKit; // summary: // Mobile Widgets // description: // This module provides a number of widgets that can be used to build // web-based applications for mobile devices such as iPhone or Android. // These widgets work best with webkit-based browsers, such as Safari or // Chrome, since webkit-specific CSS3 features are used. // However, the widgets should work in a "graceful degradation" manner // even on non-CSS3 browsers, such as IE or Firefox. In that case, // fancy effects, such as animation, gradient color, or round corner // rectangle, may not work, but you can still operate your application. // // Furthermore, as a separate file, a compatibility module, // dojox.mobile.compat, is available that simulates some of CSS3 features // used in this module. If you use the compatibility module, fancy visual // effects work better even on non-CSS3 browsers. // // Note that use of dijit._Container, dijit._Contained, dijit._Templated, // and dojo.query is intentionally avoided to reduce download code size. dojo.declare( "dojox.mobile.View", dijit._WidgetBase, { // 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, _started: false, constructor: function(params, node){ if(node){ dojo.byId(node).style.visibility = "hidden"; } }, buildRendering: function(){ this.domNode = this.containerNode = this.srcNodeRef || dojo.doc.createElement("DIV"); this.domNode.className = "mblView"; this.connect(this.domNode, "webkitAnimationEnd", "onAnimationEnd"); this.connect(this.domNode, "webkitAnimationStart", "onAnimationStart"); var id = location.href.match(/#(\w+)([^\w=]|$)/) ? RegExp.$1 : null; this._visible = this.selected && !id || this.id == id; if(this.selected){ dojox.mobile._defaultView = this; } }, startup: function(){ if(this._started){ return; } var _this = this; setTimeout(function(){ if(!_this._visible){ _this.domNode.style.display = "none"; }else{ dojox.mobile.currentView = _this; _this.onStartView(); } _this.domNode.style.visibility = "visible"; }, dojo.isIE?100:0); // give IE a little time to complete drawing this._started = true; }, onStartView: function(){ // Stub function to connect to from your application. // Called only when this view is shown at startup time. }, onBeforeTransitionIn: function(moveTo, dir, transition, context, method){ // Stub function to connect to from your application. }, onAfterTransitionIn: function(moveTo, dir, transition, context, method){ // Stub function to connect to from your application. }, onBeforeTransitionOut: function(moveTo, dir, transition, context, method){ // Stub function to connect to from your application. }, onAfterTransitionOut: function(moveTo, dir, transition, context, method){ // Stub function to connect to from your application. }, _saveState: function(moveTo, dir, transition, context, method){ this._context = context; this._method = method; if(transition == "none" || !dojo.isWebKit){ transition = null; } this._moveTo = moveTo; this._dir = dir; this._transition = transition; this._arguments = []; var i; for(i = 0; i < arguments.length; i++){ this._arguments.push(arguments[i]); } this._args = []; if(context || method){ for(i = 5; i < arguments.length; i++){ this._args.push(arguments[i]); } } }, 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 destination view id to transition the current view to. // If null, transitions to a blank view. // 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. // transision: String // The type of transition to perform. "slide", "fade", or "flip" // 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: // Transitions to the blank view, and then opens another page. // | performTransition(null, 1, "slide", null, function(){location.href = href;}); if(dojo.hash){ if(typeof(moveTo) == "string" && moveTo.charAt(0) == '#' && !dojox.mobile._params){ dojox.mobile._params = []; for(var i = 0; i < arguments.length; i++){ dojox.mobile._params.push(arguments[i]); } dojo.hash(moveTo); return; } } this._saveState.apply(this, arguments); var toNode; if(moveTo){ if(typeof(moveTo) == "string"){ // removes a leading hash mark (#) and params if exists // ex. "#bar&myParam=0003" -> "bar" moveTo.match(/^#?([^&?]+)/); toNode = RegExp.$1; }else{ toNode = moveTo; } }else{ if(!this._dummyNode){ this._dummyNode = dojo.doc.createElement("DIV"); dojo.body().appendChild(this._dummyNode); } toNode = this._dummyNode; } var fromNode = this.domNode; toNode = this.toNode = dojo.byId(toNode); if(!toNode){ alert("dojox.mobile.View#performTransition: destination view not found: "+toNode); } toNode.style.visibility = "hidden"; toNode.style.display = ""; this.onBeforeTransitionOut.apply(this, arguments); var toWidget = dijit.byNode(toNode); if(toWidget){ // perform view transition keeping the scroll position if(this.keepScrollPos && !dijit.getEnclosingWidget(this.domNode.parentNode)){ var scrollTop = dojo.body().scrollTop || dojo.doc.documentElement.scrollTop || dojo.global.pageYOffset || 0; if(dir == 1){ toNode.style.top = "0px"; if(scrollTop > 1){ fromNode.style.top = -scrollTop + "px"; if(dojo.config["mblHideAddressBar"] !== false){ setTimeout(function(){ // iPhone needs setTimeout dojo.global.scrollTo(0, 1); }, 0); } } }else{ if(scrollTop > 1 || toNode.offsetTop !== 0){ var toTop = -toNode.offsetTop; toNode.style.top = "0px"; fromNode.style.top = toTop - scrollTop + "px"; if(dojo.config["mblHideAddressBar"] !== false && toTop > 0){ setTimeout(function(){ // iPhone needs setTimeout dojo.global.scrollTo(0, toTop + 1); }, 0); } } } }else{ toNode.style.top = "0px"; } toWidget.onBeforeTransitionIn.apply(toWidget, arguments); } toNode.style.display = "none"; toNode.style.visibility = "visible"; this._doTransition(fromNode, toNode, transition, dir); }, _doTransition: function(fromNode, toNode, transition, dir){ var rev = (dir == -1) ? " reverse" : ""; toNode.style.display = ""; if(!transition || transition == "none"){ this.domNode.style.display = "none"; this.invokeCallback(); }else{ dojo.addClass(fromNode, transition + " out" + rev); dojo.addClass(toNode, transition + " in" + rev); } }, onAnimationStart: function(e){ }, onAnimationEnd: function(e){ var isOut = false; if(dojo.hasClass(this.domNode, "out")){ isOut = true; this.domNode.style.display = "none"; dojo.forEach([this._transition,"in","out","reverse"], function(s){ dojo.removeClass(this.domNode, s); }, this); } if(e.animationName.indexOf("shrink") === 0){ var li = e.target; li.style.display = "none"; dojo.removeClass(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"); }, invokeCallback: function(){ this.onAfterTransitionOut.apply(this, this._arguments); var toWidget = dijit.byNode(this.toNode); if(toWidget){ toWidget.onAfterTransitionIn.apply(toWidget, this._arguments); } dojox.mobile.currentView = toWidget; var c = this._context, m = this._method; if(!c && !m){ return; } if(!m){ m = c; c = null; } c = c || dojo.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++){ if(dojo.hasClass(nodes[i], "mblView") && dojo.style(nodes[i], "display") != "none"){ return dijit.byNode(nodes[i]); } } }, show: function(){ // summary: // Shows this view without a transition animation. var fs = this.getShowingView().domNode.style; // from-style var ts = this.domNode.style; // to-style fs.display = "none"; ts.display = ""; dojox.mobile.currentView = this; }, addChild: function(widget){ this.containerNode.appendChild(widget.domNode); } }); dojo.declare( "dojox.mobile.Heading", dijit._WidgetBase, { back: "", href: "", moveTo: "", transition: "slide", label: "", iconBase: "", buildRendering: function(){ this.domNode = this.containerNode = this.srcNodeRef || dojo.doc.createElement("H1"); this.domNode.className = "mblHeading"; this._view = dijit.getEnclosingWidget(this.domNode.parentNode); // parentNode is null if created programmatically if(this.label){ this.domNode.appendChild(document.createTextNode(this.label)); }else{ this.label = ""; dojo.forEach(this.domNode.childNodes, function(n){ if(n.nodeType == 3){ this.label += n.nodeValue; } }, this); this.label = dojo.trim(this.label); } if(this.back){ var btn = dojo.create("DIV", {className:"mblArrowButton"}, this.domNode, "first"); var head = dojo.create("DIV", {className:"mblArrowButtonHead"}, btn); var body = dojo.create("DIV", {className:"mblArrowButtonBody mblArrowButtonText"}, btn); this._body = body; this._head = head; this._btn = btn; body.innerHTML = this.back; this.connect(body, "onclick", "onClick"); var neck = dojo.create("DIV", {className:"mblArrowButtonNeck"}, btn); btn.style.width = body.offsetWidth + head.offsetWidth + "px"; this.setLabel(this.label); } }, startup: function(){ if(this._btn){ this._btn.style.width = this._body.offsetWidth + this._head.offsetWidth + "px"; } }, onClick: function(e){ var h1 = this.domNode; dojo.addClass(h1, "mblArrowButtonSelected"); setTimeout(function(){ dojo.removeClass(h1, "mblArrowButtonSelected"); }, 1000); this.goTo(this.moveTo, this.href); }, setLabel: function(label){ if(label != this.label){ this.label = label; this.domNode.firstChild.nodeValue = label; } }, goTo: function(moveTo, href){ if(!this._view){ this._view = dijit.byNode(this.domNode.parentNode); } if(!this._view){ return; } if(href){ this._view.performTransition(null, -1, this.transition, this, function(){location.href = href;}); }else{ if(dojox.mobile.app && dojox.mobile.app.STAGE_CONTROLLER_ACTIVE){ // If in a full mobile app, then use its mechanisms to move back a scene dojo.publish("/dojox/mobile/app/goback"); } else{ this._view.performTransition(moveTo, -1, this.transition); } } } }); dojo.declare( "dojox.mobile.RoundRect", dijit._WidgetBase, { shadow: false, buildRendering: function(){ this.domNode = this.containerNode = this.srcNodeRef || dojo.doc.createElement("DIV"); this.domNode.className = this.shadow ? "mblRoundRect mblShadow" : "mblRoundRect"; } }); dojo.declare( "dojox.mobile.RoundRectCategory", dijit._WidgetBase, { label: "", buildRendering: function(){ this.domNode = this.containerNode = this.srcNodeRef || dojo.doc.createElement("H2"); this.domNode.className = "mblRoundRectCategory"; if(this.label){ this.domNode.innerHTML = this.label; }else{ this.label = this.domNode.innerHTML; } } }); dojo.declare( "dojox.mobile.EdgeToEdgeCategory", dojox.mobile.RoundRectCategory, { buildRendering: function(){ this.inherited(arguments); this.domNode.className = "mblEdgeToEdgeCategory"; } }); dojo.declare( "dojox.mobile.RoundRectList", dijit._WidgetBase, { transition: "slide", iconBase: "", iconPos: "", buildRendering: function(){ this.domNode = this.containerNode = this.srcNodeRef || dojo.doc.createElement("UL"); this.domNode.className = "mblRoundRectList"; }, addChild: function(widget){ this.containerNode.appendChild(widget.domNode); widget.inheritParams(); widget.setIcon(); } }); dojo.declare( "dojox.mobile.EdgeToEdgeList", dojox.mobile.RoundRectList, { stateful: false, // keep the selection state or not buildRendering: function(){ this.inherited(arguments); this.domNode.className = "mblEdgeToEdgeList"; } }); dojo.declare( "dojox.mobile.AbstractItem", dijit._WidgetBase, { icon: "", iconPos: "", // top,left,width,height (ex. "0,0,29,29") href: "", hrefTarget: "", moveTo: "", scene: "", clickable: false, url: "", urlTarget: "", // node id under which a new view is created transition: "", transitionDir: 1, callback: null, sync: true, label: "", toggle: false, _duration: 800, // duration of selection, milliseconds inheritParams: function(){ var parent = this.getParentWidget(); if(parent){ if(!this.transition){ this.transition = parent.transition; } if(!this.icon){ this.icon = parent.iconBase; } if(!this.iconPos){ this.iconPos = parent.iconPos; } } }, findCurrentView: function(moveTo){ var w; if(moveTo){ w = dijit.byId(moveTo); if(w){ return w.getShowingView(); } } var n = this.domNode.parentNode; while(true){ w = dijit.getEnclosingWidget(n); if(!w){ return null; } if(w.performTransition){ break; } n = w.domNode.parentNode; } return w; }, transitionTo: function(moveTo, href, url, scene){ var w = this.findCurrentView(moveTo); // the current view widget if(!w || moveTo && w === dijit.byId(moveTo)){ return; } if(href){ if(this.hrefTarget){ dojox.mobile.openWindow(this.href, this.hrefTarget); }else{ w.performTransition(null, this.transitionDir, this.transition, this, function(){location.href = href;}); } return; } else if(scene){ dojo.publish("/dojox/mobile/app/pushScene", [scene]); return; } if(url){ var id; if(dojox.mobile._viewMap && dojox.mobile._viewMap[url]){ // external view has already been loaded id = dojox.mobile._viewMap[url]; }else{ // get the specified external view and append it to the var text = this._text; if(!text){ if(this.sync){ text = dojo.trim(dojo._getText(url)); }else{ dojo["require"]("dojo._base.xhr"); var prog = dojox.mobile.ProgressIndicator.getInstance(); dojo.body().appendChild(prog.domNode); prog.start(); var xhr = dojo.xhrGet({ url: url, handleAs: "text" }); xhr.addCallback(dojo.hitch(this, function(response, ioArgs){ prog.stop(); if(response){ this._text = response; this.transitionTo(moveTo, href, url, scene); } })); xhr.addErrback(function(error){ prog.stop(); alert("Failed to load "+url+"\n"+(error.description||error)); }); return; } } this._text = null; id = this._parse(text); if(!dojox.mobile._viewMap){ dojox.mobile._viewMap = []; } dojox.mobile._viewMap[url] = id; } moveTo = id; w = this.findCurrentView(moveTo) || w; // the current view widget } w.performTransition(moveTo, this.transitionDir, this.transition, this.callback && this, this.callback); }, _parse: function(text){ var container = dojo.create("DIV"); var view; var id = this.urlTarget; var target = dijit.byId(id) && dijit.byId(id).containerNode || dojo.byId(id) || dojox.mobile.currentView && dojox.mobile.currentView.domNode.parentNode || dojo.body(); if(text.charAt(0) == "<"){ // html markup container.innerHTML = text; view = container.firstChild; //
if(!view && view.nodeType != 1){ alert("dojox.mobile.AbstractItem#transitionTo: invalid view content"); return; } view.setAttribute("_started", "true"); // to avoid startup() is called view.style.visibility = "hidden"; target.appendChild(container); (dojox.mobile.parser || dojo.parser).parse(container); target.appendChild(target.removeChild(container).firstChild); // reparent }else if(text.charAt(0) == "{"){ // json target.appendChild(container); this._ws = []; view = this._instantiate(eval('('+text+')'), container); for(var 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"; var id = view.id; return dojo.hash ? "#" + id : id; }, _instantiate: function(/*Object*/obj, /*DomNode*/node, /*Widget*/parent){ var widget; for(var key in obj){ if(key.charAt(0) == "@"){ continue; } var cls = dojo.getObject(key); if(!cls){ continue; } var params = {}; var proto = cls.prototype; var objs = dojo.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){ // not to call View's startup() this._ws.push(widget); } if(parent && parent.addChild){ parent.addChild(widget); } this._instantiate(objs[i], null, widget); } } return widget && widget.domNode; }, createDomButton: function(/*DomNode*/refNode, /*DomNode?*/toNode){ var s = refNode.className; if(s.match(/mblDomButton\w+_(\d+)/)){ var nDiv = RegExp.$1 - 0; for(var i = 0, p = (toNode||refNode); i < nDiv; i++){ p = dojo.create("DIV", null, p); } } }, select: function(/*Boolean?*/deselect){ // subclass must implement }, defaultClickAction: function(){ if(this.toggle){ this.select(this.selected); }else if(!this.selected){ this.select(); if(!this.selectOne){ var _this = this; setTimeout(function(){ _this.select(true); }, this._duration); } if(this.moveTo || this.href || this.url || this.scene){ this.transitionTo(this.moveTo, this.href, this.url, this.scene); } } }, getParentWidget: function(){ var ref = this.srcNodeRef || this.domNode; return ref && ref.parentNode ? dijit.getEnclosingWidget(ref.parentNode) : null; } }); dojo.declare( "dojox.mobile.ListItem", dojox.mobile.AbstractItem, { rightText: "", btnClass: "", anchorLabel: false, noArrow: false, selected: false, buildRendering: function(){ this.inheritParams(); var a = this.anchorNode = dojo.create("A"); a.className = "mblListItemAnchor"; var box = dojo.create("DIV"); box.className = "mblListItemTextBox"; if(this.anchorLabel){ box.style.cursor = "pointer"; } var r = this.srcNodeRef; if(r){ for(var i = 0, len = r.childNodes.length; i < len; i++){ box.appendChild(r.removeChild(r.firstChild)); } } if(this.label){ box.appendChild(dojo.doc.createTextNode(this.label)); } a.appendChild(box); if(this.rightText){ this._setRightTextAttr(this.rightText); } if(this.moveTo || this.href || this.url || this.clickable){ var parent = this.getParentWidget(); if(!this.noArrow && !(parent && parent.stateful)){ var arrow = dojo.create("DIV"); arrow.className = "mblArrow"; a.appendChild(arrow); } this.connect(a, "onclick", "onClick"); }else if(this.btnClass){ var div = this.btnNode = dojo.create("DIV"); div.className = this.btnClass+" mblRightButton"; div.appendChild(dojo.create("DIV")); div.appendChild(dojo.create("P")); var dummyDiv = dojo.create("DIV"); dummyDiv.className = "mblRightButtonContainer"; dummyDiv.appendChild(div); a.appendChild(dummyDiv); dojo.addClass(a, "mblListItemAnchorHasRightButton"); setTimeout(function(){ dummyDiv.style.width = div.offsetWidth + "px"; dummyDiv.style.height = div.offsetHeight + "px"; if(dojo.isIE){ // IE seems to ignore the height of LI without this.. a.parentNode.style.height = a.parentNode.offsetHeight + "px"; } }, 0); } if(this.anchorLabel){ box.style.display = "inline"; // to narrow the text region } var li = this.domNode = this.containerNode = this.srcNodeRef || dojo.doc.createElement("LI"); li.className = "mblListItem" + (this.selected ? " mblItemSelected" : ""); li.appendChild(a); this.setIcon(); }, setIcon: function(){ if(this.iconNode){ return; } var a = this.anchorNode; if(this.icon && this.icon != "none"){ var img = this.iconNode = dojo.create("IMG"); img.className = "mblListItemIcon"; img.src = this.icon; this.domNode.insertBefore(img, a); dojox.mobile.setupIcon(this.iconNode, this.iconPos); dojo.removeClass(a, "mblListItemAnchorNoIcon"); }else{ dojo.addClass(a, "mblListItemAnchorNoIcon"); } }, onClick: function(e){ var a = e.currentTarget; var li = a.parentNode; if(dojo.hasClass(li, "mblItemSelected")){ return; } // already selected if(this.anchorLabel){ for(var p = e.target; p.tagName != "LI"; p = p.parentNode){ if(p.className == "mblListItemTextBox"){ dojo.addClass(p, "mblListItemTextBoxSelected"); setTimeout(function(){ dojo.removeClass(p, "mblListItemTextBoxSelected"); }, 1000); this.onAnchorLabelClicked(e); return; } } } if(this.getParentWidget().stateful){ for(var i = 0, c = li.parentNode.childNodes; i < c.length; i++){ dojo.removeClass(c[i], "mblItemSelected"); } }else{ setTimeout(function(){ dojo.removeClass(li, "mblItemSelected"); }, 1000); } dojo.addClass(li, "mblItemSelected"); this.transitionTo(this.moveTo, this.href, this.url, this.scene); }, onAnchorLabelClicked: function(e){ }, _setRightTextAttr: function(/*String*/text){ this.rightText = text; if(!this._rightTextNode){ this._rightTextNode = dojo.create("DIV", {className:"mblRightText"}, this.anchorNode); } this._rightTextNode.innerHTML = text; } }); dojo.declare( "dojox.mobile.Switch", dijit._WidgetBase, { value: "on", leftLabel: "ON", rightLabel: "OFF", _width: 53, buildRendering: function(){ this.domNode = this.srcNodeRef || dojo.doc.createElement("DIV"); this.domNode.className = "mblSwitch"; this.domNode.innerHTML = '
' + '
' + '
'+this.leftLabel+'
' + '
' + '
' + '
'+this.rightLabel+'
' + '
' + '
' + '
'; var n = this.inner = this.domNode.firstChild; this.left = n.childNodes[0]; this.right = n.childNodes[1]; this.knob = n.childNodes[2]; dojo.addClass(this.domNode, (this.value == "on") ? "mblSwitchOn" : "mblSwitchOff"); this[this.value == "off" ? "left" : "right"].style.display = "none"; }, postCreate: function(){ this.connect(this.knob, "onclick", "onClick"); this.connect(this.knob, "touchstart", "onTouchStart"); this.connect(this.knob, "mousedown", "onTouchStart"); }, _changeState: function(/*String*/state){ this.inner.style.left = ""; dojo.addClass(this.domNode, "mblSwitchAnimation"); dojo.removeClass(this.domNode, (state == "on") ? "mblSwitchOff" : "mblSwitchOn"); dojo.addClass(this.domNode, (state == "on") ? "mblSwitchOn" : "mblSwitchOff"); var _this = this; setTimeout(function(){ _this[state == "off" ? "left" : "right"].style.display = "none"; dojo.removeClass(_this.domNode, "mblSwitchAnimation"); }, 300); }, onClick: function(e){ if(this._moved){ return; } this.value = (this.value == "on") ? "off" : "on"; this._changeState(this.value); this.onStateChanged(this.value); }, onTouchStart: function(e){ this._moved = false; this.innerStartX = this.inner.offsetLeft; if(e.targetTouches){ this.touchStartX = e.targetTouches[0].clientX; this._conn1 = dojo.connect(this.inner, "touchmove", this, "onTouchMove"); this._conn2 = dojo.connect(this.inner, "touchend", this, "onTouchEnd"); } this.left.style.display = "block"; this.right.style.display = "block"; dojo.stopEvent(e); }, onTouchMove: function(e){ e.preventDefault(); var dx; if(e.targetTouches){ if(e.targetTouches.length != 1){ return false; } dx = e.targetTouches[0].clientX - this.touchStartX; }else{ dx = e.clientX - this.touchStartX; } var pos = this.innerStartX + dx; var d = 10; if(pos <= -(this._width-d)){ pos = -this._width; } if(pos >= -d){ pos = 0; } this.inner.style.left = pos + "px"; this._moved = true; }, onTouchEnd: function(e){ dojo.disconnect(this._conn1); dojo.disconnect(this._conn2); if(this.innerStartX == this.inner.offsetLeft){ if(dojo.isWebKit){ var ev = dojo.doc.createEvent("MouseEvents"); ev.initEvent("click", true, true); this.knob.dispatchEvent(ev); } return; } var newState = (this.inner.offsetLeft < -(this._width/2)) ? "off" : "on"; this._changeState(newState); if(newState != this.value){ this.value = newState; this.onStateChanged(this.value); } }, onStateChanged: function(/*String*/newState){ } }); dojo.declare( "dojox.mobile.Button", dijit._WidgetBase, { btnClass: "mblBlueButton", duration: 1000, // duration of selection, milliseconds label: null, buildRendering: function(){ this.domNode = this.containerNode = this.srcNodeRef || dojo.doc.createElement("BUTTON"); this.domNode.className = "mblButton "+this.btnClass; if(this.label){ this.domNode.innerHTML = this.label; } this.connect(this.domNode, "onclick", "onClick"); }, onClick: function(e){ var button = this.domNode; var c = "mblButtonSelected "+this.btnClass+"Selected"; dojo.addClass(button, c); setTimeout(function(){ dojo.removeClass(button, c); }, this.duration); } }); dojo.declare( "dojox.mobile.ToolBarButton", dojox.mobile.AbstractItem, { selected: false, _defaultColor: "mblColorDefault", _selColor: "mblColorDefaultSel", buildRendering: function(){ this.inheritParams(); this.domNode = this.containerNode = this.srcNodeRef || dojo.doc.createElement("div"); dojo.addClass(this.domNode, "mblToolbarButton mblArrowButtonText"); var color; if(this.selected){ color = this._selColor; }else if(this.domNode.className.indexOf("mblColor") == -1){ color = this._defaultColor; } dojo.addClass(this.domNode, color); if(this.label){ this.domNode.innerHTML = this.label; }else{ this.label = this.domNode.innerHTML; } if(this.icon && this.icon != "none"){ var img; if(this.iconPos){ var iconDiv = dojo.create("DIV", null, this.domNode); img = dojo.create("IMG", null, iconDiv); img.style.position = "absolute"; var arr = this.iconPos.split(/[ ,]/); dojo.style(iconDiv, { position: "relative", width: arr[2] + "px", height: arr[3] + "px" }); }else{ img = dojo.create("IMG", null, this.domNode); } img.src = this.icon; dojox.mobile.setupIcon(img, this.iconPos); this.iconNode = img; } this.createDomButton(this.domNode); this.connect(this.domNode, "onclick", "onClick"); }, select: function(/*Boolean?*/deselect){ dojo.toggleClass(this.domNode, this._selColor, !deselect); this.selected = !deselect; }, onClick: function(e){ this.defaultClickAction(); } }); dojo.declare( "dojox.mobile.ProgressIndicator", null, { interval: 100, // milliseconds colors: [ "#C0C0C0", "#C0C0C0", "#C0C0C0", "#C0C0C0", "#C0C0C0", "#C0C0C0", "#B8B9B8", "#AEAFAE", "#A4A5A4", "#9A9A9A", "#8E8E8E", "#838383" ], _bars: [], constructor: function(){ this.domNode = dojo.create("DIV"); this.domNode.className = "mblProgContainer"; for(var i = 0; i < 12; i++){ var div = dojo.create("DIV"); div.className = "mblProg mblProg"+i; this.domNode.appendChild(div); this._bars.push(div); } }, start: function(){ var cntr = 0; var _this = this; this.timer = setInterval(function(){ cntr--; cntr = cntr < 0 ? 11 : cntr; var c = _this.colors; for(var i = 0; i < 12; i++){ var idx = (cntr + i) % 12; _this._bars[i].style.backgroundColor = c[idx]; } }, this.interval); }, stop: function(){ if(this.timer){ clearInterval(this.timer); } this.timer = null; if(this.domNode.parentNode){ this.domNode.parentNode.removeChild(this.domNode); } } }); dojox.mobile.ProgressIndicator._instance = null; dojox.mobile.ProgressIndicator.getInstance = function(){ if(!dojox.mobile.ProgressIndicator._instance){ dojox.mobile.ProgressIndicator._instance = new dojox.mobile.ProgressIndicator(); } return dojox.mobile.ProgressIndicator._instance; }; dojox.mobile.addClass = function(){ // summary: // Adds a theme class name to . // description: // Finds the currently applied theme name, such as 'iphone' or 'android' // from link elements, and adds it as a class name for the body element. var elems = document.getElementsByTagName("link"); for(var i = 0, len = elems.length; i < len; i++){ if(elems[i].href.match(/dojox\/mobile\/themes\/(\w+)\//)){ dojox.mobile.theme = RegExp.$1; dojo.addClass(dojo.body(), dojox.mobile.theme); break; } } }; dojox.mobile.setupIcon = function(/*DomNode*/iconNode, /*String*/iconPos){ if(iconNode && iconPos){ var arr = dojo.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 iconNode.style.clip = "rect("+t+"px "+r+"px "+b+"px "+l+"px)"; iconNode.style.top = dojo.style(iconNode, "top") - t + "px"; iconNode.style.left = dojo.style(iconNode.parentNode, "paddingLeft") - l + "px"; } }; dojox.mobile.hideAddressBar = function(){ dojo.body().style.minHeight = "1000px"; // to ensure enough height for scrollTo to work setTimeout(function(){ scrollTo(0, 1); }, 100); setTimeout(function(){ scrollTo(0, 1); }, 400); setTimeout(function(){ scrollTo(0, 1); // re-define the min-height with the actual height dojo.body().style.minHeight = (dojo.global.innerHeight||dojo.doc.documentElement.clientHeight) + "px"; }, 1000); }; dojox.mobile.openWindow = function(url, target){ dojo.global.open(url, target || "_blank"); }; dojo._loaders.unshift(function(){ // avoid use of dojo.query /* var list = dojo.query('[lazy=true] [dojoType]', null); list.forEach(function(node, index, nodeList){ node.setAttribute("__dojoType", node.getAttribute("dojoType")); node.removeAttribute("dojoType"); }); */ var nodes = dojo.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"); } } } }); dojo.addOnLoad(function(){ dojox.mobile.addClass(); if(dojo.config["mblApplyPageStyles"] !== false){ dojo.addClass(dojo.doc.documentElement, "mobile"); } // You can disable hiding the address bar with the following djConfig. // var djConfig = { mblHideAddressBar: false }; if(dojo.config["mblHideAddressBar"] !== false){ dojox.mobile.hideAddressBar(); if(dojo.config["mblAlwaysHideAddressBar"] == true){ if(dojo.global.onorientationchange !== undefined){ dojo.connect(dojo.global, "onorientationchange", dojox.mobile.hideAddressBar); }else{ dojo.connect(dojo.global, "onresize", dojox.mobile.hideAddressBar); } } } // avoid use of dojo.query /* var list = dojo.query('[__dojoType]', null); list.forEach(function(node, index, nodeList){ node.setAttribute("dojoType", node.getAttribute("__dojoType")); node.removeAttribute("__dojoType"); }); */ var nodes = dojo.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){ var arr; arr = dijit.findWidgets(root); var widgets = arr; for(var i = 0; i < widgets.length; i++){ arr = arr.concat(findWidgets(widgets[i].containerNode)); } return arr; }; dojo.subscribe("/dojo/hashchange", null, function(value){ var view = dojox.mobile.currentView; if(!view){ return; } var params = dojox.mobile._params; if(!params){ // browser back/forward button was pressed var moveTo = value ? value : dojox.mobile._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 dojox.mobile.Heading) ? -1 : 1; break; } } params = [ moveTo, dir, transition ]; } view.performTransition.apply(view, params); dojox.mobile._params = null; }); } dojo.body().style.visibility = "visible"; }); dijit.getEnclosingWidget = function(node){ while(node && node.tagName !== "BODY"){ if(node.getAttribute && node.getAttribute("widgetId")){ return dijit.registry.byId(node.getAttribute("widgetId")); } node = node._parentNode || node.parentNode; } return null; }; }