Unreviewed, rolling out r216677.
[WebKit-https.git] / PerformanceTests / Speedometer / resources / todomvc / dependency-examples / flight / app / js / utils.js
1 /*global define */
2 'use strict';
3
4 // tmpl function scooped from underscore.
5 // http://documentcloud.github.com/underscore/#template
6 define(function () {
7     var _ = {};
8
9     // List of HTML entities for escaping.
10     var entityMap = {
11         escape: {
12             '&': '&',
13             '<': '&lt;',
14             '>': '&gt;',
15             '"': '&quot;',
16             /*jshint quotmark:false */
17             "'": '&#x27;',
18             '/': '&#x2F;'
19         }
20     };
21
22     var escapeKeys = '&<>"\'/';
23     var unescapeKeys = '&amp;|&lt;|&gt;|&quot;|&#x27;|&#x2F;';
24
25     // Regexes containing the keys and values listed immediately above.
26     var entityRegexes = {
27         escape:   new RegExp('[' + escapeKeys + ']', 'g'),
28         unescape: new RegExp('(' + unescapeKeys + ')', 'g')
29     };
30
31     // Functions for escaping and unescaping strings to/from HTML interpolation.
32     ['escape', 'unescape'].forEach(function (method) {
33         _[method] = function (string) {
34             if (string === null || string === undefined) {
35                 return '';
36             }
37
38             return ('' + string).replace(entityRegexes[method], function (match) {
39                 return entityMap[method][match];
40             });
41         };
42     });
43
44     var settings = {
45         evaluate: /<%([\s\S]+?)%>/g,
46         interpolate: /<%=([\s\S]+?)%>/g,
47         escape: /<%-([\s\S]+?)%>/g
48     };
49
50     var noMatch = /(.)^/;
51     var escapes = {
52         /*jshint quotmark:false */
53         "'": "'",
54         '\\': '\\',
55         '\r': 'r',
56         '\n': 'n',
57         '\t': 't',
58         '\u2028': 'u2028',
59         '\u2029': 'u2029'
60     };
61
62     var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
63
64     // JavaScript micro-templating, similar to John Resig's implementation.
65     // Underscore templating handles arbitrary delimiters, preserves whitespace,
66     // and correctly escapes quotes within interpolated code.
67     var template = function (text, data) {
68         var render;
69
70         // Combine delimiters into one regular expression via alternation.
71         var matcher = new RegExp([
72             (settings.escape || noMatch).source,
73             (settings.interpolate || noMatch).source,
74             (settings.evaluate || noMatch).source
75         ].join('|') + '|$', 'g');
76
77         // Compile the template source, escaping string literals appropriately.
78         var index = 0;
79         var source = "__p+='";
80         text.replace(matcher, function (match, escape, interpolate, evaluate, offset) {
81             source += text.slice(index, offset)
82             .replace(escaper, function (match) {
83                 return '\\' + escapes[match];
84             });
85
86             if (escape) {
87                 source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
88             }
89             if (interpolate) {
90                 source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
91             }
92             if (evaluate) {
93                 source += "';\n" + evaluate + "\n__p+='";
94             }
95             index = offset + match.length;
96             return match;
97         });
98         source += "';\n";
99
100         // If a variable is not specified, place data values in local scope.
101         if (!settings.variable) {
102             source = 'with(obj||{}){\n' + source + '}\n';
103         }
104
105         source = "var __t,__p='',__j=Array.prototype.join," +
106             "print=function(){__p+=__j.call(arguments,'');};\n" +
107             source + "return __p;\n";
108
109         try {
110             /*jshint evil:true */
111             render = new Function(settings.variable || 'obj', '_', source);
112         } catch (err) {
113             err.source = source;
114             throw err;
115         }
116
117         if (data) {
118             return render(data, _);
119         }
120
121         var template = function (data) {
122             return render.call(this, data, _);
123         };
124
125         // Provide the compiled function source as a convenience for precompilation.
126         template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
127
128         return template;
129     };
130
131     return {
132         tmpl: template
133     };
134 });