function Template (textString, optionsObject) { // new Template("Total: <%= value %>", {delimiters: ["<%", '%>"]}).render({value: 10})
if (!optionsObject) {optionsObject = {};}
if (!optionsObject.hasOwnProperty("delimiters")) {
optionsObject.delimiters = ["<%", "%>"];
}
var openDelimiter = optionsObject.delimiters[0] // <%
, closeDelimiter = optionsObject.delimiters[1] // %>
, stringInsideDelimiters = "([\\s\\S]+?)" // some string
, tags = {
interpolate: openDelimiter + "=" + stringInsideDelimiters + closeDelimiter // <%= some string %>
, escape: openDelimiter + "-" + stringInsideDelimiters + closeDelimiter // <%- some string %>
, evaluate: openDelimiter + stringInsideDelimiters + closeDelimiter // <% some string %>
}
, matcherRegExp = RegExp([
tags.interpolate
, tags.escape
, tags.evaluate // Important!!! Must be last!
].join("|") + "|$", "g") // /<%=([\s\S]+?)%>|<%-([\s\S]+?)%>|<%([\s\S]+?)%>|$/g
, escapeReqExp = new RegExp([
"\\\\" // single backslash
, "'" // single quote
, "\\r" // carriage return
, "\\n" // newline
, "\\u2028" // line separator
, "\\u2029" // paragraph separator
].join("|"), "g") // /\\|'|\r|\n|\u2028|\u2029/g
, escapeCharacter = function (match) {
var characters = {
"'": "\\'"
, "\\": "\\\\"
, "\r": "\\r"
, "\n": "\\n"
, "\u2028": "\\u2028"
, "\u2029": "\\u2029"
};
return characters[match];
}
, escapeTags = function (string) {
string = (string === null) ? "" : "" + string;
var escapeMap = {
"&": "&"
, "<": "<"
, ">": ">"
, '"': """
, "'": "'"
, "`": "`"
}
, escapeSymbols = function (match) {
return escapeMap[match];
}
, getKeys = function (object) {
var keys = [];
for (var key in object) {
if (object.hasOwnProperty(key)) {keys.push(key);}
}
return keys;
}
, pattern = "(?:" + getKeys(escapeMap).join("|") + ")" // (?:&|<|>|"|'|`)
, testRegExp = RegExp(pattern)
, replaceRegExp = RegExp(pattern, "g");
return testRegExp.test(string) ? string.replace(replaceRegExp, escapeSymbols) : string;
}
, renderFunction
, render;
try {
renderFunction = new Function(
"dataObject"
, "escapeTags"
, "var temp"
+ " , result = '';"
+ "with (dataObject || {}) {"
+ " result += '" + (function(){
var resultString = ""
, index = 0;
textString.replace(matcherRegExp, function (match, interpolateCodeString, escapeCodeString, evaluateCodeString, offset) {
resultString += textString.slice(index, offset)
.replace(escapeReqExp, escapeCharacter);
index = offset + match.length;
if (interpolateCodeString) {
resultString += "' + ( ( temp = (" + interpolateCodeString + ") ) === null ? '' : temp) + '";
} else if (escapeCodeString) {
resultString += "' + ( ( temp = (" + escapeCodeString + ") ) === null ? '' : escapeTags(temp)) + '";
} else if (evaluateCodeString) {
resultString += "';" + evaluateCodeString + "result += '";
}
return match;
});
return resultString;
})()
+ "';"
+ "}"
+ "return result;"
);
} catch (error) {
throw error;
}
this.render = function (dataObject) {
return renderFunction.call(null, dataObject, escapeTags);
};
}
console.log(new Template("Total: <% if (true) { %>1<% } %>").render({value: '<div>1</div>'}));
console.log(new Template("Total: <%= value %>").render({value: '<div>1</div>'}));
console.log(new Template("Total: <%- value %>").render({value: '<div>1</div>'}));
console.log(new Template("Total: {{= value }}", {delimiters: ["{{", "}}"]}).render({value: '<div>1</div>'}));
Комментариев нет:
Отправить комментарий