/
History.js
112 lines (85 loc) · 2.35 KB
/
History.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/*
---
name: History
description: History Management via popstate or hashchange.
authors: Christoph Pojer (@cpojer)
license: MIT-style license.
requires: [Core/Events, Core/Element.Event, Class-Extras/Class.Binds]
provides: History
...
*/
(function(){
var events = Element.NativeEvents,
location = window.location,
getUrlPart = function(url){
if(url.substr(0,8) == 'https://' || url.substr(0,7) == 'http://'){
url = '/'+url.split('/').slice(3).join('/');
}
return url.split('#')[0];
},
base = getUrlPart(location.href),
history = window.history,
hasPushState = ('pushState' in history),
event = hasPushState ? 'popstate' : 'hashchange';
this.History = new new Class({
Implements: [Class.Binds, Events],
initialize: hasPushState ? function(){
events[event] = 2;
window.addEvent(event, this.bound('pop'));
} : function(){
events[event] = 1;
window.addEvent(event, this.bound('pop'));
this.hash = location.hash;
var hashchange = ('onhashchange' in window);
if (!(hashchange && (document.documentMode === undefined || document.documentMode > 7)))
this.timer = this.check.periodical(200, this);
},
getUrlPart: getUrlPart,
push: hasPushState ? function(url, title, state){
url = getUrlPart(url);
if (base && base != url) base = null;
history.pushState(state || null, title || null, url);
this.onChange(url, state);
} : function(url){
location.hash = getUrlPart(url);
},
replace: hasPushState ? function(url, title, state){
history.replaceState(state || null, title || null, getUrlPart(url));
} : function(url){
url = getUrlPart(url);
this.hash = '#' + url;
this.push(url);
},
pop: hasPushState ? function(event){
var url = getUrlPart(location.href);
if (url == base){
base = null;
return;
}
this.onChange(url, event.event.state);
} : function(){
var hash = location.hash;
if (this.hash == hash) return;
this.hash = hash;
this.onChange(getUrlPart(hash.substr(1)));
},
onChange: function(url, state){
this.fireEvent('change', [url, state || {}]);
},
back: function(){
history.back();
},
forward: function(){
history.forward();
},
getPath: function(){
return hasPushState ? getUrlPart(location.href) : getUrlPart(location.hash.substr(1));
},
hasPushState: function(){
return hasPushState;
},
check: function(){
if (this.hash != location.hash) this.pop();
}
});
}).call(this);