source: Dev/trunk/src/client/qed-client/app/Router.js

Last change on this file was 536, checked in by hendrikvanantwerpen, 10 years ago

Not sure what this fix was for.

File size: 4.6 KB
Line 
1define([
2    "./Content",
3    "./Path",
4    "dojo/_base/declare",
5    "dojo/_base/event",
6    "dojo/_base/lang",
7    "dojo/hash",
8    "dojo/on",
9    "dojo/topic",
10    "require"
11], function(Content, Path, declare, event, lang, hash, on, topic, require) {
12
13    var Router = declare(null,{
14        _started: false,
15        _routes: null,
16        _previousHash: null,
17        _beforePreviousHash: null,
18
19        constructor: function() {
20            this._routes = [];
21        },
22        startup: function() {
23            if ( this._started ) { return; }
24            Content.startup();
25            this._started = true;
26            if ( hash() === "" ) {
27                hash(Path.getDefault());
28            }
29            this._handleHashChange(hash());
30            window.onbeforeunload = function(evt) {
31                var msg;
32                if ( Content.isDirty() ) {
33                    msg = "Unsaved changes, leave anyway?";
34                    evt.returnValue = msg;
35                }
36                return msg;
37            };
38                        topic.subscribe("/dojo/hashchange",
39                            lang.hitch(this,'_handleHashChange'));
40        },
41        register: function(route) {
42            if ( this._started ) {
43                console.warn('Registering routes after startup() is called is discouraged.');
44            }
45            var callback = this._normalizeCallback(route);
46            if ( callback ) {
47                if ( route.path ) {
48                    route.callback = callback;
49                    route.path = new Path(route.path);
50                    this._routes.push(route);
51                } else {
52                    this._defaultCallback = callback;
53                }
54            } else {
55                console.warn("Route "+(route.path||"default")+" has no action.");
56            }
57        },
58        _normalizeCallback: function(route) {
59            var self = this;
60            var callback = null;
61            if ( route.callback ) {
62                callback = function(params){
63                    Content.set(route.callback(params));
64                };
65            } else if ( route.redirect ) {
66                callback = function(params){
67                    self.go(route.redirect);
68                };
69            } else if ( route.constructor ) {
70                callback = function(params){
71                    Content.set( new route.constructor(params) );
72                };
73            }
74            return callback;
75        },
76        _handleHashChange: function(newHash) {
77            if ( this._previousHash === newHash ) {
78                return false;
79            }
80            if ( Content.isDirty() ) {
81                if ( !confirm("Unsaved changes, leave anyway?") ) {
82                    var probablyBack = this._beforePreviousHash === newHash;
83                    // if we think we go backwards, we re-add the history
84                    // entry, otherwise we reset the current one,
85                    // resulting in minor annoyance of double back
86                    // behaviour.
87                    hash(this._previousHash,!probablyBack);
88                    return false;
89                } else {
90                    Content.markClean();
91                }
92            }
93            this._beforePreviousHash = this._previousHash;
94            this._previousHash = newHash;
95            for (var i = this._routes.length-1; i >= 0; i--) {
96                var route = this._routes[i];
97                var params = null;
98                if ((params = route.path.match(newHash)) !== null) {
99                    try {
100                        route.callback(params);
101                    } catch(err) {
102                        console.error("Page change failed with",err,err.stack,err.toString());
103                    }
104                    return true;
105                }
106            }
107            try {
108                this._defaultCallback();
109            } catch(err) {
110                console.error("Default page failed.",err);
111            }
112            return true;
113        },
114        go: function(path,args,replace) {
115            if ( !this._started ) { return; }
116            var newHash = Path.format(path,args);
117            if ( replace === true ) {
118                this._beforePreviousHash = this._previousHash;
119                this._previousHash = newHash;
120            }
121            hash(newHash,replace);
122        },
123        _defaultCallback: function() {
124            var Page = require("./Page");
125            Content.set(new Page({
126                templateString: "<div>Requested page not found. Go <a href=\"#"+Path.getDefault()+"\">home</a>.</div>"
127            }));
128        }
129    });
130
131    return new Router();
132});
Note: See TracBrowser for help on using the repository browser.