268 lines
8.3 KiB
JavaScript
268 lines
8.3 KiB
JavaScript
//>>built
|
|
define("dojox/mobile/Heading", [
|
|
"dojo/_base/array",
|
|
"dojo/_base/connect",
|
|
"dojo/_base/declare",
|
|
"dojo/_base/lang",
|
|
"dojo/_base/window",
|
|
"dojo/dom-class",
|
|
"dojo/dom-construct",
|
|
"dojo/dom-style",
|
|
"dijit/registry", // registry.byId
|
|
"dijit/_Contained",
|
|
"dijit/_Container",
|
|
"dijit/_WidgetBase",
|
|
"./View"
|
|
], function(array, connect, declare, lang, win, domClass, domConstruct, domStyle, registry, Contained, Container, WidgetBase, View){
|
|
|
|
var dm = lang.getObject("dojox.mobile", true);
|
|
|
|
/*=====
|
|
var Contained = dijit._Contained;
|
|
var Container = dijit._Container;
|
|
var WidgetBase = dijit._WidgetBase;
|
|
=====*/
|
|
|
|
// module:
|
|
// dojox/mobile/Heading
|
|
// summary:
|
|
// A widget that represents a navigation bar.
|
|
|
|
return declare("dojox.mobile.Heading", [WidgetBase, Container, Contained],{
|
|
// summary:
|
|
// A widget that represents a navigation bar.
|
|
// description:
|
|
// Heading is a widget that represents a navigation bar, which
|
|
// usually appears at the top of an application. It usually
|
|
// displays the title of the current view and can contain a
|
|
// navigational control. If you use it with
|
|
// dojox.mobile.ScrollableView, it can also be used as a fixed
|
|
// header bar or a fixed footer bar. In such cases, specify the
|
|
// fixed="top" attribute to be a fixed header bar or the
|
|
// fixed="bottom" attribute to be a fixed footer bar. Heading can
|
|
// have one or more ToolBarButton widgets as its children.
|
|
|
|
// back: String
|
|
// A label for the navigational control to return to the previous
|
|
// View.
|
|
back: "",
|
|
|
|
// href: String
|
|
// A URL to open when the navigational control is pressed.
|
|
href: "",
|
|
|
|
// 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: "",
|
|
|
|
// 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: "slide",
|
|
|
|
// label: String
|
|
// A title text of the heading. If the label is not specified, the
|
|
// innerHTML of the node is used as a label.
|
|
label: "",
|
|
|
|
// iconBase: String
|
|
// The default icon path for child items.
|
|
iconBase: "",
|
|
|
|
// backProp: Object
|
|
// Properties for the back button.
|
|
backProp: {className: "mblArrowButton"},
|
|
|
|
// tag: String
|
|
// A name of html tag to create as domNode.
|
|
tag: "H1",
|
|
|
|
buildRendering: function(){
|
|
this.domNode = this.containerNode = this.srcNodeRef || win.doc.createElement(this.tag);
|
|
this.domNode.className = "mblHeading";
|
|
if(!this.label){
|
|
array.forEach(this.domNode.childNodes, function(n){
|
|
if(n.nodeType == 3){
|
|
var v = lang.trim(n.nodeValue);
|
|
if(v){
|
|
this.label = v;
|
|
this.labelNode = domConstruct.create("SPAN", {innerHTML:v}, n, "replace");
|
|
}
|
|
}
|
|
}, this);
|
|
}
|
|
if(!this.labelNode){
|
|
this.labelNode = domConstruct.create("SPAN", null, this.domNode);
|
|
}
|
|
this.labelNode.className = "mblHeadingSpanTitle";
|
|
this.labelDivNode = domConstruct.create("DIV", {
|
|
className: "mblHeadingDivTitle",
|
|
innerHTML: this.labelNode.innerHTML
|
|
}, this.domNode);
|
|
},
|
|
|
|
startup: function(){
|
|
if(this._started){ return; }
|
|
var parent = this.getParent && this.getParent();
|
|
if(!parent || !parent.resize){ // top level widget
|
|
var _this = this;
|
|
setTimeout(function(){ // necessary to render correctly
|
|
_this.resize();
|
|
}, 0);
|
|
}
|
|
this.inherited(arguments);
|
|
},
|
|
|
|
resize: function(){
|
|
if(this._btn){
|
|
this._btn.style.width = this._body.offsetWidth + this._head.offsetWidth + "px";
|
|
}
|
|
if(this.labelNode){
|
|
// find the rightmost left button (B), and leftmost right button (C)
|
|
// +-----------------------------+
|
|
// | |A| |B| |C| |D| |
|
|
// +-----------------------------+
|
|
var leftBtn, rightBtn;
|
|
var children = this.containerNode.childNodes;
|
|
for(var i = children.length - 1; i >= 0; i--){
|
|
var c = children[i];
|
|
if(c.nodeType === 1){
|
|
if(!rightBtn && domClass.contains(c, "mblToolBarButton") && domStyle.get(c, "float") === "right"){
|
|
rightBtn = c;
|
|
}
|
|
if(!leftBtn && (domClass.contains(c, "mblToolBarButton") && domStyle.get(c, "float") === "left" || c === this._btn)){
|
|
leftBtn = c;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!this.labelNodeLen && this.label){
|
|
this.labelNode.style.display = "inline";
|
|
this.labelNodeLen = this.labelNode.offsetWidth;
|
|
this.labelNode.style.display = "";
|
|
}
|
|
|
|
var bw = this.domNode.offsetWidth; // bar width
|
|
var rw = rightBtn ? bw - rightBtn.offsetLeft + 5 : 0; // rightBtn width
|
|
var lw = leftBtn ? leftBtn.offsetLeft + leftBtn.offsetWidth + 5 : 0; // leftBtn width
|
|
var tw = this.labelNodeLen || 0; // title width
|
|
domClass[bw - Math.max(rw,lw)*2 > tw ? "add" : "remove"](this.domNode, "mblHeadingCenterTitle");
|
|
}
|
|
array.forEach(this.getChildren(), function(child){
|
|
if(child.resize){ child.resize(); }
|
|
});
|
|
},
|
|
|
|
_setBackAttr: function(/*String*/back){
|
|
if (!back){
|
|
domConstruct.destroy(this._btn);
|
|
this._btn = null;
|
|
this.back = "";
|
|
}else{
|
|
if(!this._btn){
|
|
var btn = domConstruct.create("DIV", this.backProp, this.domNode, "first");
|
|
var head = domConstruct.create("DIV", {className:"mblArrowButtonHead"}, btn);
|
|
var body = domConstruct.create("DIV", {className:"mblArrowButtonBody mblArrowButtonText"}, btn);
|
|
|
|
this._body = body;
|
|
this._head = head;
|
|
this._btn = btn;
|
|
this.backBtnNode = btn;
|
|
this.connect(body, "onclick", "onClick");
|
|
}
|
|
this.back = back;
|
|
this._body.innerHTML = this._cv ? this._cv(this.back) : this.back;
|
|
}
|
|
this.resize();
|
|
},
|
|
|
|
_setLabelAttr: function(/*String*/label){
|
|
this.label = label;
|
|
this.labelNode.innerHTML = this.labelDivNode.innerHTML = this._cv ? this._cv(label) : label;
|
|
},
|
|
|
|
findCurrentView: function(){
|
|
// summary:
|
|
// Search for the view widget that contains this widget.
|
|
var w = this;
|
|
while(true){
|
|
w = w.getParent();
|
|
if(!w){ return null; }
|
|
if(w instanceof View){ break; }
|
|
}
|
|
return w;
|
|
},
|
|
|
|
onClick: function(e){
|
|
var h1 = this.domNode;
|
|
domClass.add(h1, "mblArrowButtonSelected");
|
|
setTimeout(function(){
|
|
domClass.remove(h1, "mblArrowButtonSelected");
|
|
}, 1000);
|
|
|
|
if(this.back && !this.moveTo && !this.href && history){
|
|
history.back();
|
|
return;
|
|
}
|
|
|
|
// keep the clicked position for transition animations
|
|
var view = this.findCurrentView();
|
|
if(view){
|
|
view.clickedPosX = e.clientX;
|
|
view.clickedPosY = e.clientY;
|
|
}
|
|
this.goTo(this.moveTo, this.href);
|
|
},
|
|
|
|
goTo: function(moveTo, href){
|
|
// summary:
|
|
// Given the destination, makes a view transition.
|
|
var view = this.findCurrentView();
|
|
if(!view){ return; }
|
|
if(href){
|
|
view.performTransition(null, -1, this.transition, this, function(){location.href = href;});
|
|
}else{
|
|
if(dm.app && dm.app.STAGE_CONTROLLER_ACTIVE){
|
|
// If in a full mobile app, then use its mechanisms to move back a scene
|
|
connect.publish("/dojox/mobile/app/goback");
|
|
}else{
|
|
// Basically transition should be performed between two
|
|
// siblings that share the same parent.
|
|
// However, when views are nested and transition occurs from
|
|
// an inner view, search for an ancestor view that is a sibling
|
|
// of the target view, and use it as a source view.
|
|
var node = registry.byId(view.convertToId(moveTo));
|
|
if(node){
|
|
var parent = node.getParent();
|
|
while(view){
|
|
var myParent = view.getParent();
|
|
if(parent === myParent){
|
|
break;
|
|
}
|
|
view = myParent;
|
|
}
|
|
}
|
|
if(view){
|
|
view.performTransition(moveTo, -1, this.transition);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
});
|