Code
·
134 lines
·
2896 bytes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134function XSS(unsafe)
{
if (Array.isArray(unsafe))
{
return unsafe.map(item => XSS(item)).join(', ');
}
if (unsafe === null || unsafe === undefined)
{
return '';
}
return String(unsafe).replace(/[&<>"']/g, match =>
({
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
}[match]));
}
// Template functionality
Element.prototype.Template = function (template, data, append)
{
var strHtml = window.TemplateHtml(template, data);
if (append)
{
var temp = document.createElement("span");
temp.innerHTML = strHtml;
this.insertAdjacentElement('beforeend', temp);
}
else
{
this.innerHTML = strHtml;
}
};
function TemplateHtml(template, data)
{
try
{
var element = typeof template === "string" ? document.getElementById(template) : template;
if (!element)
throw new Error("Template not found.");
if (!element.jscache)
{
var html = element.textContent.replace(/\s+/g, ' ').trim();
var jsParts = ["let _='';"];
var concatParts = [];
var index = 0;
while (index < html.length)
{
var start = html.indexOf('<%', index);
if (start < 0)
{
concatParts.push("'" + html.slice(index).replace(/'/g, "\\'") + "'");
if (concatParts.length > 0)
{
jsParts.push("_+=" + concatParts.join('+') + ";");
concatParts = [];
}
break;
}
if (start > index)
{
concatParts.push("'" + html.slice(index, start).replace(/'/g, "\\'") + "'");
}
index = start + 2;
var is_ = html[index] === '=';
if (is_)
index++;
var end = html.indexOf('%>', index);
if (end < 0)
throw new Error("Unclosed template tag.");
var code = html.slice(index, end).trim();
if (is_)
{
concatParts.push("XSS(" + code + ")");
}
else
{
if (concatParts.length > 0)
{
jsParts.push("_+=" + concatParts.join('+') + ";");
concatParts = [];
}
jsParts.push(code + ";");
}
index = end + 2;
}
if (concatParts.length > 0)
{
jsParts.push("_+=" + concatParts.join('+') + ";");
concatParts = [];
}
jsParts.push('return _;');
var js = jsParts.join('');
jsParts = [];
element.jscache = function (data)
{
var context = { data, XSS };
for (var key in data)
{
if (typeof data[key] === 'function')
{
try
{
context.data[key] = data[key]();
}
catch (err)
{
console.error(`Error executing function ${key}: ${err.message}`);
context.data[key] = '';
}
}
}
try
{
return (function (ctx) { with (ctx) { return eval('(function() {' + js + '})()'); } })(context);
}
catch (err)
{
console.error(`Template execution error: ${err.message}`);
return '';
}
};
}
return element.jscache(data);
}
catch (err)
{
console.error("Template error:", err.message);
return "";
}
}