packages feed

hablo-1.1.0.1: share/js/Navigation.js

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);
      })
    )
  );
}