hablo/share/js/Navigation.js

122 lines
3.3 KiB
JavaScript

import {articlesList, getResource, render} from DomRenderer;
import blog from Hablo.Config;
import * as Async from UnitJS.Async;
import * as Cache from UnitJS.Cache;
import * as Dom from UnitJS.Dom;
import * as Fun from UnitJS.Fun;
var cache = {};
['article', 'page'].forEach(function(contentType) {
cache[contentType] = Cache.make(function(key) {
var url = ["", blog.path[contentType + 'sPath'], key + '.md'].join('/');
return Async.bind(
Async.http({method: 'GET', url: url}),
function(queryResult) {
if(queryResult.status == 200) {
return Async.wrap(queryResult.responseText);
} else {
return Async.fail(
"Could not load " + contentType + " " + url + " (" + queryResult.status + " " + queryResult.statusText + ")"
);
}
}
);
});
});
window.addEventListener('popstate', function(e) {
if(e.state != undefined) {
navigate(e.state.url);
}
});
history.replaceState({url: window.location.pathname}, 'Blog - title', window.location.pathname);
return {
hijackLinks: hijackLinks
};
function hijackLinks(domElem) {
domElem = domElem || document;
var links = domElem.getElementsByTagName('a');
for(var i = 0; i < links.length; i++) {
var a = links[i];
var href = a.getAttribute("href");
if((href[0] == "/" && href.slice(-3) != ".md") || href[0] == "#") {
a.addEventListener('click', visit(a.getAttribute("href")));
}
}
}
function visit(url) {
return function(e) {
e.preventDefault();
if(url[0] == '#') {
window.location = url;
history.replaceState({url: window.location.pathname}, 'Blog - title', url);
} else {
navigate(url);
history.pushState({url: url}, 'Blog - title', url);
}
};
}
function navigate(url) {
var resource = getResource(url);
switch(resource.type) {
case 'list': show(getArticlesList(resource)); break;
case 'article':
case 'page': show(getCached(resource)); break;
default: console.log("No idea how to navigate to " + url);
}
}
function getCached(resource) {
return Async.bind(
cache[resource.type].get(resource.key),
Async.map(
function(contents) {return [render(resource, contents)];}
)
);
}
function preview(key) {
return Async.bind(
cache.article.get(key),
function(contents) {
return Async.wrap(
render({type: 'article', key: key}, contents, blog.skin.previewLinesCount)
);
}
);
}
function articleIds(resource) {
var ids = resource.tag != undefined ? blog.tags[resource.tag] : Object.keys(blog.articles);
var reverseDate = function (id) {return -blog.articles[id].metadata.date;};
ids.sort(Fun.compare(reverseDate));
return ids.slice(0, resource.all ? undefined : blog.skin.previewArticlesCount);
}
function getArticlesList(resource) {
return Async.bind(
Async.parallel.apply(null, articleIds(resource).map(preview)),
Async.map(articlesList(resource))
);
}
function show(contents) {
Async.run(
Async.bind(
contents,
Async.map(function (domElems) {
domElems = domElems.filter(Fun.defined);
var div = document.getElementById('contents');
Dom.clear(div);
for(var i = 0; i < domElems.length; i++) {
div.appendChild(domElems[i]);
}
hijackLinks(div);
})
)
);
}