Skip to content

Commit d925d1c

Browse files
committed
3.4.1
1 parent b1770bd commit d925d1c

File tree

2 files changed

+6095
-0
lines changed

2 files changed

+6095
-0
lines changed

dist/amd/can-route-pushstate.js

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
/*can-route-pushstate@3.4.0#can-route-pushstate*/
2+
define([
3+
'require',
4+
'exports',
5+
'module',
6+
'can-util/js/is-node',
7+
'can-util/js/assign',
8+
'can-util/js/each',
9+
'can-util/js/make-array',
10+
'can-util/js/diff-object',
11+
'can-util/namespace',
12+
'can-globals/location',
13+
'can-event',
14+
'can-route'
15+
], function (require, exports, module) {
16+
(function (global, require, exports, module) {
17+
'use strict';
18+
var isNode = require('can-util/js/is-node');
19+
var extend = require('can-util/js/assign');
20+
var each = require('can-util/js/each');
21+
var makeArray = require('can-util/js/make-array');
22+
var diffObject = require('can-util/js/diff-object');
23+
var namespace = require('can-util/namespace');
24+
var LOCATION = require('can-globals/location');
25+
var canEvent = require('can-event');
26+
var route = require('can-route');
27+
var hasPushstate = window.history && window.history.pushState;
28+
var loc = LOCATION();
29+
var validProtocols = {
30+
'http:': true,
31+
'https:': true,
32+
'': true
33+
};
34+
var usePushStateRouting = hasPushstate && loc && validProtocols[loc.protocol];
35+
if (usePushStateRouting) {
36+
route.bindings.pushstate = {
37+
root: '/',
38+
matchSlashes: false,
39+
paramsMatcher: /^\?(?:[^=]+=[^&]*&)*[^=]+=[^&]*/,
40+
querySeparator: '?',
41+
bind: function () {
42+
if (isNode()) {
43+
return;
44+
}
45+
canEvent.on.call(document.documentElement, 'click', 'a', anchorClickHandler);
46+
each(methodsToOverwrite, function (method) {
47+
originalMethods[method] = window.history[method];
48+
window.history[method] = function (state, title, url) {
49+
var absolute = url.indexOf('http') === 0;
50+
var loc = LOCATION();
51+
var searchHash = loc.search + loc.hash;
52+
if (!absolute && url !== loc.pathname + searchHash || absolute && url !== loc.href + searchHash) {
53+
originalMethods[method].apply(window.history, arguments);
54+
route.setState();
55+
}
56+
};
57+
});
58+
canEvent.on.call(window, 'popstate', route.setState);
59+
},
60+
unbind: function () {
61+
canEvent.off.call(document.documentElement, 'click', 'a', anchorClickHandler);
62+
each(methodsToOverwrite, function (method) {
63+
window.history[method] = originalMethods[method];
64+
});
65+
canEvent.off.call(window, 'popstate', route.setState);
66+
},
67+
matchingPartOfURL: function () {
68+
var root = cleanRoot(), location = LOCATION(), loc = location.pathname + location.search, index = loc.indexOf(root);
69+
return loc.substr(index + root.length);
70+
},
71+
setURL: function (path, newProps, oldProps) {
72+
var method = 'pushState';
73+
var changed;
74+
if (includeHash && path.indexOf('#') === -1 && window.location.hash) {
75+
path += window.location.hash;
76+
}
77+
changed = diffObject(oldProps, newProps).map(function (d) {
78+
return d.property;
79+
});
80+
if (replaceStateAttrs.length > 0) {
81+
var toRemove = [];
82+
for (var i = 0, l = changed.length; i < l; i++) {
83+
if (replaceStateAttrs.indexOf(changed[i]) !== -1) {
84+
method = 'replaceState';
85+
}
86+
if (replaceStateAttrs.once && replaceStateAttrs.once.indexOf(changed[i]) !== -1) {
87+
toRemove.push(changed[i]);
88+
}
89+
}
90+
if (toRemove.length > 0) {
91+
removeAttrs(replaceStateAttrs, toRemove);
92+
removeAttrs(replaceStateAttrs.once, toRemove);
93+
}
94+
}
95+
window.history[method](null, null, route._call('root') + path);
96+
}
97+
};
98+
var anchorClickHandler = function (e) {
99+
if (!(e.isDefaultPrevented ? e.isDefaultPrevented() : e.defaultPrevented === true)) {
100+
var node = this._node || this;
101+
var linksHost = node.host || window.location.host;
102+
if (node.href === 'javascript://') {
103+
return;
104+
}
105+
if (window.location.host === linksHost) {
106+
var root = cleanRoot();
107+
if (node.pathname.indexOf(root) === 0) {
108+
var nodePathWithSearch = node.pathname + node.search;
109+
var url = nodePathWithSearch.substr(root.length);
110+
var curParams = route.deparam(url);
111+
if (curParams.hasOwnProperty('route')) {
112+
includeHash = true;
113+
var windowPathWithSearch = window.location.pathname + window.location.search;
114+
var shouldCallPreventDefault = nodePathWithSearch !== windowPathWithSearch || node.hash === window.location.hash;
115+
window.history.pushState(null, null, node.href);
116+
if (shouldCallPreventDefault && e.preventDefault) {
117+
e.preventDefault();
118+
}
119+
}
120+
}
121+
}
122+
}
123+
}, cleanRoot = function () {
124+
var domain = location.protocol + '//' + location.host, root = route._call('root'), index = root.indexOf(domain);
125+
if (index === 0) {
126+
return root.substr(domain.length);
127+
}
128+
return root;
129+
}, removeAttrs = function (arr, attrs) {
130+
var index;
131+
for (var i = attrs.length - 1; i >= 0; i--) {
132+
if ((index = arr.indexOf(attrs[i])) !== -1) {
133+
arr.splice(index, 1);
134+
}
135+
}
136+
}, methodsToOverwrite = [
137+
'pushState',
138+
'replaceState'
139+
], originalMethods = {}, includeHash = true, replaceStateAttrs = [];
140+
route.defaultBinding = 'pushstate';
141+
extend(route, {
142+
replaceStateOn: function () {
143+
var attrs = makeArray(arguments);
144+
Array.prototype.push.apply(replaceStateAttrs, attrs);
145+
},
146+
replaceStateOnce: function () {
147+
var attrs = makeArray(arguments);
148+
replaceStateAttrs.once = makeArray(replaceStateAttrs.once);
149+
Array.prototype.push.apply(replaceStateAttrs.once, attrs);
150+
route.replaceStateOn.apply(this, arguments);
151+
},
152+
replaceStateOff: function () {
153+
var attrs = makeArray(arguments);
154+
removeAttrs(replaceStateAttrs, attrs);
155+
}
156+
});
157+
}
158+
module.exports = namespace.route = route;
159+
}(function () {
160+
return this;
161+
}(), require, exports, module));
162+
});

0 commit comments

Comments
 (0)