source: frontend/node_modules/underscore/amd/template.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 13 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 3.4 KB
Line 
1define(['./defaults', './underscore', './templateSettings'], function (defaults, underscore, templateSettings) {
2
3 // When customizing `_.templateSettings`, if you don't want to define an
4 // interpolation, evaluation or escaping regex, we need one that is
5 // guaranteed not to match.
6 var noMatch = /(.)^/;
7
8 // Certain characters need to be escaped so that they can be put into a
9 // string literal.
10 var escapes = {
11 "'": "'",
12 '\\': '\\',
13 '\r': 'r',
14 '\n': 'n',
15 '\u2028': 'u2028',
16 '\u2029': 'u2029'
17 };
18
19 var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g;
20
21 function escapeChar(match) {
22 return '\\' + escapes[match];
23 }
24
25 // In order to prevent third-party code injection through
26 // `_.templateSettings.variable`, we test it against the following regular
27 // expression. It is intentionally a bit more liberal than just matching valid
28 // identifiers, but still prevents possible loopholes through defaults or
29 // destructuring assignment.
30 var bareIdentifier = /^\s*(\w|\$)+\s*$/;
31
32 // JavaScript micro-templating, similar to John Resig's implementation.
33 // Underscore templating handles arbitrary delimiters, preserves whitespace,
34 // and correctly escapes quotes within interpolated code.
35 // NB: `oldSettings` only exists for backwards compatibility.
36 function template(text, settings, oldSettings) {
37 if (!settings && oldSettings) settings = oldSettings;
38 settings = defaults({}, settings, underscore.templateSettings);
39
40 // Combine delimiters into one regular expression via alternation.
41 var matcher = RegExp([
42 (settings.escape || noMatch).source,
43 (settings.interpolate || noMatch).source,
44 (settings.evaluate || noMatch).source
45 ].join('|') + '|$', 'g');
46
47 // Compile the template source, escaping string literals appropriately.
48 var index = 0;
49 var source = "__p+='";
50 text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
51 source += text.slice(index, offset).replace(escapeRegExp, escapeChar);
52 index = offset + match.length;
53
54 if (escape) {
55 source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
56 } else if (interpolate) {
57 source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
58 } else if (evaluate) {
59 source += "';\n" + evaluate + "\n__p+='";
60 }
61
62 // Adobe VMs need the match returned to produce the correct offset.
63 return match;
64 });
65 source += "';\n";
66
67 var argument = settings.variable;
68 if (argument) {
69 // Insure against third-party code injection. (CVE-2021-23358)
70 if (!bareIdentifier.test(argument)) throw new Error(
71 'variable is not a bare identifier: ' + argument
72 );
73 } else {
74 // If a variable is not specified, place data values in local scope.
75 source = 'with(obj||{}){\n' + source + '}\n';
76 argument = 'obj';
77 }
78
79 source = "var __t,__p='',__j=Array.prototype.join," +
80 "print=function(){__p+=__j.call(arguments,'');};\n" +
81 source + 'return __p;\n';
82
83 var render;
84 try {
85 render = new Function(argument, '_', source);
86 } catch (e) {
87 e.source = source;
88 throw e;
89 }
90
91 var template = function(data) {
92 return render.call(this, data, underscore);
93 };
94
95 // Provide the compiled source as a convenience for precompilation.
96 template.source = 'function(' + argument + '){\n' + source + '}';
97
98 return template;
99 }
100
101 return template;
102
103});
Note: See TracBrowser for help on using the repository browser.