121 lines
3.3 KiB
JavaScript
121 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);
|
|
})
|
|
)
|
|
);
|
|
}
|