Fixed js page loading issue

Load html using $.parseHTML so that no scripts are executed, otherwise
all scripts are loaded each page load and ajax load which causes an
infinite loop.

Currently, though everything is functioning, there are a few
deficiencies. See TODO.org for more details.

Signed-off-by: Collin J. Doering <collin.doering@rekahsoft.ca>
This commit is contained in:
Collin J. Doering 2015-08-12 03:08:42 -04:00
parent e5a90c220e
commit a21fe60c9e
2 changed files with 158 additions and 128 deletions

View File

@ -8,7 +8,6 @@
**** DONE Only generate one version of the site
CLOSED: [2015-08-10 Mon 22:57]
** Benefits
This refactor will have a couple added benefits. Namely:
@ -22,13 +21,32 @@
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 Modify nav URLs using javascript once page is loaded
*** 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
*** WAIT Modify nav URLs using javascript once page is loaded
- State "WAIT" from "TODO" [2015-08-12 Wed 02:54] \\
This hasn't been done and doesn't need to be, as the rel attributes on the anchor tags
within the nav are 'picked up' by jquery-address and treated correctly (using the
clientside router).
If it is indeed enabled then the user can benefit from the SPA functionality of the site.
Otherwise they will be able to browse the site using the original, unmodified links. This is
similar to how the link withing the page-content div work currently, and mainly would have to
be adapted for the navigation.
*** TODO Fix issue with tag and pagination urls <<page loading issue>>
*** TODO Fix issue with tag and pagination page generation
All URLs are required to work without javascript. Thus there can't be any tricks employed
in javascript to modify urls (the js router rewriting). Currently this happens with the
@ -37,13 +55,20 @@
- etc..
Currently URLs to paginated pages (which includes the blog and tag pages) are broken. They
generate "/tags/*.html" instead of "/tags/*1.html".
generate "/tags/*.html" instead of "/tags/*1.html". Also see [[pagination artifact][this issue]]which is related to
this last issue (which when solved would hopefully fix this as well).
*** TODO Fix ajax page loading
Pages don't load properly when javascript is enabled. This likely is having an effect on
this [[page loading issue][issue]] as well. More debugging is required.
*** TODO Pagination creates an extra unexpected file <<pagination artifact>>
When the blog page and tag pages are paginated an extra file is generated that is not
expected. For example, for the paginated blog, "/blog1.html through "/blogN.html" and
"/blog.html" are generated. "/blog.html" is not expected to be generated and seems to be an
artifact of pagination. It contains all blog posts (contained in "/blog1.html" through
"/blogN.html").
*** Complete
**** DONE Fix ajax page loading
CLOSED: [2015-08-12 Wed 02:41]
Pages don't load properly when javascript is enabled.
**** DONE Generate nav with href pointing to normal urls, not virtual ones
CLOSED: [2015-08-10 Mon 22:55]
(Eg. /pages/blog.html instead of #/blog.html)

View File

@ -91,7 +91,7 @@ _paq.push(['enableLinkTracking']);
if (url === "/blog.html") {
url = "/blog1.html";
}
return "pages" + url;
return url;
},
rewriteVirtualUrl: function (url) {
if (url === "/blog1.html") {
@ -113,7 +113,7 @@ _paq.push(['enableLinkTracking']);
if (url === "/") {
url = "/index.html";
}
return "pages" + url;
return url;
},
rewriteVirtualUrl: function (url) {
if (url === "/index.html") {
@ -176,140 +176,145 @@ _paq.push(['enableLinkTracking']);
return spec;
}()),
page = (function () {
// var pageId = '#page-content', navId = '#nav';
page = (function () {
// var pageId = '#page-content', navId = '#nav';
function loadPageContent(page_href, virt_href, handlerCallback) {
// Track page view with piwik
_paq.push(['setDocumentTitle', document.domain + '/' + virt_href]);
_paq.push(['trackPageView']);
function loadPageContent(page_href, virt_href, handlerCallback) {
// Track page view with piwik
_paq.push(['setDocumentTitle', document.domain + '/' + virt_href]);
_paq.push(['trackPageView']);
// Remove loading error from page-content
$('#page-content').removeClass('loading-error');
$.ajax({
url: page_href,
type: 'GET',
dataType: 'html',
beforeSend: function (xhr, settings) {
// Remove loading error from page-content
$('#page-content').removeClass('loading-error');
// Add .loading to #page-content and #nav to facilitate a loading animation
$('#page-content, #nav').removeClass('loading-done').addClass('loading');
// Add .loading to #page-content and #nav to facilitate a loading animation
$('#page-content, #nav').removeClass('loading-done').addClass('loading');
// Run current handlers onSuccess callback (if it exists)
if (handlerCallback.hasOwnProperty('beforeSend') && typeof handlerCallback.beforeSend === 'function') {
handlerCallback.beforeSend(page_href, virt_href);
// Run current handlers onSuccess callback (if it exists)
if (handlerCallback.hasOwnProperty('beforeSend') && typeof handlerCallback.beforeSend === 'function') {
handlerCallback.beforeSend(page_href, virt_href);
}
console.log('beforeSend a.menuitem');
},
success: function (dta) {
// Remove the initial loading gif (if its there)
$('#page-content').removeClass('init');
// Remove any status message errors or successes
$('#status').slideUp('normal', function () {
$('#status').removeClass('error').removeClass('success').children('p.message').remove();
});
// Stop animations in the nav and page-content and scroll to the top of the page in a set amount of time
setTimeout(function () {
// Replace old page-content with new page-content
dta = $($.parseHTML(dta)).filter('#page-content').html();
$('#page-content').html(dta);
// Stop page loading
$('#page-content, #nav').removeClass('loading');
// Reload any new maths using MathJax
$('#page-content .math').each(function (math_elem) {
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 fullscreen functionality to inline-images and figures
$('article.post p > img').click(function () {
$(this).get(0).toggleFullScreen();
});
$('figure').click(function () {
$(this).children('img').get(0).toggleFullScreen();
});
// Run current handles onSuccess callback (if it exists)
if (handlerCallback.hasOwnProperty('onSuccess') && typeof handlerCallback.onSuccess === 'function') {
handlerCallback.onSuccess();
}
// Scroll to top of the page
if ($('body').scrollTop() > $('#nav').offset().top - 15) {
$('html, body').animate({
scrollTop: $('#nav').offset().top - 15
}, 'fast');
}
}, 250);
},
error: function (xhr, status) {
/* Remove .loading from #page-content and #nav to stop the loading
* animation. Then add .loading-error to #page-content if its the sites
* first load (#page-content has class .init). Finally, display an error
* message in #status.
*/
$('#page-content, #nav').removeClass('loading');
if ($('#page-content.init')[0]) {
// TODO: instead of immediately displaying error, check if the content is stored in local storage
$('#page-content').addClass('loading-error').html('<p class="container border-box">Error initially loading blog.rekahsoft.ca. Check the url! Given "' + page_href + '"</p>');
} else if ($('#status.error')[0]) {
$('#status').prepend('<p class="message">Error retrieving page ' + page_href + '</p>');
} else {
$('#status').prepend('<p class="message">Error retrieving page ' + page_href + '</p>');
$('#status').addClass('error').slideDown();
}
// Run current handles onError callback (if it exists)
if (handlerCallback.hasOwnProperty('onError') && typeof handlerCallback.onError === 'function') {
handlerCallback.onError();
}
}
});
}
console.log('beforeSend a.menuitem');
function init(router) {
router.setCallback(loadPageContent);
$('#page-content').load(page_href + ' #page-content', function (dta, status, xhr) {
if (status === "error") {
/* Remove .loading from #page-content and #nav to stop the loading
* animation. Then add .loading-error to #page-content if its the sites
* first load (#page-content has class .init). Finally, display an error
* message in #status.
*/
$('#page-content, #nav').removeClass('loading');
if ($('#page-content.init')[0]) {
// TODO: instead of immediately displaying error, check if the content is stored in local storage
$('#page-content').addClass('loading-error').html('<p class="container border-box">Error initially loading blog.rekahsoft.ca. Check the url! Given "' + page_href + '"</p>');
} else if ($('#status.error')[0]) {
$('#status').prepend('<p class="message">Error retrieving page ' + page_href + '</p>');
} else {
$('#status').prepend('<p class="message">Error retrieving page ' + page_href + '</p>');
$('#status').addClass('error').slideDown();
}
// Run current handles onError callback (if it exists)
if (handlerCallback.hasOwnProperty('onError') && typeof handlerCallback.onError === 'function') {
handlerCallback.onError();
}
} else {
// Remove the initial loading gif (if its there)
$('#page-content').removeClass('init');
// Remove any status message errors or successes
$('#status').slideUp('normal', function () {
$('#status').removeClass('error').removeClass('success').children('p.message').remove();
$(document).ready(function () {
$('#nav-menu a.menuitem').click(function () {
$(this).closest('ul').find('li.active').removeClass('active');
$(this).closest('li').addClass('active');
//$('.navbar-collapse').collapse('hide');
});
// Stop animations in the nav and page-content and scroll to the top of the page in a set amount of time
setTimeout(function () {
// Replace old page-content with new page-content
$('#page-content').html(dta);
// Stop page loading
$('#page-content, #nav').removeClass('loading');
// Reload any new maths using MathJax
$('#page-content .math').each(function (math_elem) {
mj.Hub.Queue(["Typeset", mj.Hub, math_elem[0]]);
$('#status a.close-button').click(function () {
$(this).parent().slideUp(function () {
$(this).removeClass('error').removeClass('success');
$(this).children('p.message').remove();
});
});
// 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 fullscreen functionality to inline-images and figures
$('article.post p > img').click(function () {
$(this).get(0).toggleFullScreen();
});
$('figure').click(function () {
$(this).children('img').get(0).toggleFullScreen();
});
// Run current handles onSuccess callback (if it exists)
if (handlerCallback.hasOwnProperty('onSuccess') && typeof handlerCallback.onSuccess === 'function') {
handlerCallback.onSuccess();
}
// Scroll to top of the page
if ($('body').scrollTop() > $('#nav').offset().top - 15) {
$('html, body').animate({
scrollTop: $('#nav').offset().top - 15
}, 'fast');
}
}, 250);
}
});
}
function init(router) {
router.setCallback(loadPageContent);
$(document).ready(function () {
$('#nav-menu a.menuitem').click(function () {
$(this).closest('ul').find('li.active').removeClass('active');
$(this).closest('li').addClass('active');
//$('.navbar-collapse').collapse('hide');
});
$('#status a.close-button').click(function () {
$(this).parent().slideUp(function () {
$(this).removeClass('error').removeClass('success');
$(this).children('p.message').remove();
// 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);
});
});
}
// 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);
});
});
}
var spec = {
init: init
};
return spec;
}());
var spec = {
init: init
};
return spec;
}());
// Start of execution
page.init(router);
}(jQuery, MathJax));