Site working with or without javascript

Now uses history.pushState as a replacement for jquery-address.

Links to blog and tag pages are broken currently; see TODO.org for
details.

Signed-off-by: Collin J. Doering <collin.doering@rekahsoft.ca>
This commit is contained in:
Collin J. Doering 2015-08-13 05:57:19 -04:00
parent c5803970bd
commit 97d4bff5cd
4 changed files with 68 additions and 125 deletions

View File

@ -1,7 +1,9 @@
* rm-js-req TODOs
** Goals
*** TODO Have SPA functionality when javascript is enabled
*** WAIT Have SPA functionality when javascript is enabled
- State "WAIT" from "TODO" [2015-08-13 Thu 05:22] \\
Does have SPA functionality when javascript is enabled but still suffers from a [[link issue]]
*** Complete
**** DONE Remove the javascipt requirement (so that all urls can be viewed without javascript)
CLOSED: [2015-08-10 Mon 22:57]
@ -21,21 +23,7 @@
In order to implement this, a reasonable size refactor needs to take place. Below is a list
of things to be completed in order to successfully achieve the aforementioned goals.
*** TODO Replace jquery-address with use of window.history.pushState
window.history.pushState(object, title, url) can be used to set the browsers url without
relading the page and without breaking browser history. It also doesn't use hashes in the
url and thus urls appear 'normal' and thus will work without modification with or without
javascript.
This will fix the issue where if the initial landing page is any other page besides "/"
like "/blog.html" for example, and then a link is clicked, like for example the 'contact'
navigation link, then the url will be "/blog.html#/contact.html" which will indeed load
properly but is ugly and worse, means there are many different ways to get to the 'same
page'.
See: https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history
*** TODO Fix issue with tag and pagination page generation
*** TODO Fix issue with tag and pagination page generation <<link issue>>
Currently URLs to paginated pages (which includes the blog and tag pages) are broken. They
generate "/tags/*.html" instead of "/tags/*1.html".
@ -73,3 +61,17 @@
CLOSED: [2015-08-10 Mon 22:57]
The enhanced javascipt additions to the site will then have to extract the page-content div
before loading it into the page.
**** DONE Replace jquery-address with use of window.history.pushState
CLOSED: [2015-08-13 Thu 05:21]
window.history.pushState(object, title, url) can be used to set the browsers url without
relading the page and without breaking browser history. It also doesn't use hashes in the
url and thus urls appear 'normal' and thus will work without modification with or without
javascript.
This will fix the issue where if the initial landing page is any other page besides "/"
like "/blog.html" for example, and then a link is clicked, like for example the 'contact'
navigation link, then the url will be "/blog.html#/contact.html" which will indeed load
properly but is ugly and worse, means there are many different ways to get to the 'same
page'.
See: https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history

View File

@ -44,128 +44,67 @@ _paq.push(['enableLinkTracking']);
(function ($, mj) {
"use strict";
// The identity function
function idFun(x) {
return x;
}
var router = (function () {
var routes = [
{ // Post pages handler
acceptUrls: /posts\/.*\.html/,
rewriteGetUrl: idFun,
rewriteVirtualUrl: idFun,
ajaxCallbacks: {
beforeSend: function () {
$('#nav-menu li.active').removeClass('active');
$('#nav-menu li a[href="./blog.html"]').parent('li').addClass('active');
$('#nav-menu li a[href="/blog.html"]').parent('li').addClass('active');
}
}
},
{ // Tag pages handler
acceptUrls: /tags\/.*(\d*)\.html/,
rewriteGetUrl: function (url) {
var tag_not_regexp = /(tags\/.*[^\d]+)(\.html)/;
if (tag_not_regexp.test(url)) {
return url.replace(tag_not_regexp, "$11$2");
}
return url;
},
rewriteVirtualUrl: function (url) {
var tag_one_regexp = /(tags\/.*)1(\.html)/;
if (tag_one_regexp.test(url)) {
return url.replace(tag_one_regexp, "$1$2");
}
return url;
},
ajaxCallbacks: {
beforeSend: function () {
$('#nav-menu li.active').removeClass('active');
$('#nav-menu li a[href="./blog.html"]').parent('li').addClass('active');
$('#nav-menu li a[href="/blog.html"]').parent('li').addClass('active');
}
}
},
{ // Blog pages handler
acceptUrls: /blog\d*\.html/,
rewriteGetUrl: function (url) {
if (url === "/blog.html") {
url = "/blog1.html";
}
return url;
},
rewriteVirtualUrl: function (url) {
if (url === "/blog1.html") {
url = "/blog.html";
}
return url;
},
ajaxCallbacks: {
beforeSend: function () {
// Set the blog menuitem as active
$('a.menuitem[href="./blog.html"]').closest('ul').find('li.active').removeClass('active');
$('a.menuitem[href="./blog.html"]').closest('li').addClass('active');
$('a.menuitem[href="/blog.html"]').closest('ul').find('li.active').removeClass('active');
$('a.menuitem[href="/blog.html"]').closest('li').addClass('active');
}
}
},
{ // Default page handler
acceptUrls: /.*/,
rewriteGetUrl: function (url) {
if (url === "/") {
url = "/index.html";
}
return url;
},
rewriteVirtualUrl: function (url) {
if (url === "/index.html") {
url = "/";
}
return url;
},
ajaxCallbacks: {
beforeSend: function (url, virt_url) {
if (virt_url === "/") {
virt_url = "/index.html";
beforeSend: function (url) {
if (url === "/") {
url = "/index.html";
}
// Initially set the active menuitem in the nav
$('a.menuitem[href="' + virt_url + '"]').closest('ul').find('li.active').removeClass('active');
$('a.menuitem[href="' + virt_url + '"]').closest('li').addClass('active');
$('a.menuitem[href="' + url + '"]').closest('ul').find('li.active').removeClass('active');
$('a.menuitem[href="' + url + '"]').closest('li').addClass('active');
}
}
}],
callback = idFun,
callback = function () { return null; },
spec = {
runRouter: function runRouter(url) {
function runRouter_help(spec) {
var i, new_virt_url;
for (i = 0; i < routes.length; i += 1) {
if (routes[i].acceptUrls.test(spec.url)) {
new_virt_url = routes[i].rewriteVirtualUrl(spec.url);
if (new_virt_url === spec.url) {
if (spec.hasRedirect) {
// TODO: use history API in place of $.address (from jquery-address)
history.pushState(null, "Title", new_virt_url);
} else {
callback(routes[i].rewriteGetUrl(spec.url), spec.url, routes[i].ajaxCallbacks);
}
} else if (spec.numRecur <= spec.recurDepth) {
runRouter_help({ url: new_virt_url,
hasRedirect: true,
numRecur: spec.numRecur + 1,
recurDepth: spec.recurDepth });
} else {
console.log("Exceeded recursion depth for router");
}
break;
var i;
for (i = 0; i < routes.length; i += 1) {
if (routes[i].acceptUrls.test(url)) {
if (url === "/index.html") {
history.pushState(null, "Home", "/");
} else {
// TODO: strip url into title
history.pushState(null, "Title", url);
}
callback(url, routes[i].ajaxCallbacks);
break;
}
}
runRouter_help({ url: url,
hasRedirect: false,
numRecur: 1,
recurDepth: 5 });
},
setCallback: function setCallback(cb) {
if (typeof cb === 'function') {
@ -180,9 +119,9 @@ _paq.push(['enableLinkTracking']);
page = (function () {
// var pageId = '#page-content', navId = '#nav';
function loadPageContent(page_href, virt_href, handlerCallback) {
function loadPageContent(page_href, handlerCallback) {
// Track page view with piwik
_paq.push(['setDocumentTitle', document.domain + '/' + virt_href]);
_paq.push(['setDocumentTitle', document.domain + page_href]);
_paq.push(['trackPageView']);
$.ajax({
@ -195,7 +134,7 @@ _paq.push(['enableLinkTracking']);
// Run current handlers onSuccess callback (if it exists)
if (handlerCallback.hasOwnProperty('beforeSend') && typeof handlerCallback.beforeSend === 'function') {
handlerCallback.beforeSend(page_href, virt_href);
handlerCallback.beforeSend(page_href);
}
console.log('beforeSend a.menuitem');
@ -220,18 +159,8 @@ _paq.push(['enableLinkTracking']);
mj.Hub.Queue(["Typeset", mj.Hub, math_elem[0]]);
});
// Rewrite new URLs within new content inserted into #page-content
$('#page-content a').each(function (i) {
var href = $(this).attr('href'),
external_url_regexp = /https?:\/\/.*/,
mailto_regexp = /mailto:.*/,
files_regexp = /files\/.*/,
images_regexp = /images\/.*/;
if (!(external_url_regexp.test(href) || mailto_regexp.test(href) || files_regexp.test(href) || images_regexp.test(href))) {
$(this).attr('href', "/#" + href);
}
});
// Add anchor click handlers for internal links in new content loaded into #page-content
jsUrls('#page-content a');
// Add fullscreen functionality to inline-images and figures
$('article.post p > img').click(function () {
@ -272,9 +201,30 @@ _paq.push(['enableLinkTracking']);
});
}
function jsUrls(sel) {
$(sel).each(function (i) {
var href = $(this).attr('href'),
external_url_regexp = /https?:\/\/.*/,
mailto_regexp = /mailto:.*/,
files_regexp = /files\/.*/,
images_regexp = /images\/.*/;
if (!(external_url_regexp.test(href) || mailto_regexp.test(href) || files_regexp.test(href) || images_regexp.test(href))) {
$(this).click(function (e) {
e.preventDefault();
router.runRouter(href);
});
}
});
}
function init(router) {
router.setCallback(loadPageContent);
window.addEventListener("popstate", function (e) {
router.runRouter(location.pathname);
});
$(document).ready(function () {
$('#nav-menu a.menuitem').click(function () {
$(this).closest('ul').find('li.active').removeClass('active');
@ -289,12 +239,8 @@ _paq.push(['enableLinkTracking']);
});
});
// TODO: use history API in place of $.address.change (from jquery-address)
// Callback for when the inital page has completely loaded (including images, etc..)
//$.address.change(function (event) {
// console.log("Change " + event.value);
// router.runRouter(event.value);
//}); // TODO
// Add anchor click handlers for internal links
jsUrls('#page-content a, #nav-menu a.menuitem');
});
}

View File

@ -224,7 +224,6 @@ main = do
makeItem ""
>>= loadAndApplyTemplate "templates/pages/blog.html" ctx
>>= loadAndApplyTemplate "templates/default.html" indexCtx
>>= relativizeUrls
match "pages/*" $ do
route navgenRoute
@ -266,7 +265,6 @@ main = do
(makeItem . itemBody) pg
>>= loadAndApplyTemplate "templates/default.html" indexCtx
>>= relativizeUrls
match "posts/**" $ do
route $ setExtension "html"
@ -288,7 +286,6 @@ main = do
>>= saveSnapshot "content"
>>= loadAndApplyTemplate "templates/partials/post.html" (taggedPostCtx tags)
>>= loadAndApplyTemplate "templates/default.html" indexCtx
>>= relativizeUrls
create ["atom.xml"] $ do
route idRoute
@ -351,7 +348,6 @@ paginateTagsRules loc tags =
makeItem ""
>>= loadAndApplyTemplate "templates/tag-page.html" ctx
>>= loadAndApplyTemplate "templates/default.html" indexCtx
>>= relativizeUrls
rulesExtraDependencies [tagsDependency tags] $ do
create [tagsMakeId tags tag] $ do

View File

@ -38,10 +38,9 @@
<div id="page-content">
<noscript>
<div class="container" id="noscript-alert">
<h1>This site requires javascript!</h1>
<h1>This site works best with javascript!</h1>
<p>
If you insist on not using javascript we provide a simplified website
<a class="alert-link" href="nojs/index.html">here</a>
Some features of this site will not work without javascript, though all the content is still available.
</p>
</div>
</noscript>