Fix #153 and Improve pushState navigation

This commit is contained in:
Samy Pessé
2014-04-25 15:12:19 +02:00
parent b8a3d0e254
commit 47e9506397
3 changed files with 60 additions and 12 deletions
+12 -11
View File
@@ -1,32 +1,34 @@
define([
"jQuery",
"utils/path",
"core/events",
"core/state",
"core/search",
"core/progress",
"core/exercise",
"core/quiz"
], function($, events, state, search, progress, exercises, quiz) {
], function($, path, events, state, search, progress, exercises, quiz) {
var prev, next;
var githubCountStars, githubCountWatch;
var usePushState = !navigator.userAgent.match('CriOS') && (typeof history.pushState !== "undefined");
var usePushState = (typeof history.pushState !== "undefined");
var updateHistory = function(url, title) {
history.pushState({ path: url }, title, url);
};
var handleNavigation = function(relativeUrl, push) {
var url = path.isAbsolute(relativeUrl) ? relativeUrl : path.join(path.dirname(window.location.pathname), relativeUrl);
console.log("navigate to ", url, "baseurl="+relativeUrl);
var handleNavigation = function(url, push) {
if (!usePushState) {
// Refresh the page to the new URL if pushState not supported
location.href = url;
location.href = relativeUrl;
return
}
return $.get(url)
.done(function (html) {
if (push) updateHistory(url, null);
// Push url to history
if (push) history.pushState({ path: url }, null, url);
// Replace html content
html = html.replace( /<(\/?)(html|head|body)([^>]*)>/ig, function(a,b,c,d){
return '<' + b + 'div' + ( b ? '' : ' data-element="' + c + '"' ) + d + '>';
});
@@ -55,8 +57,8 @@ define([
state.update($("html"));
preparePage();
})
.fail(function () {
location.href = url;
.fail(function (e) {
location.href = relativeUrl;
});
};
@@ -148,7 +150,6 @@ define([
if (event.state === null) {
return;
}
return handleNavigation(event.state.path, false);
};
+47
View File
@@ -0,0 +1,47 @@
define([], function() {
// Joins path segments. Preserves initial "/" and resolves ".." and "."
// Does not support using ".." to go above/outside the root.
// This means that join("foo", "../../bar") will not resolve to "../bar"
function join(/* path segments */) {
// Split the inputs into a list of path commands.
var parts = [];
for (var i = 0, l = arguments.length; i < l; i++) {
parts = parts.concat(arguments[i].split("/"));
}
// Interpret the path commands to get the new resolved path.
var newParts = [];
for (i = 0, l = parts.length; i < l; i++) {
var part = parts[i];
// Remove leading and trailing slashes
// Also remove "." segments
if (!part || part === ".") continue;
// Interpret ".." to pop the last segment
if (part === "..") newParts.pop();
// Push new path segments.
else newParts.push(part);
}
// Preserve the initial slash if there was one.
if (parts[0] === "") newParts.unshift("");
// Turn back into a single string path.
return newParts.join("/") || (newParts.length ? "/" : ".");
}
// A simple function to get the dirname of a path
// Trailing slashes are ignored. Leading slash is preserved.
function dirname(path) {
return join(path, "..");
}
// test if a path or url is absolute
function isAbsolute(path) {
if (!path) return false;
return (path[0] == "/" || path.indexOf("http://") == 0 || path.indexOf("https://") == 0);
}
return {
dirname: dirname,
join: join,
isAbsolute: isAbsolute
};
})