Skip to content

Instantly share code, notes, and snippets.

@sunnylost
Last active August 29, 2015 14:08
Show Gist options
  • Save sunnylost/a3cbd63b3affa89c19f0 to your computer and use it in GitHub Desktop.
Save sunnylost/a3cbd63b3affa89c19f0 to your computer and use it in GitHub Desktop.
A simple template checker
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Check Template</title>
</head>
<body>
<iframe id="iframe" style="visibility:hidden;"></iframe>
<script type="text/tmpl" id="t1">
<? item && $.each(item , function(key , data){?>
<li class="item <? if(key == 0) { ?>cur<? } ?>"><?= data.name ?> (<?= data.total ?>)</li>
<?});?>
<li class="last_item"><label><input class="all_rate_btn" checked="checked" type="checkbox"/> 只看有内容的评价</label></li>
</script>
<script>
//c == '<' || c == '>' || c == '=' || c == '?'
function checkTemplate(str, data) {
'use strict';
var source = document.getElementById(str).innerHTML,
sourceLines;
source = source ? source.trim() : '';
sourceLines = source.split(/[\r\n]/);
data = data || {};
var len = source.length,
i = 0,
lineNum = 1,
line = [],
codePieces = [],
placeholder = 0,
stmts = '',
c,
isBegin = false,
isQuestionMark = false,
isInExpression = false,
isInStatement = false;
codePieces[0] = line;
line.extraPlaceHolder = 0;
for(; i < len; i++) {
c = source[i];
switch(c) {
case '\n':
line = codePieces[lineNum++] = [];
line.extraPlaceHolder = 0;
break;
case '<':
isBegin = true;
placeholder++;
break;
case '?':
isQuestionMark = true;
if(isBegin) {
placeholder++;
line.push(new Array(placeholder + 1).join(' '));
isInStatement = true;
placeholder = 0;
break;
}
placeholder++;
break;
case '=':
if(isInStatement && isQuestionMark) {
isInExpression = true;
break;
}
case '>':
if(isQuestionMark) {
if(isInExpression) {
stmts += ';';
line.extraPlaceHolder++;
}
line.push(stmts);
isQuestionMark = isInStatement = isInExpression = false;
stmts = '';
break;
}
default:
if(isInStatement) {
stmts += c;
} else {
placeholder++;
}
isBegin = isQuestionMark = false;
break;
}
}
var fn = '(function() {\r\n';
codePieces.forEach(function(v, i) {
fn += v.join('') + '\r\n';
});
fn += '}.call(JSON.parse("' + JSON.stringify(data) + '")))';
/*
onerror arguments:https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers.onerror
*/
iframe.contentWindow.onerror = function(msg, _, line, col, error) {
var code,
prePos = 10,
errorMessageStyle = 'color:#fff;font-weight:bold;background-color:#f00;';
/*
上面 fn 中在定义函数名后有换行,所以这里减 2
*/
line = line && line > 2 ? (line - 2) : 0;
if(line > codePieces.length) return false;
var extraCol = codePieces[line].extraPlaceHolder;
code = sourceLines[line]
col = col ? (col - extraCol) : 0;
var start = col > prePos ? (col - prePos) : 0;
console.group('Error');
console.log('Error occurs at Line:', line + 1, ' Col:', col);
if(line != 0) {
console.log(sourceLines[line - 1]);
}
console.log(code.substring(0, start) + '%c' + code.substring(start, col + prePos) + '...', errorMessageStyle);
if(line != sourceLines.length - 1) {
console.log(sourceLines[line + 1]);
}
requestAnimationFrame(function() {
console.groupEnd();
});
return false;
};
var doc = iframe.contentDocument;
var s = doc.createElement('script');
s.innerHTML = fn;
doc.body.appendChild(s);
return codePieces;
}
var obj = checkTemplate('t1');
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment