summaryrefslogtreecommitdiff
path: root/js/dojo-1.7.2/dojox/mobile/View.js
diff options
context:
space:
mode:
authorTristan Zur <tzur@web.web.ccwn.org>2014-03-27 22:27:47 +0100
committerTristan Zur <tzur@web.web.ccwn.org>2014-03-27 22:27:47 +0100
commitb62676ca5d3d6f6ba3f019ea3f99722e165a98d8 (patch)
tree86722cb80f07d4569f90088eeaea2fc2f6e2ef94 /js/dojo-1.7.2/dojox/mobile/View.js
Initial commit of intern.ccwn.org contentsHEADmaster
Diffstat (limited to 'js/dojo-1.7.2/dojox/mobile/View.js')
-rw-r--r--js/dojo-1.7.2/dojox/mobile/View.js513
1 files changed, 513 insertions, 0 deletions
diff --git a/js/dojo-1.7.2/dojox/mobile/View.js b/js/dojo-1.7.2/dojox/mobile/View.js
new file mode 100644
index 0000000..4230200
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/mobile/View.js
@@ -0,0 +1,513 @@
+//>>built
+define("dojox/mobile/View", [
+ "dojo/_base/kernel", // to test dojo.hash
+ "dojo/_base/array",
+ "dojo/_base/config",
+ "dojo/_base/connect",
+ "dojo/_base/declare",
+ "dojo/_base/lang",
+ "dojo/_base/sniff",
+ "dojo/_base/window",
+ "dojo/_base/Deferred",
+ "dojo/dom",
+ "dojo/dom-class",
+ "dojo/dom-geometry",
+ "dojo/dom-style",
+// "dojo/hash", // optionally prereq'ed
+ "dijit/registry", // registry.byNode
+ "dijit/_Contained",
+ "dijit/_Container",
+ "dijit/_WidgetBase",
+ "./ViewController", // to load ViewController for you (no direct references)
+ "./transition"
+], function(dojo, array, config, connect, declare, lang, has, win, Deferred, dom, domClass, domGeometry, domStyle, registry, Contained, Container, WidgetBase, ViewController, transitDeferred){
+
+/*=====
+ var Contained = dijit._Contained;
+ var Container = dijit._Container;
+ var WidgetBase = dijit._WidgetBase;
+ var ViewController = dojox.mobile.ViewController;
+=====*/
+
+ // module:
+ // dojox/mobile/View
+ // summary:
+ // A widget that represents a view that occupies the full screen
+
+ var dm = lang.getObject("dojox.mobile", true);
+
+ return declare("dojox.mobile.View", [WidgetBase, Container, Contained], {
+ // summary:
+ // A widget that represents a view that occupies the full screen
+ // description:
+ // View acts as a container for any HTML and/or widgets. An entire
+ // HTML page can have multiple View widgets and the user can
+ // navigate through the views back and forth without page
+ // transitions.
+
+ // selected: Boolean
+ // If true, the view is displayed at startup time.
+ selected: false,
+
+ // keepScrollPos: Boolean
+ // If true, the scroll position is kept between views.
+ keepScrollPos: true,
+
+ constructor: function(params, node){
+ if(node){
+ dom.byId(node).style.visibility = "hidden";
+ }
+ this._aw = has("android") >= 2.2 && has("android") < 3; // flag for android animation workaround
+ },
+
+ buildRendering: function(){
+ this.domNode = this.containerNode = this.srcNodeRef || win.doc.createElement("DIV");
+ this.domNode.className = "mblView";
+ this.connect(this.domNode, "webkitAnimationEnd", "onAnimationEnd");
+ this.connect(this.domNode, "webkitAnimationStart", "onAnimationStart");
+ if(!config['mblCSS3Transition']){
+ this.connect(this.domNode, "webkitTransitionEnd", "onAnimationEnd");
+ }
+ var id = location.href.match(/#(\w+)([^\w=]|$)/) ? RegExp.$1 : null;
+
+ this._visible = this.selected && !id || this.id == id;
+
+ if(this.selected){
+ dm._defaultView = this;
+ }
+ },
+
+ startup: function(){
+ if(this._started){ return; }
+ var siblings = [];
+ var children = this.domNode.parentNode.childNodes;
+ var visible = false;
+ // check if a visible view exists
+ for(var i = 0; i < children.length; i++){
+ var c = children[i];
+ if(c.nodeType === 1 && domClass.contains(c, "mblView")){
+ siblings.push(c);
+ visible = visible || registry.byNode(c)._visible;
+ }
+ }
+ var _visible = this._visible;
+ // if no visible view exists, make the first view visible
+ if(siblings.length === 1 || (!visible && siblings[0] === this.domNode)){
+ _visible = true;
+ }
+ var _this = this;
+ setTimeout(function(){ // necessary to render the view correctly
+ if(!_visible){
+ _this.domNode.style.display = "none";
+ }else{
+ dm.currentView = _this; //TODO:1.8 reconsider this. currentView may not have a currently showing view when views are nested.
+ _this.onStartView();
+ connect.publish("/dojox/mobile/startView", [_this]);
+ }
+ if(_this.domNode.style.visibility != "visible"){ // this check is to avoid screen flickers
+ _this.domNode.style.visibility = "visible";
+ }
+ var parent = _this.getParent && _this.getParent();
+ if(!parent || !parent.resize){ // top level widget
+ _this.resize();
+ }
+ }, has("ie") ? 100 : 0); // give IE a little time to complete drawing
+ this.inherited(arguments);
+ },
+
+ resize: function(){
+ // summary:
+ // Calls resize() of each child widget.
+ array.forEach(this.getChildren(), function(child){
+ if(child.resize){ child.resize(); }
+ });
+ },
+
+ onStartView: function(){
+ // summary:
+ // Stub function to connect to from your application.
+ // description:
+ // Called only when this view is shown at startup time.
+ },
+
+ onBeforeTransitionIn: function(moveTo, dir, transition, context, method){
+ // summary:
+ // Stub function to connect to from your application.
+ // description:
+ // Called before the arriving transition occurs.
+ },
+
+ onAfterTransitionIn: function(moveTo, dir, transition, context, method){
+ // summary:
+ // Stub function to connect to from your application.
+ // description:
+ // Called after the arriving transition occurs.
+ },
+
+ onBeforeTransitionOut: function(moveTo, dir, transition, context, method){
+ // summary:
+ // Stub function to connect to from your application.
+ // description:
+ // Called before the leaving transition occurs.
+ },
+
+ onAfterTransitionOut: function(moveTo, dir, transition, context, method){
+ // summary:
+ // Stub function to connect to from your application.
+ // description:
+ // Called after the leaving transition occurs.
+ },
+
+ _saveState: function(moveTo, dir, transition, context, method){
+ this._context = context;
+ this._method = method;
+ if(transition == "none"){
+ transition = null;
+ }
+ this._moveTo = moveTo;
+ this._dir = dir;
+ this._transition = transition;
+ this._arguments = lang._toArray(arguments);
+ this._args = [];
+ if(context || method){
+ for(var i = 5; i < arguments.length; i++){
+ this._args.push(arguments[i]);
+ }
+ }
+ },
+
+ _fixViewState: function(/*DomNode*/toNode){
+ // summary:
+ // Sanity check for view transition states.
+ // description:
+ // Sometimes uninitialization of Views fails after making view transition,
+ // and that results in failure of subsequent view transitions.
+ // This function does the uninitialization for all the sibling views.
+ var nodes = this.domNode.parentNode.childNodes;
+ for(var i = 0; i < nodes.length; i++){
+ var n = nodes[i];
+ if(n.nodeType === 1 && domClass.contains(n, "mblView")){
+ n.className = "mblView"; //TODO: Should remove classes one by one. This would clear user defined classes or even mblScrollableView.
+ }
+ }
+ toNode.className = "mblView"; // just in case toNode is a sibling of an ancestor.
+ },
+
+ convertToId: function(moveTo){
+ if(typeof(moveTo) == "string"){
+ // removes a leading hash mark (#) and params if exists
+ // ex. "#bar&myParam=0003" -> "bar"
+ moveTo.match(/^#?([^&?]+)/);
+ return RegExp.$1;
+ }
+ return moveTo;
+ },
+
+ performTransition: function(/*String*/moveTo, /*Number*/dir, /*String*/transition,
+ /*Object|null*/context, /*String|Function*/method /*optional args*/){
+ // summary:
+ // Function to perform the various types of view transitions, such as fade, slide, and flip.
+ // moveTo: String
+ // The id of the transition destination view which resides in
+ // the current page.
+ // If the value has a hash sign ('#') before the id
+ // (e.g. #view1) and the dojo.hash module is loaded by the user
+ // application, the view transition updates the hash in the
+ // browser URL so that the user can bookmark the destination
+ // view. In this case, the user can also use the browser's
+ // back/forward button to navigate through the views in the
+ // browser history.
+ // If null, transitions to a blank view.
+ // If '#', returns immediately without transition.
+ // dir: Number
+ // The transition direction. If 1, transition forward. If -1, transition backward.
+ // For example, the slide transition slides the view from right to left when dir == 1,
+ // and from left to right when dir == -1.
+ // transition: String
+ // A type of animated transition effect. You can choose from
+ // the standard transition types, "slide", "fade", "flip", or
+ // from the extended transition types, "cover", "coverv",
+ // "dissolve", "reveal", "revealv", "scaleIn",
+ // "scaleOut", "slidev", "swirl", "zoomIn", "zoomOut". If
+ // "none" is specified, transition occurs immediately without
+ // animation.
+ // context: Object
+ // The object that the callback function will receive as "this".
+ // method: String|Function
+ // A callback function that is called when the transition has been finished.
+ // A function reference, or name of a function in context.
+ // tags:
+ // public
+ //
+ // example:
+ // Transition backward to a view whose id is "foo" with the slide animation.
+ // | performTransition("foo", -1, "slide");
+ //
+ // example:
+ // Transition forward to a blank view, and then open another page.
+ // | performTransition(null, 1, "slide", null, function(){location.href = href;});
+ if(moveTo === "#"){ return; }
+ if(dojo.hash){
+ if(typeof(moveTo) == "string" && moveTo.charAt(0) == '#' && !dm._params){
+ dm._params = [];
+ for(var i = 0; i < arguments.length; i++){
+ dm._params.push(arguments[i]);
+ }
+ dojo.hash(moveTo);
+ return;
+ }
+ }
+ this._saveState.apply(this, arguments);
+ var toNode;
+ if(moveTo){
+ toNode = this.convertToId(moveTo);
+ }else{
+ if(!this._dummyNode){
+ this._dummyNode = win.doc.createElement("DIV");
+ win.body().appendChild(this._dummyNode);
+ }
+ toNode = this._dummyNode;
+ }
+ var fromNode = this.domNode;
+ var fromTop = fromNode.offsetTop;
+ toNode = this.toNode = dom.byId(toNode);
+ if(!toNode){ console.log("dojox.mobile.View#performTransition: destination view not found: "+moveTo); return; }
+ toNode.style.visibility = this._aw ? "visible" : "hidden";
+ toNode.style.display = "";
+ this._fixViewState(toNode);
+ var toWidget = registry.byNode(toNode);
+ if(toWidget){
+ // Now that the target view became visible, it's time to run resize()
+ if(config["mblAlwaysResizeOnTransition"] || !toWidget._resized){
+ dm.resizeAll(null, toWidget);
+ toWidget._resized = true;
+ }
+
+ if(transition && transition != "none"){
+ // Temporarily add padding to align with the fromNode while transition
+ toWidget.containerNode.style.paddingTop = fromTop + "px";
+ }
+
+ toWidget.movedFrom = fromNode.id;
+ }
+
+ this.onBeforeTransitionOut.apply(this, arguments);
+ connect.publish("/dojox/mobile/beforeTransitionOut", [this].concat(lang._toArray(arguments)));
+ if(toWidget){
+ // perform view transition keeping the scroll position
+ if(this.keepScrollPos && !this.getParent()){
+ var scrollTop = win.body().scrollTop || win.doc.documentElement.scrollTop || win.global.pageYOffset || 0;
+ fromNode._scrollTop = scrollTop;
+ var toTop = (dir == 1) ? 0 : (toNode._scrollTop || 0);
+ toNode.style.top = "0px";
+ if(scrollTop > 1 || toTop !== 0){
+ fromNode.style.top = toTop - scrollTop + "px";
+ if(config["mblHideAddressBar"] !== false){
+ setTimeout(function(){ // iPhone needs setTimeout
+ win.global.scrollTo(0, (toTop || 1));
+ }, 0);
+ }
+ }
+ }else{
+ toNode.style.top = "0px";
+ }
+ toWidget.onBeforeTransitionIn.apply(toWidget, arguments);
+ connect.publish("/dojox/mobile/beforeTransitionIn", [toWidget].concat(lang._toArray(arguments)));
+ }
+ if(!this._aw){
+ toNode.style.display = "none";
+ toNode.style.visibility = "visible";
+ }
+
+ if(dm._iw && dm.scrollable){ // Workaround for iPhone flicker issue (only when scrollable.js is loaded)
+ var ss = dm.getScreenSize();
+ // Show cover behind the view.
+ // cover's z-index is set to -10000, lower than z-index value specified in transition css.
+ win.body().appendChild(dm._iwBgCover);
+ domStyle.set(dm._iwBgCover, {
+ position: "absolute",
+ top: "0px",
+ left: "0px",
+ height: (ss.h + 1) + "px", // "+1" means the height of scrollTo(0,1)
+ width: ss.w + "px",
+ backgroundColor: domStyle.get(win.body(), "background-color"),
+ zIndex: -10000,
+ display: ""
+ });
+ // Show toNode behind the cover.
+ domStyle.set(toNode, {
+ position: "absolute",
+ zIndex: -10001,
+ visibility: "visible",
+ display: ""
+ });
+ // setTimeout seems to be necessary to avoid flicker.
+ // Also the duration of setTimeout should be long enough to avoid flicker.
+ // 0 is not effective. 50 sometimes causes flicker.
+ setTimeout(lang.hitch(this, function(){
+ this._doTransition(fromNode, toNode, transition, dir);
+ }), 80);
+ }else{
+ this._doTransition(fromNode, toNode, transition, dir);
+ }
+ },
+ _toCls: function(s){
+ // convert from transition name to corresponding class name
+ // ex. "slide" -> "mblSlide"
+ return "mbl"+s.charAt(0).toUpperCase() + s.substring(1);
+ },
+
+ _doTransition: function(fromNode, toNode, transition, dir){
+ var rev = (dir == -1) ? " mblReverse" : "";
+ if(dm._iw && dm.scrollable){ // Workaround for iPhone flicker issue (only when scrollable.js is loaded)
+ // Show toNode after flicker ends
+ domStyle.set(toNode, {
+ position: "",
+ zIndex: ""
+ });
+ // Remove cover
+ win.body().removeChild(dm._iwBgCover);
+ }else if(!this._aw){
+ toNode.style.display = "";
+ }
+ if(!transition || transition == "none"){
+ this.domNode.style.display = "none";
+ this.invokeCallback();
+ }else if(config['mblCSS3Transition']){
+ //get dojox/css3/transit first
+ Deferred.when(transitDeferred, lang.hitch(this, function(transit){
+ //follow the style of .mblView.mblIn in View.css
+ //need to set the toNode to absolute position
+ var toPosition = domStyle.get(toNode, "position");
+ domStyle.set(toNode, "position", "absolute");
+ Deferred.when(transit(fromNode, toNode, {transition: transition, reverse: (dir===-1)?true:false}),lang.hitch(this,function(){
+ domStyle.set(toNode, "position", toPosition);
+ this.invokeCallback();
+ }));
+ }));
+ }else{
+ var s = this._toCls(transition);
+ domClass.add(fromNode, s + " mblOut" + rev);
+ domClass.add(toNode, s + " mblIn" + rev);
+ setTimeout(function(){
+ domClass.add(fromNode, "mblTransition");
+ domClass.add(toNode, "mblTransition");
+ }, 100);
+ // set transform origin
+ var fromOrigin = "50% 50%";
+ var toOrigin = "50% 50%";
+ var scrollTop, posX, posY;
+ if(transition.indexOf("swirl") != -1 || transition.indexOf("zoom") != -1){
+ if(this.keepScrollPos && !this.getParent()){
+ scrollTop = win.body().scrollTop || win.doc.documentElement.scrollTop || win.global.pageYOffset || 0;
+ }else{
+ scrollTop = -domGeometry.position(fromNode, true).y;
+ }
+ posY = win.global.innerHeight / 2 + scrollTop;
+ fromOrigin = "50% " + posY + "px";
+ toOrigin = "50% " + posY + "px";
+ }else if(transition.indexOf("scale") != -1){
+ var viewPos = domGeometry.position(fromNode, true);
+ posX = ((this.clickedPosX !== undefined) ? this.clickedPosX : win.global.innerWidth / 2) - viewPos.x;
+ if(this.keepScrollPos && !this.getParent()){
+ scrollTop = win.body().scrollTop || win.doc.documentElement.scrollTop || win.global.pageYOffset || 0;
+ }else{
+ scrollTop = -viewPos.y;
+ }
+ posY = ((this.clickedPosY !== undefined) ? this.clickedPosY : win.global.innerHeight / 2) + scrollTop;
+ fromOrigin = posX + "px " + posY + "px";
+ toOrigin = posX + "px " + posY + "px";
+ }
+ domStyle.set(fromNode, {webkitTransformOrigin:fromOrigin});
+ domStyle.set(toNode, {webkitTransformOrigin:toOrigin});
+ }
+ dm.currentView = registry.byNode(toNode);
+ },
+
+ onAnimationStart: function(e){
+ },
+
+
+ onAnimationEnd: function(e){
+ var name = e.animationName || e.target.className;
+ if(name.indexOf("Out") === -1 &&
+ name.indexOf("In") === -1 &&
+ name.indexOf("Shrink") === -1){ return; }
+ var isOut = false;
+ if(domClass.contains(this.domNode, "mblOut")){
+ isOut = true;
+ this.domNode.style.display = "none";
+ domClass.remove(this.domNode, [this._toCls(this._transition), "mblIn", "mblOut", "mblReverse"]);
+ }else{
+ // Reset the temporary padding
+ this.containerNode.style.paddingTop = "";
+ }
+ domStyle.set(this.domNode, {webkitTransformOrigin:""});
+ if(name.indexOf("Shrink") !== -1){
+ var li = e.target;
+ li.style.display = "none";
+ domClass.remove(li, "mblCloseContent");
+ }
+ if(isOut){
+ this.invokeCallback();
+ }
+ // this.domNode may be destroyed as a result of invoking the callback,
+ // so check for that before accessing it.
+ this.domNode && (this.domNode.className = "mblView");
+
+ // clear the clicked position
+ this.clickedPosX = this.clickedPosY = undefined;
+ },
+
+ invokeCallback: function(){
+ this.onAfterTransitionOut.apply(this, this._arguments);
+ connect.publish("/dojox/mobile/afterTransitionOut", [this].concat(this._arguments));
+ var toWidget = registry.byNode(this.toNode);
+ if(toWidget){
+ toWidget.onAfterTransitionIn.apply(toWidget, this._arguments);
+ connect.publish("/dojox/mobile/afterTransitionIn", [toWidget].concat(this._arguments));
+ toWidget.movedFrom = undefined;
+ }
+
+ var c = this._context, m = this._method;
+ if(!c && !m){ return; }
+ if(!m){
+ m = c;
+ c = null;
+ }
+ c = c || win.global;
+ if(typeof(m) == "string"){
+ c[m].apply(c, this._args);
+ }else{
+ m.apply(c, this._args);
+ }
+ },
+
+ getShowingView: function(){
+ // summary:
+ // Find the currently showing view from my sibling views.
+ // description:
+ // Note that dojox.mobile.currentView is the last shown view.
+ // If the page consists of a splitter, there are multiple showing views.
+ var nodes = this.domNode.parentNode.childNodes;
+ for(var i = 0; i < nodes.length; i++){
+ var n = nodes[i];
+ if(n.nodeType === 1 && domClass.contains(n, "mblView") && domStyle.get(n, "display") !== "none"){
+ return registry.byNode(n);
+ }
+ }
+ return null;
+ },
+
+ show: function(){
+ // summary:
+ // Shows this view without a transition animation.
+ var view = this.getShowingView();
+ if(view){
+ view.domNode.style.display = "none"; // from-style
+ }
+ this.domNode.style.display = ""; // to-style
+ dm.currentView = this;
+ }
+ });
+});