83 lines
2.3 KiB
JavaScript
83 lines
2.3 KiB
JavaScript
(function (scope) {
|
|
'use strict';
|
|
|
|
var TITLE_RE = /<title>([\s\S]*?)<\/title>/i;
|
|
var TEMPLATE_RE = /data-template="([a-z0-9_-]+)"/i;
|
|
|
|
var TEMPLATES = './templates/';
|
|
|
|
var NAMES = [
|
|
'base.njk',
|
|
'page.njk',
|
|
'book.njk',
|
|
'index.njk',
|
|
'bookmark.njk',
|
|
'reference.njk',
|
|
'verses.njk',
|
|
'verse.njk',
|
|
'version.njk',
|
|
'toast.njk',
|
|
'notice.njk'
|
|
];
|
|
|
|
scope.TEMPLATE_URLS = NAMES.map(function (name) { return TEMPLATES + name; });
|
|
|
|
scope.createRenderer = function (readText) {
|
|
function Loader() {}
|
|
Loader.prototype.async = true;
|
|
Loader.prototype.getSource = function (name, callback) {
|
|
readText(TEMPLATES + name).then(
|
|
function (src) { callback(null, { src: src, path: name, noCache: false }); },
|
|
function (err) { callback(err); });
|
|
};
|
|
|
|
var env = new nunjucks.Environment(new Loader(), { autoescape: true });
|
|
|
|
var loaded = null;
|
|
|
|
// Nunjucks resolves {% include %} asynchronously. A template that is not
|
|
// compiled yet when the render reaches it is skipped, taking the rest of
|
|
// the block it sits in with it, and the render still succeeds.
|
|
function loadAll() {
|
|
if (!loaded) {
|
|
loaded = Promise.all(NAMES.map(function (name) {
|
|
return new Promise(function (resolve) {
|
|
env.getTemplate(name, true, null, false, function () { resolve(); });
|
|
});
|
|
}));
|
|
}
|
|
return loaded;
|
|
}
|
|
|
|
function render(name, context) {
|
|
return loadAll().then(function () {
|
|
return new Promise(function (resolve, reject) {
|
|
env.render(name, context, function (err, out) {
|
|
return err ? reject(err) : resolve(out);
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
return {
|
|
render: render,
|
|
|
|
compose: function (fragment, chrome) {
|
|
var title = (TITLE_RE.exec(fragment) || ['', ''])[1].trim();
|
|
var content = fragment.replace(TITLE_RE, '');
|
|
var name = (TEMPLATE_RE.exec(content) || ['', 'page'])[1] + '.njk';
|
|
return render(name, {
|
|
title: title,
|
|
content: content,
|
|
mark: chrome.mark,
|
|
reference: chrome.reference
|
|
});
|
|
},
|
|
|
|
notice: function (heading, text) {
|
|
return render('notice.njk', { heading: heading, text: text });
|
|
}
|
|
};
|
|
};
|
|
})(self);
|