source: Dev/trunk/src/client/dojox/app/controllers/History.js

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

Added Dojo 1.9.3 release.

  • Property svn:executable set to *
File size: 4.5 KB
Line 
1define(["dojo/_base/lang", "dojo/_base/declare", "dojo/on", "../Controller", "../utils/hash", "dojo/topic"],
2function(lang, declare, on, Controller, hash, topic){
3        // module:
4        //              dojox/app/controllers/History
5        // summary:
6        //              Bind "app-domNode" event on dojox/app application instance.
7        //              Bind "startTransition" event on dojox/app application domNode.
8        //              Bind "popstate" event on window object.
9        //              Maintain history by HTML5 "pushState" method and "popstate" event.
10
11        return declare("dojox.app.controllers.History", Controller, {
12                // _currentPosition:     Integer
13                //              Persistent variable which indicates the current position/index in the history
14                //              (so as to be able to figure out whether the popState event was triggerd by
15                //              a backward or forward action).
16                _currentPosition: 0,
17
18                // currentState: Object
19                //              Current state
20                currentState: {},
21
22                constructor: function(){
23                        // summary:
24                        //              Bind "app-domNode" event on dojox/app application instance.
25                        //              Bind "startTransition" event on dojox/app application domNode.
26                        //              Bind "popstate" event on window object.
27                        //
28
29                        this.events = {
30                                "app-domNode": this.onDomNodeChange
31                        };
32                        if(this.app.domNode){
33                                this.onDomNodeChange({oldNode: null, newNode: this.app.domNode});
34                        }
35                        this.bind(window, "popstate", lang.hitch(this, this.onPopState));
36                },
37
38                onDomNodeChange: function(evt){
39                        if(evt.oldNode != null){
40                                this.unbind(evt.oldNode, "startTransition");
41                        }
42                        this.bind(evt.newNode, "startTransition", lang.hitch(this, this.onStartTransition));
43                },
44
45                onStartTransition: function(evt){
46                        // summary:
47                        //              Response to dojox/app "startTransition" event.
48                        //
49                        // example:
50                        //              Use "dojox/mobile/TransitionEvent" to trigger "startTransition" event, and this function will response the event. For example:
51                        //              |       var transOpts = {
52                        //              |               title:"List",
53                        //              |               target:"items,list",
54                        //              |               url: "#items,list",
55                        //              |               params: {"param1":"p1value"}
56                        //              |       };
57                        //              |       new TransitionEvent(domNode, transOpts, e).dispatch();
58                        //
59                        // evt: Object
60                        //              Transition options parameter
61                        var currentHash = window.location.hash;
62                        var currentView = hash.getTarget(currentHash, this.app.defaultView);
63                        var currentParams =  hash.getParams(currentHash);
64                        var _detail = lang.clone(evt.detail);
65                        _detail.target = _detail.title = currentView;
66                        _detail.url = currentHash;
67                        _detail.params = currentParams;
68                        _detail.id = this._currentPosition;
69
70                        // Create initial state if necessary
71                        if(history.length == 1){
72                                history.pushState(_detail, _detail.href, currentHash);
73                        }
74
75                        // Update the current state
76                        _detail.bwdTransition = _detail.transition;
77                        lang.mixin(this.currentState, _detail);
78                        history.replaceState(this.currentState, this.currentState.href, currentHash);
79
80                        // Create a new "current state" history entry
81                        this._currentPosition += 1;
82                        evt.detail.id = this._currentPosition;
83
84                        var newHash = evt.detail.url || "#" + evt.detail.target;
85
86                        if(evt.detail.params){
87                                newHash = hash.buildWithParams(newHash, evt.detail.params);
88                        }
89
90                        evt.detail.fwdTransition = evt.detail.transition;
91                        history.pushState(evt.detail, evt.detail.href, newHash);
92                        this.currentState = lang.clone(evt.detail);
93
94                        // Finally: Publish pushState topic
95                        topic.publish("/app/history/pushState", evt.detail.target);
96                },
97
98                onPopState: function(evt){
99                        // summary:
100                        //              Response to dojox/app "popstate" event.
101                        //
102                        // evt: Object
103                        //              Transition options parameter
104
105                        // Clean browser's cache and refresh the current page will trigger popState event,
106                        // but in this situation the application has not started and throws an error.
107                        // So we need to check application status, if application not STARTED, do nothing.
108                        if((this.app.getStatus() !== this.app.lifecycle.STARTED) || !evt.state ){
109                                return;
110                        }
111
112                        // Get direction of navigation and update _currentPosition accordingly
113                        var backward = evt.state.id < this._currentPosition;
114                        backward ? this._currentPosition -= 1 : this._currentPosition += 1;
115
116                        // Publish popState topic and transition to the target view. Important: Use correct transition.
117                        // Reverse transitionDir only if the user navigates backwards.
118                        var opts = lang.mixin({reverse: backward ? true : false}, evt.state);
119                        opts.transition = backward ? opts.bwdTransition : opts.fwdTransition;
120                        this.app.emit("app-transition", {
121                                viewId: evt.state.target,
122                                opts: opts
123                        });
124                        topic.publish("/app/history/popState", evt.state.target);
125                }
126        });
127});
Note: See TracBrowser for help on using the repository browser.