Dot.js vs DoT12.js comparison
Compare with 2 native codes of similar engines with common template and data structure
by spmbt
HTML
<head lang="en">
<title>Testing of the doT12 template engine </title>
</head>
<body>
<div class="tmpl">
<div class="titl"><span>Template</span></div>
<textarea cols=120 rows=22>
(Article about this clone of doT.js: https://habrahabr.ru/post/333662/ [ru])
<div>
{{=it.as}}</div>
<div>{{=12+3400}}</div>
<div>
{{=it.bs +1}}
</div>
<div>{{=12+6800}}</div>
</textarea>
</div>
<div class="dat">
<div class="titl"><span>Data</span></div>
<textarea cols=120 rows=10>
{as:12, bs:34, cs: 567}
</textarea>
</div>
<div class="doing">
<button onclick="window.doing()">Recalc</button>
<input checked type="checkbox" class="autocalc" title="calculate automatically after change"/>
<button onclick="window.compile()" style="margin-left: 39px">Show function</button>
<button id="bench" onclick="window.bench()" style="margin-left: 40px">Bench 1e3</button>
</div>
<div class="res right from2nd" data-version="v. 1.2.1"></div>
<div class="res left" data-version="v. 1.1.1"></div>
<div class="xmps">
<div class="title" title="Save current example by click and show another one">
Examples
</div>
<div class="xmp current" data-xmpkey="0">
Expressions
<textarea class="tmpl"> <!-- this current content is placed in body >.tmpl -->
xmpl1
</textarea>
<textarea class="dat">
dat1
</textarea>
</div>
<div class="xmp" data-xmpkey="1">
Array
<textarea class="tmpl">
{{~it:v:i}}<b>[{{=i}}]: {{=v.name}}</b>
{{~}}
</textarea>
<textarea class="dat">
[
{ "name": "asfaf" },
{ "name": "ertdfg" },
{ "name": "jghj" },
{ "noName": "tyrt" },
{ "name": "werwet" }
]
</textarea>
</div>
<div class="xmp" data-xmpkey="2">
Structure (new)
<textarea class="tmpl">
{{@:v:i}}<b>[{{=i}}] : {{=v.name}}</b>
{{@}}
</textarea>
<textarea class="dat">
[
{ "name": "Moe" },
{ "name": "Larry" },
{ "name": "Curly"...
CSS
html,body{height: 100%}
button{padding:0 8px; border-radius: 3px;}
.tmpl textarea, .dat textarea{width: 100%}
.tmpl .titl, .dat .titl{
text-align: right;
height: .2em;
margin: -.1em 0;
}
.tmpl .titl span, .dat .titl span{position: relative; top: -.5em; color: #777}
.res.left, .res.right{
position: relative;
width: 49.6%;
min-height: 80%;
margin:2px 0 24px;
border:1px solid #888;
word-wrap: break-word;
background-color:#f7f3f2;
}
.res.right{
float: right;
background-color:#f3f5fb;
}
.res.left:before, .res.right.from2nd:before, .res.right.from2nd:after{
content: attr(data-version);
position: absolute;
top: -.1em;
right: 0;
padding: 0 2px 0 3px;
font-size: 13px;
border: 1px solid rgba(208, 208, 208, 0.6);
border-radius: 2px;
background-color: rgba(238, 238, 238, 0.6);
}
.res.right.from2nd:after{
content:'from second script';
top: -1.1em;
padding: 0 6px 0 9px;
font-size: 12px;
border-radius: 5px;
}
.xmps{
position: absolute;
top: 0;
right: 120px;
padding: 0 2px 0 3px;
font-size: 13px;
border: 1px solid rgba(208, 208, 208, 0.6);
border-radius: 2px;
background-color: rgba(238, 242, 255, 0.6);
}
.xmps .title{
text-align: right;
}
.res.left:hover:before, .res.right.from2nd:hover:before,
.xmps .xmp, .xmps .xmp .tmpl, .xmps .xmp .dat{
display: none;
padding: 1px 3px;
}
.xmps:hover .xmp{
display: block;
}
.xmps .xmp.current{
background-color: rgba(255, 238, 233, 0.85);
}
.xmps .xmp:not(.current):hover{
background-color: rgba(223, 232, 248, 0.9);
cursor: pointer;
}
.warn{background-color: #fef6de;}
.autocalc{line-height: 30px; vertical-align: middle}
JavaScript
//========= define of window.doT ===============
// doT.js
// 2011-2014, Laura Doktorova, https://github.com/olado/doT
// Licensed under the MIT license.
(function(){
"use strict";
var doT = {version: '1.1.1'
,name: 'doT'
,templateSettings: {
evaluate: /\{\{([\s\S]+?(\}?)+)\}\}/g,
interpolate: /\{\{=([\s\S]+?)\}\}/g,
encode: /\{\{!([\s\S]+?)\}\}/g,
use: /\{\{#([\s\S]+?)\}\}/g,
useParams: /(^|[^\w$])def(?:\.|\[[\'\"])([\w$\.]+)(?:[\'\"]\])?\s*\:\s*([\w$\.]+|\"[^\"]+\"|\'[^\']+\'|\{[^\}]+\})/g,
define: /\{\{##\s*([\w\.$]+)\s*(\:|=)([\s\S]+?)#\}\}/g,
defineParams:/^\s*([\w$]+):([\s\S]+)/,
conditional: /\{\{\?(\?)?\s*([\s\S]*?)\s*\}\}/g,
iterate: /\{\{~\s*(?:\}\}|([\s\S]+?)\s*\:\s*([\w$]+)\s*(?:\:\s*([\w$]+))?\s*\}\})/g,
varname: 'it',
strip: !true,
append: true,
selfcontained: false, // Self-sufficient, not need global definition of _encodeHTML()
doNotSkipEncoded: false //Do not show values of encoded characters of the & ...; format
},
template: undefined, //fn, compile template
compile: undefined, //fn, for express
log: true
}, _globals;
doT.encodeHTMLSource = function(doNotSkipEncoded){
var encodeHTMLRules = {'&': '&', '<': '<', '>': '>', '"': '"', "'": ''', '/': '/'},
matchHTML = doNotSkipEncoded ? /[&<>"'\/]/g : /&(?!#?\w+;)|<|>|"|'|\//g;
return function(code){
return code ? code.toString().replace(matchHTML, function(m) {return encodeHTMLRules[m] || m;}) : '';
};
};
_globals = (function(){ return this || (0,eval)('this'); }());
/* istanbul ignore else */
if(typeof module !='undefined' && module.exports)
module.exports = doT;
else if(typeof define =='function' && define.amd)
define(function(){return doT;});
else
_globals.doT = doT;
var startend = {
append: { start: "'+(", end: ")+'", startencode: "'+encodeHTML("},
split: { start: "';out+=(", end: ");out+='", startencode: "';out+=encodeHTML("}
},...