source: Dev/trunk/src/client/dojox/mobile/bookmarkable.js @ 532

Last change on this file since 532 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 4.6 KB
Line 
1define([
2        "dojo/_base/array",
3        "dojo/_base/connect",
4        "dojo/_base/lang",
5        "dojo/_base/window",
6        "dojo/hash",
7        "dijit/registry",
8        "./TransitionEvent",
9        "./View",
10        "./viewRegistry"
11], function(array, connect, lang, win, hash, registry, TransitionEvent, View, viewRegistry){
12
13        // module:
14        //              dojox/mobile/bookmarkable
15
16        var b = {
17                // summary:
18                //              Utilities to make the view transitions bookmarkable.
19
20                // settingHash: [private] Boolean
21                //              Whether the browser URL needs to be updated to include the hash.
22                settingHash: false,
23               
24                // transitionInfo: Array
25                //              An array containing information about the transition.
26                transitionInfo: [],
27
28                getTransitionInfo: function(/*String*/ fromViewId, /*String*/ toViewId){
29                        // summary:
30                        //              Returns an array containing the transition information.
31                        return this.transitionInfo[fromViewId.replace(/^#/, "") + ":" + toViewId.replace(/^#/, "")]; // Array
32                },
33
34                addTransitionInfo: function(/*String*/ fromViewId, /*String*/ toViewId, /*Object*/args){
35                        // summary:
36                        //              Adds transition information.
37                        this.transitionInfo[fromViewId.replace(/^#/, "") + ":" + toViewId.replace(/^#/, "")] = args;
38                },
39
40                findTransitionViews: function(/*String*/moveTo){
41                        // summary:
42                        //              Searches for a starting view and a destination view.
43                        if(!moveTo){ return []; }
44                        var view = registry.byId(moveTo.replace(/^#/, ""));
45                        if(!view){ return []; }
46                        for(var v = view.getParent(); v; v = v.getParent()){ // search for the topmost invisible parent node
47                                if(v.isVisible && !v.isVisible()){
48                                        view = v;
49                                }
50                        }
51                        // fromView, toView
52                        return [view.getShowingView(), view]; // Array
53                },
54
55                onHashChange: function(value){
56                        // summary:
57                        //              Called on "/dojo/hashchange" events.
58                        if(this.settingHash){
59                                this.settingHash = false;
60                                return;
61                        }
62                        var params = this.handleFragIds(value);
63                        params.hashchange = true;
64                        new TransitionEvent(win.body(), params).dispatch();
65                },
66
67                handleFragIds: function(/*String*/fragIds){
68                        // summary:
69                        //              Analyzes the given hash (fragment id).
70                        // description:
71                        //              Given a comma-separated list of view IDs, this method
72                        //              searches for a transition destination, and makes all the
73                        //              views in the hash visible.
74
75                        var arr, moveTo;
76                        if(!fragIds){
77                                moveTo = viewRegistry.initialView.id;
78                                arr = this.findTransitionViews(moveTo);
79                        }else{
80                                var ids = fragIds.replace(/^#/, "").split(/,/);
81                                for(var i = 0; i < ids.length; i++){
82                                        // Search for a transition destination view.
83
84                                        var view = registry.byId(ids[i]);
85
86                                        // Skip a visible view. Visible view can't be a destination candidate.
87                                        if(view.isVisible()){ continue; }
88
89                                        // Check if all the ancestors are in the fragIds.
90                                        // If not, obviously the view was NOT visible before the previous transition.
91                                        // That means the previous transition can't happen from that view,
92                                        // which means the view can't be a destination.
93                                        var success = true;
94                                        for(var v = viewRegistry.getParentView(view); v; v = viewRegistry.getParentView(v)){
95                                                if(array.indexOf(ids, v.id) === -1){
96                                                        success = false;
97                                                        break;
98                                                }
99                                        }
100                                        if(!success){
101                                                // Simply make the view visible without transition.
102                                                array.forEach(view.getSiblingViews(), function(v){
103                                                        v.domNode.style.display = (v === view) ? "" : "none";
104                                                });
105                                                continue;
106                                        }
107
108                                        arr = this.findTransitionViews(ids[i]);
109                                        if(arr.length === 2){
110                                                moveTo = ids[i];
111                                                // The destination found. But continue the loop to make
112                                                // the other views in the fragIds visible.
113                                        }
114                                }
115                        }
116
117                        var args = this.getTransitionInfo(arr[0].id, arr[1].id);
118                        var dir = 1;
119                        if(!args){
120                                args = this.getTransitionInfo(arr[1].id, arr[0].id);
121                                dir = -1;
122                        }
123
124                        return {
125                                moveTo: "#" + moveTo,
126                                transitionDir: args ? args.transitionDir * dir : 1,
127                                transition: args ? args.transition : "none"
128                        };
129                },
130
131                setFragIds: function(/*Widget*/toView){
132                        // summary:
133                        //              Updates the hash (fragment id) in the browser URL.
134                        // description:
135                        //              The hash value consists of one or more visible view ids
136                        //              separated with commas.
137
138                        var arr = array.filter(viewRegistry.getViews(), function(v){ return v.isVisible(); });
139                        this.settingHash = true;
140                        hash(array.map(arr, function(v){ return v.id; }).join(","));
141                }
142        };
143
144        connect.subscribe("/dojo/hashchange", null, function(){ b.onHashChange.apply(b, arguments); });
145
146        lang.extend(View, {
147                getTransitionInfo: function(){ b.getTransitionInfo.apply(b, arguments); },
148                addTransitionInfo: function(){ b.addTransitionInfo.apply(b, arguments); },
149                handleFragIds: function(){ b.handleFragIds.apply(b, arguments); },
150                setFragIds: function(){ b.setFragIds.apply(b, arguments); }
151        });
152
153        return b;
154});
Note: See TracBrowser for help on using the repository browser.