Rendered JS

This commit is contained in:
nicco 2018-02-09 15:01:09 +01:00
parent d90f695c9e
commit 47a23b656e
6 changed files with 88 additions and 108 deletions

52
dist/actions.js vendored
View File

@ -5,8 +5,8 @@ const options_1 = require("./options");
const util_1 = require("./util"); const util_1 = require("./util");
const path_1 = require("path"); const path_1 = require("path");
const parser_1 = require("./parser"); const parser_1 = require("./parser");
exports.comment = html => { exports.comment = (html, options, re) => {
const tag = options_1.re.comment + options_1.re.ending; const tag = re.comment + re.ending;
const end = html.indexOf(tag); const end = html.indexOf(tag);
if (end === -1) if (end === -1)
throw new Error(options_1.error.parse.comment_not_closed); throw new Error(options_1.error.parse.comment_not_closed);
@ -15,11 +15,11 @@ exports.comment = html => {
length: end + tag.length length: end + tag.length
}; };
}; };
exports.logic = html => { exports.logic = (html, options, re) => {
const rexp = { const rexp = {
start: new RegExp(`${options_1.re.begin}\\${options_1.re.if} *\\${options_1.re.if_else}?${options_1.re.valid_variable} *${options_1.re.ending}`, 'g'), start: new RegExp(`${re.begin}\\${re.if} *\\${re.if_else}?${re.valid_variable} *${re.ending}`, 'g'),
else: new RegExp(`${options_1.re.begin} *\\${options_1.re.if_else} *${options_1.re.ending}`, 'g'), else: new RegExp(`${re.begin} *\\${re.if_else} *${re.ending}`, 'g'),
end: RegExp(`${options_1.re.begin} *\\${options_1.re.closing_tag} *\\${options_1.re.if} *${options_1.re.ending}`, 'g'), end: RegExp(`${re.begin} *\\${re.closing_tag} *\\${re.if} *${re.ending}`, 'g'),
}; };
const current = { const current = {
found: rexp.start.exec(html), found: rexp.start.exec(html),
@ -28,10 +28,10 @@ exports.logic = html => {
}; };
if (current.found === null || current.found.index !== 0) if (current.found === null || current.found.index !== 0)
throw new Error(options_1.error.parse.default); throw new Error(options_1.error.parse.default);
current.variable = current.found[0].slice(options_1.re.begin.length + options_1.re.if.length, -options_1.re.ending.length).trim(); current.variable = current.found[0].slice(re.begin.length + re.if.length, -re.ending.length).trim();
current.inverted = current.variable[0] === options_1.re.if_invert; current.inverted = current.variable[0] === re.if_invert;
if (current.inverted) if (current.inverted)
current.variable = current.variable.slice(options_1.re.if_invert.length); current.variable = current.variable.slice(re.if_invert.length);
let next; let next;
do { do {
next = { next = {
@ -53,30 +53,30 @@ exports.logic = html => {
if (current.inverted) if (current.inverted)
isTrue = !isTrue; isTrue = !isTrue;
if (isTrue) if (isTrue)
return compiler_1.compileBlock(body.if).parts; return compiler_1.compileBlock(body.if, options, re).parts;
else else
return compiler_1.compileBlock(body.else).parts; return compiler_1.compileBlock(body.else, options, re).parts;
}], }],
length: next.end.index + next.end[0].length length: next.end.index + next.end[0].length
}; };
}; };
exports.importer = html => { exports.importer = (html, options, re) => {
const end = html.indexOf(options_1.re.ending); const end = html.indexOf(re.ending);
if (end === -1) if (end === -1)
throw new Error(options_1.error.parse.include_not_closed); throw new Error(options_1.error.parse.include_not_closed);
const template_name = html.substring(options_1.re.begin.length + options_1.re.incude.length, end).trim(); const template_name = html.substring(re.begin.length + re.incude.length, end).trim();
const file_name = path_1.join(options_1.options.template_dir, `${template_name}.${options_1.options.template_ext}`); const file_name = path_1.join(options.views, `${template_name}.${options.extension}`);
const file = util_1.readFileSync(file_name); const file = util_1.readFileSync(file_name);
return { return {
parts: compiler_1.compileBlock(file).parts, parts: compiler_1.compileBlock(file, options, re).parts,
length: end + options_1.re.ending.length length: end + re.ending.length
}; };
}; };
exports.variables = html => { exports.variables = (html, options, re) => {
const end = html.indexOf(options_1.re.ending); const end = html.indexOf(re.ending);
if (end === -1) if (end === -1)
throw new Error(options_1.error.parse.variable_not_closed); throw new Error(options_1.error.parse.variable_not_closed);
const variable_name = html.substring(options_1.re.begin.length, end).trim(); const variable_name = html.substring(re.begin.length, end).trim();
return { return {
parts: [(data) => { parts: [(data) => {
const output = util_1.getFromObject(data, variable_name); const output = util_1.getFromObject(data, variable_name);
@ -87,13 +87,13 @@ exports.variables = html => {
return output; return output;
} }
}], }],
length: end + options_1.re.ending.length length: end + re.ending.length
}; };
}; };
exports.loop = html => { exports.loop = (html, options, re) => {
const rexp = { const rexp = {
start: new RegExp(`${options_1.re.begin}\\${options_1.re.for} *${options_1.re.valid_variable} *${options_1.re.for_in} *${options_1.re.valid_variable} *${options_1.re.ending}`, 'g'), start: new RegExp(`${re.begin}\\${re.for} *${re.valid_variable} *${re.for_in} *${re.valid_variable} *${re.ending}`, 'g'),
end: RegExp(`${options_1.re.begin} *\\${options_1.re.closing_tag} *\\${options_1.re.for} *${options_1.re.ending}`, 'g'), end: RegExp(`${re.begin} *\\${re.closing_tag} *\\${re.for} *${re.ending}`, 'g'),
}; };
const current = { const current = {
found: rexp.start.exec(html), found: rexp.start.exec(html),
@ -102,7 +102,7 @@ exports.loop = html => {
}; };
if (current.found === null || current.found.index !== 0) if (current.found === null || current.found.index !== 0)
throw new Error(options_1.error.parse.default); throw new Error(options_1.error.parse.default);
const statement = current.found[0].slice(options_1.re.begin.length + options_1.re.if.length, -options_1.re.ending.length).trim().split(options_1.re.for_in); const statement = current.found[0].slice(re.begin.length + re.if.length, -re.ending.length).trim().split(re.for_in);
current.variable = statement[0].trim(); current.variable = statement[0].trim();
current.arr = statement[1].trim(); current.arr = statement[1].trim();
let next; let next;
@ -120,7 +120,7 @@ exports.loop = html => {
let ret = ''; let ret = '';
for (const variable of util_1.getFromObject(data, current.arr)) { for (const variable of util_1.getFromObject(data, current.arr)) {
const newData = Object.assign({ [current.variable]: variable }, data); const newData = Object.assign({ [current.variable]: variable }, data);
ret += parser_1.computeParts(compiler_1.compileBlock(html).parts, newData); ret += parser_1.computeParts(compiler_1.compileBlock(html, options, re).parts, newData);
} }
return ret; return ret;
}], }],

59
dist/cometa.js vendored
View File

@ -5,43 +5,42 @@ const util = require("./util");
const parser = require("./parser"); const parser = require("./parser");
const compiler = require("./compiler"); const compiler = require("./compiler");
const options_1 = require("./options"); const options_1 = require("./options");
const cache = new Map(); module.exports = class {
function compile(html) { constructor(opt, rexp) {
return { this.options = options_1.options;
template: compiler.process(html), this.expressions = options_1.re;
time: Date.now() this._express = this.renderFile;
}; this.cache = new Map();
} this.options = Object.assign(this.options, opt);
function renderFile(file, data, callback) { this.expressions = Object.assign(this.expressions, rexp);
if (module.parent === null)
throw new Error('Not imported');
this.options.views = path.join(path.dirname(module.parent.filename), this.options.views);
}
renderFile(file, data, callback) {
console.log('Options', this.options);
util.readFile(file).then(html => { util.readFile(file).then(html => {
console.log('Options', this.options);
if (html === undefined) {
callback(`No template found: ${file}`, '');
return;
}
util.checksum(html, true).then(hash => { util.checksum(html, true).then(hash => {
if (options_1.options.caching && !cache.get(html)) if (this.options.caching && !this.cache.get(html))
cache.set(html, compile(html)); this.cache.set(html, {
const compiled = cache.get(html); template: compiler.process(html, this.options, this.expressions),
time: Date.now()
});
const compiled = this.cache.get(html);
if (compiled) if (compiled)
callback(null, parser.computeParts(compiled.template, data)); callback(null, parser.computeParts(compiled.template, data));
else else
callback('Error: Chache not found', ''); callback('Error: Chache not found', '');
}); });
}); });
}
exports.renderFile = renderFile;
async function render(template_name, data) {
const template_path = path.join(options_1.options.template_dir, `${template_name}.${options_1.options.template_ext}`);
if (options_1.options.caching && !cache.get(template_name)) {
const html = await util.readFile(template_path);
if (html !== undefined)
cache.set(template_name, compile(html));
else {
'No file found'.log();
return '';
} }
renderTemplate(template_name, data, callback) {
const template_path = path.join(this.options.views, `${template_name}.${this.options.extension}`);
this.renderFile(template_path, data, callback);
} }
const compiled = cache.get(template_name); };
if (compiled)
return parser.computeParts(compiled.template, data);
else
return '';
}
exports.render = render;
exports._express = renderFile;

26
dist/compiler.js vendored
View File

@ -2,11 +2,11 @@
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
const options_1 = require("./options"); const options_1 = require("./options");
const actions = require("./actions"); const actions = require("./actions");
const rexp = Object.freeze({ exports.compileBlock = (part, optoins, re) => {
begin: new RegExp(options_1.re.begin, 'g'), const rexp = Object.freeze({
end: new RegExp(options_1.re.ending, 'g'), begin: new RegExp(re.begin, 'g'),
}); end: new RegExp(re.ending, 'g'),
exports.compileBlock = part => { });
let next; let next;
const getNext = (s) => Object.freeze({ const getNext = (s) => Object.freeze({
start: s.search(rexp.begin), start: s.search(rexp.begin),
@ -26,24 +26,24 @@ exports.compileBlock = part => {
addToRet(part.substr(0, next.start)); addToRet(part.substr(0, next.start));
part = part.slice(next.start); part = part.slice(next.start);
let func; let func;
switch (part[options_1.re.begin.length]) { switch (part[re.begin.length]) {
case options_1.re.comment: case re.comment:
func = actions.comment; func = actions.comment;
break; break;
case options_1.re.if: case re.if:
func = actions.logic; func = actions.logic;
break; break;
case options_1.re.for: case re.for:
func = actions.loop; func = actions.loop;
break; break;
case options_1.re.incude: case re.incude:
func = actions.importer; func = actions.importer;
break; break;
default: default:
func = actions.variables; func = actions.variables;
break; break;
} }
const result = func(part); const result = func(part, options_1.options, re);
addToRet(result.parts); addToRet(result.parts);
part = part.slice(result.length); part = part.slice(result.length);
next = getNext(part); next = getNext(part);
@ -51,8 +51,8 @@ exports.compileBlock = part => {
addToRet(part); addToRet(part);
return ret; return ret;
}; };
function process(html, options = {}) { function process(html, options, re) {
const parts = exports.compileBlock(html).parts; const parts = exports.compileBlock(html, options, re).parts;
return parts; return parts;
} }
exports.process = process; exports.process = process;

7
dist/options.js vendored
View File

@ -17,11 +17,8 @@ exports.error = {
exports.options = { exports.options = {
encoding: 'utf-8', encoding: 'utf-8',
caching: true, caching: true,
template_dir: './views', views: './views',
template_ext: 'html', extension: 'html',
compiled_dir: './cache',
compiled_ext: 'bjs',
max_recursion: 100,
}; };
exports.re = { exports.re = {
begin: '{{', begin: '{{',

2
dist/parser.js vendored
View File

@ -2,7 +2,7 @@
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
const options_1 = require("./options"); const options_1 = require("./options");
function computeParts(parts, data = {}) { function computeParts(parts, data = {}) {
if (parts.length === 0) if (parts === undefined || parts.length === 0)
return ''; return '';
return computePart(parts[0], data) + computeParts(parts.slice(1), data); return computePart(parts[0], data) + computeParts(parts.slice(1), data);
} }

28
dist/util.js vendored
View File

@ -2,14 +2,11 @@
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
const fs = require("fs"); const fs = require("fs");
const crypto = require("crypto"); const crypto = require("crypto");
String.prototype.log = function () {
console.log(this);
};
function readFile(url) { function readFile(url) {
return new Promise(res => { return new Promise(res => {
fs.readFile(url, (err, data) => { fs.readFile(url, (err, data) => {
if (err) if (err)
throw new Error(`No such file: ${url}`); res();
else else
res(data.toString()); res(data.toString());
}); });
@ -20,20 +17,6 @@ function readFileSync(url) {
return fs.readFileSync(url).toString(); return fs.readFileSync(url).toString();
} }
exports.readFileSync = readFileSync; exports.readFileSync = readFileSync;
function writeFile(url, data) {
return new Promise(res => {
fs.writeFile(url, data, err => {
if (err)
res(false);
res(true);
});
});
}
exports.writeFile = writeFile;
function writeFileSync(url, data) {
fs.writeFileSync(url, data);
}
exports.writeFileSync = writeFileSync;
function fileExists(url) { function fileExists(url) {
return new Promise(res => { return new Promise(res => {
fs.exists(url, _ => { fs.exists(url, _ => {
@ -56,10 +39,6 @@ function checksum(url, plain = false, alg = 'sha1') {
}); });
} }
exports.checksum = checksum; exports.checksum = checksum;
function replaceBetween(start, end, str, replace) {
return str.substring(0, start) + replace + str.substring(end);
}
exports.replaceBetween = replaceBetween;
function getFromObject(data, name) { function getFromObject(data, name) {
name = name.trim(); name = name.trim();
const valid = /^[A-z]\w*(\.[A-z]\w*|\[\d+\]|\[('|")\w+\2\]|\[[A-z]\w*\])*$/.test(name); const valid = /^[A-z]\w*(\.[A-z]\w*|\[\d+\]|\[('|")\w+\2\]|\[[A-z]\w*\])*$/.test(name);
@ -67,8 +46,13 @@ function getFromObject(data, name) {
return ''; return '';
name = name.replace(/('|")/g, ''); name = name.replace(/('|")/g, '');
name = name.replace(/\[(\w+)\]/g, '.$1'); name = name.replace(/\[(\w+)\]/g, '.$1');
try {
for (const i of name.split('.')) for (const i of name.split('.'))
data = data[i]; data = data[i];
}
catch (e) {
return '';
}
return data; return data;
} }
exports.getFromObject = getFromObject; exports.getFromObject = getFromObject;