1 | define([ |
---|
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 | }); |
---|