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 = {'&': '&#38;', '<': '&#60;', '>': '&#62;', '"': '&#34;', "'": '&#39;', '/': '&#47;'},
			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("}
	},...