source: Dev/branches/rest-dojo-ui/client/dojox/mobile/Heading.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 8.2 KB
Line 
1define([
2        "dojo/_base/array",
3        "dojo/_base/connect",
4        "dojo/_base/declare",
5        "dojo/_base/lang",
6        "dojo/_base/window",
7        "dojo/dom-class",
8        "dojo/dom-construct",
9        "dojo/dom-style",
10        "dijit/registry",       // registry.byId
11        "dijit/_Contained",
12        "dijit/_Container",
13        "dijit/_WidgetBase",
14        "./View"
15], function(array, connect, declare, lang, win, domClass, domConstruct, domStyle, registry, Contained, Container, WidgetBase, View){
16
17        var dm = lang.getObject("dojox.mobile", true);
18
19/*=====
20        var Contained = dijit._Contained;
21        var Container = dijit._Container;
22        var WidgetBase = dijit._WidgetBase;
23=====*/
24
25        // module:
26        //              dojox/mobile/Heading
27        // summary:
28        //              A widget that represents a navigation bar.
29
30        return declare("dojox.mobile.Heading", [WidgetBase, Container, Contained],{
31                // summary:
32                //              A widget that represents a navigation bar.
33                // description:
34                //              Heading is a widget that represents a navigation bar, which
35                //              usually appears at the top of an application. It usually
36                //              displays the title of the current view and can contain a
37                //              navigational control. If you use it with
38                //              dojox.mobile.ScrollableView, it can also be used as a fixed
39                //              header bar or a fixed footer bar. In such cases, specify the
40                //              fixed="top" attribute to be a fixed header bar or the
41                //              fixed="bottom" attribute to be a fixed footer bar. Heading can
42                //              have one or more ToolBarButton widgets as its children.
43
44                // back: String
45                //              A label for the navigational control to return to the previous
46                //              View.
47                back: "",
48
49                // href: String
50                //              A URL to open when the navigational control is pressed.
51                href: "",
52
53                // moveTo: String
54                //              The id of the transition destination view which resides in the
55                //              current page.
56                //
57                //              If the value has a hash sign ('#') before the id (e.g. #view1)
58                //              and the dojo.hash module is loaded by the user application, the
59                //              view transition updates the hash in the browser URL so that the
60                //              user can bookmark the destination view. In this case, the user
61                //              can also use the browser's back/forward button to navigate
62                //              through the views in the browser history.
63                //
64                //              If null, transitions to a blank view.
65                //              If '#', returns immediately without transition.
66                moveTo: "",
67
68                // transition: String
69                //              A type of animated transition effect. You can choose from the
70                //              standard transition types, "slide", "fade", "flip", or from the
71                //              extended transition types, "cover", "coverv", "dissolve",
72                //              "reveal", "revealv", "scaleIn", "scaleOut", "slidev",
73                //              "swirl", "zoomIn", "zoomOut". If "none" is specified, transition
74                //              occurs immediately without animation.
75                transition: "slide",
76
77                // label: String
78                //              A title text of the heading. If the label is not specified, the
79                //              innerHTML of the node is used as a label.
80                label: "",
81
82                // iconBase: String
83                //              The default icon path for child items.
84                iconBase: "",
85
86                // backProp: Object
87                //              Properties for the back button.
88                backProp: {className: "mblArrowButton"},
89
90                // tag: String
91                //              A name of html tag to create as domNode.
92                tag: "H1",
93
94                buildRendering: function(){
95                        this.domNode = this.containerNode = this.srcNodeRef || win.doc.createElement(this.tag);
96                        this.domNode.className = "mblHeading";
97                        if(!this.label){
98                                array.forEach(this.domNode.childNodes, function(n){
99                                        if(n.nodeType == 3){
100                                                var v = lang.trim(n.nodeValue);
101                                                if(v){
102                                                        this.label = v;
103                                                        this.labelNode = domConstruct.create("SPAN", {innerHTML:v}, n, "replace");
104                                                }
105                                        }
106                                }, this);
107                        }
108                        if(!this.labelNode){
109                                this.labelNode = domConstruct.create("SPAN", null, this.domNode);
110                        }
111                        this.labelNode.className = "mblHeadingSpanTitle";
112                        this.labelDivNode = domConstruct.create("DIV", {
113                                className: "mblHeadingDivTitle",
114                                innerHTML: this.labelNode.innerHTML
115                        }, this.domNode);
116                },
117
118                startup: function(){
119                        if(this._started){ return; }
120                        var parent = this.getParent && this.getParent();
121                        if(!parent || !parent.resize){ // top level widget
122                                var _this = this;
123                                setTimeout(function(){ // necessary to render correctly
124                                        _this.resize();
125                                }, 0);
126                        }
127                        this.inherited(arguments);
128                },
129       
130                resize: function(){
131                        if(this._btn){
132                                this._btn.style.width = this._body.offsetWidth + this._head.offsetWidth + "px";
133                        }
134                        if(this.labelNode){
135                                // find the rightmost left button (B), and leftmost right button (C)
136                                // +-----------------------------+
137                                // | |A| |B|             |C| |D| |
138                                // +-----------------------------+
139                                var leftBtn, rightBtn;
140                                var children = this.containerNode.childNodes;
141                                for(var i = children.length - 1; i >= 0; i--){
142                                        var c = children[i];
143                                        if(c.nodeType === 1){
144                                                if(!rightBtn && domClass.contains(c, "mblToolBarButton") && domStyle.get(c, "float") === "right"){
145                                                        rightBtn = c;
146                                                }
147                                                if(!leftBtn && (domClass.contains(c, "mblToolBarButton") && domStyle.get(c, "float") === "left" || c === this._btn)){
148                                                        leftBtn = c;
149                                                }
150                                        }
151                                }
152
153                                if(!this.labelNodeLen && this.label){
154                                        this.labelNode.style.display = "inline";
155                                        this.labelNodeLen = this.labelNode.offsetWidth;
156                                        this.labelNode.style.display = "";
157                                }
158
159                                var bw = this.domNode.offsetWidth; // bar width
160                                var rw = rightBtn ? bw - rightBtn.offsetLeft + 5 : 0; // rightBtn width
161                                var lw = leftBtn ? leftBtn.offsetLeft + leftBtn.offsetWidth + 5 : 0; // leftBtn width
162                                var tw = this.labelNodeLen || 0; // title width
163                                domClass[bw - Math.max(rw,lw)*2 > tw ? "add" : "remove"](this.domNode, "mblHeadingCenterTitle");
164                        }
165                        array.forEach(this.getChildren(), function(child){
166                                if(child.resize){ child.resize(); }
167                        });
168                },
169
170                _setBackAttr: function(/*String*/back){
171                        if (!back){
172                                domConstruct.destroy(this._btn);
173                                this._btn = null;
174                                this.back = "";
175                        }else{
176                                if(!this._btn){
177                                        var btn = domConstruct.create("DIV", this.backProp, this.domNode, "first");
178                                        var head = domConstruct.create("DIV", {className:"mblArrowButtonHead"}, btn);
179                                        var body = domConstruct.create("DIV", {className:"mblArrowButtonBody mblArrowButtonText"}, btn);
180
181                                        this._body = body;
182                                        this._head = head;
183                                        this._btn = btn;
184                                        this.backBtnNode = btn;
185                                        this.connect(body, "onclick", "onClick");
186                                }
187                                this.back = back;
188                                this._body.innerHTML = this._cv ? this._cv(this.back) : this.back;
189                        }
190                        this.resize();
191                },
192       
193                _setLabelAttr: function(/*String*/label){
194                        this.label = label;
195                        this.labelNode.innerHTML = this.labelDivNode.innerHTML = this._cv ? this._cv(label) : label;
196                },
197       
198                findCurrentView: function(){
199                        // summary:
200                        //              Search for the view widget that contains this widget.
201                        var w = this;
202                        while(true){
203                                w = w.getParent();
204                                if(!w){ return null; }
205                                if(w instanceof View){ break; }
206                        }
207                        return w;
208                },
209
210                onClick: function(e){
211                        var h1 = this.domNode;
212                        domClass.add(h1, "mblArrowButtonSelected");
213                        setTimeout(function(){
214                                domClass.remove(h1, "mblArrowButtonSelected");
215                        }, 1000);
216
217                        if(this.back && !this.moveTo && !this.href && history){
218                                history.back();
219                                return;
220                        }       
221       
222                        // keep the clicked position for transition animations
223                        var view = this.findCurrentView();
224                        if(view){
225                                view.clickedPosX = e.clientX;
226                                view.clickedPosY = e.clientY;
227                        }
228                        this.goTo(this.moveTo, this.href);
229                },
230       
231                goTo: function(moveTo, href){
232                        // summary:
233                        //              Given the destination, makes a view transition.
234                        var view = this.findCurrentView();
235                        if(!view){ return; }
236                        if(href){
237                                view.performTransition(null, -1, this.transition, this, function(){location.href = href;});
238                        }else{
239                                if(dm.app && dm.app.STAGE_CONTROLLER_ACTIVE){
240                                        // If in a full mobile app, then use its mechanisms to move back a scene
241                                        connect.publish("/dojox/mobile/app/goback");
242                                }else{
243                                        // Basically transition should be performed between two
244                                        // siblings that share the same parent.
245                                        // However, when views are nested and transition occurs from
246                                        // an inner view, search for an ancestor view that is a sibling
247                                        // of the target view, and use it as a source view.
248                                        var node = registry.byId(view.convertToId(moveTo));
249                                        if(node){
250                                                var parent = node.getParent();
251                                                while(view){
252                                                        var myParent = view.getParent();
253                                                        if(parent === myParent){
254                                                                break;
255                                                        }
256                                                        view = myParent;
257                                                }
258                                        }
259                                        if(view){
260                                                view.performTransition(moveTo, -1, this.transition);
261                                        }
262                                }
263                        }
264                }
265        });
266});
Note: See TracBrowser for help on using the repository browser.