webui-aria2/js/libs/dojox/mobile/Heading.js.uncompressed.js
2012-05-01 19:52:07 +08:00

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);
}
}
}
}
});
});