~ubuntu-branches/ubuntu/utopic/moodle/utopic

« back to all changes in this revision

Viewing changes to lib/yuilib/3.9.1/build/template-micro/template-micro.js

  • Committer: Package Import Robot
  • Author(s): Thijs Kinkhorst
  • Date: 2014-05-12 16:10:38 UTC
  • mfrom: (36.1.3 sid)
  • Revision ID: package-import@ubuntu.com-20140512161038-puyqf65k4e0s8ytz
Tags: 2.6.3-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* YUI 3.9.1 (build 5852) Copyright 2013 Yahoo! Inc. http://yuilibrary.com/license/ */
2
 
YUI.add('template-micro', function (Y, NAME) {
3
 
 
4
 
/*jshint expr:true */
5
 
 
6
 
/**
7
 
Adds the `Y.Template.Micro` template engine, which provides fast, simple
8
 
string-based micro-templating similar to ERB or Underscore templates.
9
 
 
10
 
@module template
11
 
@submodule template-micro
12
 
@since 3.8.0
13
 
**/
14
 
 
15
 
/**
16
 
Fast, simple string-based micro-templating engine similar to ERB or Underscore
17
 
templates.
18
 
 
19
 
@class Template.Micro
20
 
@static
21
 
@since 3.8.0
22
 
**/
23
 
 
24
 
// This code was heavily inspired by Underscore.js's _.template() method
25
 
// (written by Jeremy Ashkenas), which was in turn inspired by John Resig's
26
 
// micro-templating implementation.
27
 
 
28
 
var Micro = Y.namespace('Template.Micro');
29
 
 
30
 
/**
31
 
Default options for `Y.Template.Micro`.
32
 
 
33
 
@property {Object} options
34
 
 
35
 
    @param {RegExp} [options.code] Regex that matches code blocks like
36
 
        `<% ... %>`.
37
 
    @param {RegExp} [options.escapedOutput] Regex that matches escaped output
38
 
        tags like `<%= ... %>`.
39
 
    @param {RegExp} [options.rawOutput] Regex that matches raw output tags like
40
 
        `<%== ... %>`.
41
 
    @param {RegExp} [options.stringEscape] Regex that matches characters that
42
 
        need to be escaped inside single-quoted JavaScript string literals.
43
 
    @param {Object} [options.stringReplace] Hash that maps characters matched by
44
 
        `stringEscape` to the strings they should be replaced with. If you add
45
 
        a character to the `stringEscape` regex, you need to add it here too or
46
 
        it will be replaced with an empty string.
47
 
 
48
 
@static
49
 
@since 3.8.0
50
 
**/
51
 
Micro.options = {
52
 
    code         : /<%([\s\S]+?)%>/g,
53
 
    escapedOutput: /<%=([\s\S]+?)%>/g,
54
 
    rawOutput    : /<%==([\s\S]+?)%>/g,
55
 
    stringEscape : /\\|'|\r|\n|\t|\u2028|\u2029/g,
56
 
 
57
 
    stringReplace: {
58
 
        '\\'    : '\\\\',
59
 
        "'"     : "\\'",
60
 
        '\r'    : '\\r',
61
 
        '\n'    : '\\n',
62
 
        '\t'    : '\\t',
63
 
        '\u2028': '\\u2028',
64
 
        '\u2029': '\\u2029'
65
 
    }
66
 
};
67
 
 
68
 
/**
69
 
Compiles a template string into a JavaScript function. Pass a data object to the
70
 
function to render the template using the given data and get back a rendered
71
 
string.
72
 
 
73
 
Within a template, use `<%= ... %>` to output the value of an expression (where
74
 
`...` is the JavaScript expression or data variable to evaluate). The output
75
 
will be HTML-escaped by default. To output a raw value without escaping, use
76
 
`<%== ... %>`, but be careful not to do this with untrusted user input.
77
 
 
78
 
To execute arbitrary JavaScript code within the template without rendering its
79
 
output, use `<% ... %>`, where `...` is the code to be executed. This allows the
80
 
use of if/else blocks, loops, function calls, etc., although it's recommended
81
 
that you avoid embedding anything beyond basic flow control logic in your
82
 
templates.
83
 
 
84
 
Properties of the data object passed to a template function are made available
85
 
on a `data` variable within the scope of the template. So, if you pass in
86
 
the object `{message: 'hello!'}`, you can print the value of the `message`
87
 
property using `<%= data.message %>`.
88
 
 
89
 
@example
90
 
 
91
 
    YUI().use('template-micro', function (Y) {
92
 
        var template = '<ul class="<%= data.classNames.list %>">' +
93
 
                           '<% Y.Array.each(data.items, function (item) { %>' +
94
 
                               '<li><%= item %></li>' +
95
 
                           '<% }); %>' +
96
 
                       '</ul>';
97
 
 
98
 
        // Compile the template into a function.
99
 
        var compiled = Y.Template.Micro.compile(template);
100
 
 
101
 
        // Render the template to HTML, passing in the data to use.
102
 
        var html = compiled({
103
 
            classNames: {list: 'demo'},
104
 
            items     : ['one', 'two', 'three', 'four']
105
 
        });
106
 
    });
107
 
 
108
 
@method compile
109
 
@param {String} text Template text to compile.
110
 
@param {Object} [options] Options. If specified, these options will override the
111
 
    default options defined in `Y.Template.Micro.options`. See the documentation
112
 
    for that property for details on which options are available.
113
 
@return {Function} Compiled template function. Execute this function and pass in
114
 
    a data object to render the template with the given data.
115
 
@static
116
 
@since 3.8.0
117
 
**/
118
 
Micro.compile = function (text, options) {
119
 
    /*jshint evil:true */
120
 
 
121
 
    var blocks     = [],
122
 
        tokenClose = "\uffff",
123
 
        tokenOpen  = "\ufffe",
124
 
        source;
125
 
 
126
 
    options = Y.merge(Micro.options, options);
127
 
 
128
 
    // Parse the input text into a string of JavaScript code, with placeholders
129
 
    // for code blocks. Text outside of code blocks will be escaped for safe
130
 
    // usage within a double-quoted string literal.
131
 
    //
132
 
    // $b is a blank string, used to avoid creating lots of string objects.
133
 
    //
134
 
    // $v is a function that returns the supplied value if the value is truthy
135
 
    // or the number 0, or returns an empty string if the value is falsy and not
136
 
    // 0.
137
 
    //
138
 
    // $t is the template string.
139
 
    source = "var $b='', $v=function (v){return v || v === 0 ? v : $b;}, $t='" +
140
 
 
141
 
        // U+FFFE and U+FFFF are guaranteed to represent non-characters, so no
142
 
        // valid UTF-8 string should ever contain them. That means we can freely
143
 
        // strip them out of the input text (just to be safe) and then use them
144
 
        // for our own nefarious purposes as token placeholders!
145
 
        //
146
 
        // See http://en.wikipedia.org/wiki/Mapping_of_Unicode_characters#Noncharacters
147
 
        text.replace(/\ufffe|\uffff/g, '')
148
 
 
149
 
        .replace(options.rawOutput, function (match, code) {
150
 
            return tokenOpen + (blocks.push("'+\n$v(" + code + ")+\n'") - 1) + tokenClose;
151
 
        })
152
 
 
153
 
        .replace(options.escapedOutput, function (match, code) {
154
 
            return tokenOpen + (blocks.push("'+\n$e($v(" + code + "))+\n'") - 1) + tokenClose;
155
 
        })
156
 
 
157
 
        .replace(options.code, function (match, code) {
158
 
            return tokenOpen + (blocks.push("';\n" + code + "\n$t+='") - 1) + tokenClose;
159
 
        })
160
 
 
161
 
        .replace(options.stringEscape, function (match) {
162
 
            return options.stringReplace[match] || '';
163
 
        })
164
 
 
165
 
        // Replace the token placeholders with code.
166
 
        .replace(/\ufffe(\d+)\uffff/g, function (match, index) {
167
 
            return blocks[parseInt(index, 10)];
168
 
        })
169
 
 
170
 
        // Remove noop string concatenations that have been left behind.
171
 
        .replace(/\n\$t\+='';\n/g, '\n') +
172
 
 
173
 
        "';\nreturn $t;";
174
 
 
175
 
    // If compile() was called from precompile(), return precompiled source.
176
 
    if (options.precompile) {
177
 
        return "function (Y, $e, data) {\n" + source + "\n}";
178
 
    }
179
 
 
180
 
    // Otherwise, return an executable function.
181
 
    return this.revive(new Function('Y', '$e', 'data', source));
182
 
};
183
 
 
184
 
/**
185
 
Precompiles the given template text into a string of JavaScript source code that
186
 
can be evaluated later in another context (or on another machine) to render the
187
 
template.
188
 
 
189
 
A common use case is to precompile templates at build time or on the server,
190
 
then evaluate the code on the client to render a template. The client only needs
191
 
to revive and render the template, avoiding the work of the compilation step.
192
 
 
193
 
@method precompile
194
 
@param {String} text Template text to precompile.
195
 
@param {Object} [options] Options. If specified, these options will override the
196
 
    default options defined in `Y.Template.Micro.options`. See the documentation
197
 
    for that property for details on which options are available.
198
 
@return {String} Source code for the precompiled template.
199
 
@static
200
 
@since 3.8.0
201
 
**/
202
 
Micro.precompile = function (text, options) {
203
 
    options || (options = {});
204
 
    options.precompile = true;
205
 
 
206
 
    return this.compile(text, options);
207
 
};
208
 
 
209
 
/**
210
 
Compiles and renders the given template text in a single step.
211
 
 
212
 
This can be useful for single-use templates, but if you plan to render the same
213
 
template multiple times, it's much better to use `compile()` to compile it once,
214
 
then simply call the compiled function multiple times to avoid recompiling.
215
 
 
216
 
@method render
217
 
@param {String} text Template text to render.
218
 
@param {Object} data Data to pass to the template.
219
 
@param {Object} [options] Options. If specified, these options will override the
220
 
    default options defined in `Y.Template.Micro.options`. See the documentation
221
 
    for that property for details on which options are available.
222
 
@return {String} Rendered result.
223
 
@static
224
 
@since 3.8.0
225
 
**/
226
 
Micro.render = function (text, data, options) {
227
 
    return this.compile(text, options)(data);
228
 
};
229
 
 
230
 
/**
231
 
Revives a precompiled template function into a normal compiled template function
232
 
that can be called to render the template. The precompiled function must already
233
 
have been evaluated to a function -- you can't pass raw JavaScript code to
234
 
`revive()`.
235
 
 
236
 
@method revive
237
 
@param {Function} precompiled Precompiled template function.
238
 
@return {Function} Revived template function, ready to be rendered.
239
 
@static
240
 
@since 3.8.0
241
 
**/
242
 
Micro.revive = function (precompiled) {
243
 
    return function (data) {
244
 
        data || (data = {});
245
 
        return precompiled.call(data, Y, Y.Escape.html, data);
246
 
    };
247
 
};
248
 
 
249
 
 
250
 
}, '3.9.1', {"requires": ["escape"]});