closure 1.3.1 → 1.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +142 -9
- data/bin/closure-script +19 -0
- data/closure-compiler/README +18 -4
- data/closure-compiler/compiler.jar +0 -0
- data/closure-templates/SoyToJsSrcCompiler.jar +0 -0
- data/closure-templates/soydata.js +163 -0
- data/closure-templates/soyutils.js +1191 -159
- data/closure-templates/soyutils_usegoog.js +1107 -60
- data/docs/closure/Closure.html +58 -52
- data/docs/closure/Closure/BeanShell.html +6 -3
- data/docs/closure/Closure/Compiler.html +18 -15
- data/docs/closure/Closure/Compiler/Compilation.html +9 -3
- data/docs/closure/Closure/Compiler/Error.html +3 -3
- data/docs/closure/Closure/FileResponse.html +13 -7
- data/docs/closure/Closure/Goog.html +49 -85
- data/docs/closure/Closure/Middleware.html +5 -3
- data/docs/closure/Closure/Script.html +14 -5
- data/docs/closure/Closure/Script/NotFound.html +3 -3
- data/docs/closure/Closure/Script/RenderStackOverflow.html +3 -3
- data/docs/closure/Closure/Server.html +6 -3
- data/docs/closure/Closure/ShowExceptions.html +5 -3
- data/docs/closure/Closure/Sources.html +145 -37
- data/docs/closure/Closure/Templates.html +11 -10
- data/docs/closure/Closure/Templates/Error.html +3 -3
- data/docs/closure/_index.html +4 -4
- data/docs/closure/css/full_list.css +2 -0
- data/docs/closure/css/style.css +2 -0
- data/docs/closure/file.LICENSE.html +3 -3
- data/docs/closure/file.README.html +151 -10
- data/docs/closure/frames.html +1 -1
- data/docs/closure/index.html +151 -10
- data/docs/closure/js/full_list.js +23 -6
- data/docs/closure/method_list.html +91 -83
- data/docs/closure/top-level-namespace.html +3 -3
- data/lib/closure.rb +3 -16
- data/lib/closure/compiler.rb +135 -53
- data/lib/closure/goog.rb +5 -29
- data/lib/closure/sources.rb +22 -9
- data/lib/closure/version.rb +1 -1
- data/scripts/config.ru +0 -1
- data/scripts/hello/compiler_build.js +5 -5
- data/scripts/hello/compiler_build.map +518 -522
- data/scripts/hello/compiler_debug.js +7 -13
- data/scripts/hello/legume.js +2 -2
- data/scripts/index.erb +0 -3
- data/scripts/modules/compiler_build.js +3 -3
- data/scripts/modules/compiler_build.map +11569 -11476
- data/scripts/modules/compiler_build_api.js +1 -1
- data/scripts/modules/compiler_build_app.js +71 -70
- data/scripts/modules/compiler_build_settings.js +2 -2
- data/scripts/modules/compiler_debug.js +3 -3
- data/scripts/modules/compiler_debug_api.js +2 -2
- data/scripts/modules/compiler_debug_app.js +926 -1382
- data/scripts/modules/compiler_debug_settings.js +21 -24
- metadata +8 -18
- data/externs/chrome_extensions.externs +0 -968
- data/externs/jquery-1.3.2.externs +0 -718
- data/externs/jquery-1.4.3.externs +0 -1289
- data/externs/jquery-1.4.4.externs +0 -1302
- data/externs/jquery-1.5.externs +0 -1697
- data/externs/jquery-ui.externs +0 -10
- data/externs/jquery.externs +0 -4
- data/scripts/jquery/compiler.js.erb +0 -7
- data/scripts/jquery/compiler_out.js +0 -1
- data/scripts/jquery/index.erb +0 -25
- data/scripts/jquery/jquery_1.4.4.js +0 -167
- data/scripts/jquery/jquery_test.js +0 -8
@@ -14,26 +14,40 @@
|
|
14
14
|
* limitations under the License.
|
15
15
|
*/
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
17
|
+
/**
|
18
|
+
* @fileoverview
|
19
|
+
* Utility functions and classes for Soy.
|
20
|
+
*
|
21
|
+
* <p>
|
22
|
+
* The top portion of this file contains utilities for Soy users:<ul>
|
23
|
+
* <li> soy.StringBuilder: Compatible with the 'stringbuilder' code style.
|
24
|
+
* <li> soy.renderElement: Render template and set as innerHTML of an element.
|
25
|
+
* <li> soy.renderAsFragment: Render template and return as HTML fragment.
|
26
|
+
* </ul>
|
27
|
+
*
|
28
|
+
* <p>
|
29
|
+
* The bottom portion of this file contains utilities that should only be called
|
30
|
+
* by Soy-generated JS code. Please do not use these functions directly from
|
31
|
+
* your hand-writen code. Their names all start with '$$'.
|
32
|
+
*
|
33
|
+
* @author Mike Samuel
|
34
|
+
* @author Kai Huang
|
35
|
+
* @author Aharon Lenin
|
36
|
+
*/
|
27
37
|
|
28
38
|
goog.provide('soy');
|
29
39
|
goog.provide('soy.StringBuilder');
|
40
|
+
goog.provide('soy.esc');
|
30
41
|
|
31
|
-
goog.require('goog.
|
42
|
+
goog.require('goog.asserts');
|
43
|
+
goog.require('goog.dom.DomHelper');
|
32
44
|
goog.require('goog.format');
|
33
45
|
goog.require('goog.i18n.BidiFormatter');
|
34
46
|
goog.require('goog.i18n.bidi');
|
47
|
+
goog.require('goog.soy');
|
35
48
|
goog.require('goog.string');
|
36
49
|
goog.require('goog.string.StringBuffer');
|
50
|
+
goog.require('soydata');
|
37
51
|
|
38
52
|
|
39
53
|
// -----------------------------------------------------------------------------
|
@@ -62,27 +76,62 @@ soy.StringBuilder = goog.string.StringBuffer;
|
|
62
76
|
* instead of directly setting innerHTML in your hand-written code, so that it
|
63
77
|
* will be easier to audit the code for cross-site scripting vulnerabilities.
|
64
78
|
*
|
79
|
+
* NOTE: New code should consider using goog.soy.renderElement instead.
|
80
|
+
*
|
65
81
|
* @param {Element} element The element whose content we are rendering.
|
66
82
|
* @param {Function} template The Soy template defining the element's content.
|
67
83
|
* @param {Object=} opt_templateData The data for the template.
|
84
|
+
* @param {Object=} opt_injectedData The injected data for the template.
|
68
85
|
*/
|
69
|
-
soy.renderElement =
|
70
|
-
element.innerHTML = template(opt_templateData);
|
71
|
-
};
|
86
|
+
soy.renderElement = goog.soy.renderElement;
|
72
87
|
|
73
88
|
|
74
89
|
/**
|
75
90
|
* Helper function to render a Soy template into a single node or a document
|
76
91
|
* fragment. If the rendered HTML string represents a single node, then that
|
77
|
-
* node is returned
|
92
|
+
* node is returned (note that this is *not* a fragment, despite them name of
|
93
|
+
* the method). Otherwise a document fragment is returned containing the
|
78
94
|
* rendered nodes.
|
79
95
|
*
|
96
|
+
* NOTE: New code should consider using goog.soy.renderAsFragment
|
97
|
+
* instead (note that the arguments are different).
|
98
|
+
*
|
99
|
+
* @param {Function} template The Soy template defining the element's content.
|
100
|
+
* @param {Object=} opt_templateData The data for the template.
|
101
|
+
* @param {Document=} opt_document The document used to create DOM nodes. If not
|
102
|
+
* specified, global document object is used.
|
103
|
+
* @param {Object=} opt_injectedData The injected data for the template.
|
104
|
+
* @return {!Node} The resulting node or document fragment.
|
105
|
+
*/
|
106
|
+
soy.renderAsFragment = function(
|
107
|
+
template, opt_templateData, opt_document, opt_injectedData) {
|
108
|
+
return goog.soy.renderAsFragment(
|
109
|
+
template, opt_templateData, opt_injectedData,
|
110
|
+
new goog.dom.DomHelper(opt_document));
|
111
|
+
};
|
112
|
+
|
113
|
+
|
114
|
+
/**
|
115
|
+
* Helper function to render a Soy template into a single node. If the rendered
|
116
|
+
* HTML string represents a single node, then that node is returned. Otherwise,
|
117
|
+
* a DIV element is returned containing the rendered nodes.
|
118
|
+
*
|
119
|
+
* NOTE: New code should consider using goog.soy.renderAsElement
|
120
|
+
* instead (note that the arguments are different).
|
121
|
+
*
|
80
122
|
* @param {Function} template The Soy template defining the element's content.
|
81
123
|
* @param {Object=} opt_templateData The data for the template.
|
82
|
-
* @
|
124
|
+
* @param {Document=} opt_document The document used to create DOM nodes. If not
|
125
|
+
* specified, global document object is used.
|
126
|
+
* @param {Object=} opt_injectedData The injected data for the template.
|
127
|
+
* @return {!Element} Rendered template contents, wrapped in a parent DIV
|
128
|
+
* element if necessary.
|
83
129
|
*/
|
84
|
-
soy.
|
85
|
-
|
130
|
+
soy.renderAsElement = function(
|
131
|
+
template, opt_templateData, opt_document, opt_injectedData) {
|
132
|
+
return goog.soy.renderAsElement(
|
133
|
+
template, opt_templateData, opt_injectedData,
|
134
|
+
new goog.dom.DomHelper(opt_document));
|
86
135
|
};
|
87
136
|
|
88
137
|
|
@@ -107,9 +156,9 @@ soy.$$augmentData = function(origData, additionalParams) {
|
|
107
156
|
|
108
157
|
// Create a new object whose '__proto__' field is set to origData.
|
109
158
|
/** @constructor */
|
110
|
-
function
|
111
|
-
|
112
|
-
var newData = new
|
159
|
+
function TempCtor() {}
|
160
|
+
TempCtor.prototype = origData;
|
161
|
+
var newData = new TempCtor();
|
113
162
|
|
114
163
|
// Add the additional params to the new object.
|
115
164
|
for (var key in additionalParams) {
|
@@ -121,45 +170,462 @@ soy.$$augmentData = function(origData, additionalParams) {
|
|
121
170
|
|
122
171
|
|
123
172
|
/**
|
124
|
-
*
|
173
|
+
* Gets the keys in a map as an array. There are no guarantees on the order.
|
174
|
+
* @param {Object} map The map to get the keys of.
|
175
|
+
* @return {Array.<string>} The array of keys in the given map.
|
176
|
+
*/
|
177
|
+
soy.$$getMapKeys = function(map) {
|
178
|
+
var mapKeys = [];
|
179
|
+
for (var key in map) {
|
180
|
+
mapKeys.push(key);
|
181
|
+
}
|
182
|
+
return mapKeys;
|
183
|
+
};
|
184
|
+
|
185
|
+
|
186
|
+
/**
|
187
|
+
* Gets a consistent unique id for the given delegate template name. Two calls
|
188
|
+
* to this function will return the same id if and only if the input names are
|
189
|
+
* the same.
|
190
|
+
*
|
191
|
+
* <p> Important: This function must always be called with a string constant.
|
192
|
+
*
|
193
|
+
* <p> If Closure Compiler is not being used, then this is just this identity
|
194
|
+
* function. If Closure Compiler is being used, then each call to this function
|
195
|
+
* will be replaced with a short string constant, which will be consistent per
|
196
|
+
* input name.
|
197
|
+
*
|
198
|
+
* @param {string} delTemplateName The delegate template name for which to get a
|
199
|
+
* consistent unique id.
|
200
|
+
* @return {string} A unique id that is consistent per input name.
|
201
|
+
*
|
202
|
+
* @consistentIdGenerator
|
203
|
+
*/
|
204
|
+
soy.$$getDelegateId = function(delTemplateName) {
|
205
|
+
return delTemplateName;
|
206
|
+
};
|
207
|
+
|
208
|
+
|
209
|
+
/**
|
210
|
+
* Map from registered delegate template id/name to the priority of the
|
211
|
+
* implementation.
|
212
|
+
* @type {Object}
|
213
|
+
* @private
|
214
|
+
*/
|
215
|
+
soy.$$DELEGATE_REGISTRY_PRIORITIES_ = {};
|
216
|
+
|
217
|
+
/**
|
218
|
+
* Map from registered delegate template id/name to the implementation function.
|
219
|
+
* @type {Object}
|
220
|
+
* @private
|
221
|
+
*/
|
222
|
+
soy.$$DELEGATE_REGISTRY_FUNCTIONS_ = {};
|
223
|
+
|
224
|
+
|
225
|
+
/**
|
226
|
+
* Registers a delegate implementation. If the same delegate template id/name
|
227
|
+
* has been registered previously, then priority values are compared and only
|
228
|
+
* the higher priority implementation is stored (if priorities are equal, an
|
229
|
+
* error is thrown).
|
230
|
+
*
|
231
|
+
* @param {string} delTemplateId The delegate template id/name to register.
|
232
|
+
* @param {number} delPriority The implementation's priority value.
|
233
|
+
* @param {Function} delFn The implementation function.
|
234
|
+
*/
|
235
|
+
soy.$$registerDelegateFn = function(delTemplateId, delPriority, delFn) {
|
236
|
+
var mapKey = 'key_' + delTemplateId;
|
237
|
+
var currPriority = soy.$$DELEGATE_REGISTRY_PRIORITIES_[mapKey];
|
238
|
+
if (currPriority === undefined || delPriority > currPriority) {
|
239
|
+
// Registering new or higher-priority function: replace registry entry.
|
240
|
+
soy.$$DELEGATE_REGISTRY_PRIORITIES_[mapKey] = delPriority;
|
241
|
+
soy.$$DELEGATE_REGISTRY_FUNCTIONS_[mapKey] = delFn;
|
242
|
+
} else if (delPriority == currPriority) {
|
243
|
+
// Registering same-priority function: error.
|
244
|
+
throw Error(
|
245
|
+
'Encountered two active delegates with same priority (id/name "' +
|
246
|
+
delTemplateId + '").');
|
247
|
+
} else {
|
248
|
+
// Registering lower-priority function: do nothing.
|
249
|
+
}
|
250
|
+
};
|
251
|
+
|
252
|
+
|
253
|
+
/**
|
254
|
+
* Retrieves the (highest-priority) implementation that has been registered for
|
255
|
+
* a given delegate template id/name. If no implementation has been registered
|
256
|
+
* for the id/name, then returns an implementation that is equivalent to an
|
257
|
+
* empty template (i.e. rendered output would be empty string).
|
258
|
+
*
|
259
|
+
* @param {string} delTemplateId The delegate template id/name to get.
|
260
|
+
* @return {Function} The retrieved implementation function.
|
261
|
+
*/
|
262
|
+
soy.$$getDelegateFn = function(delTemplateId) {
|
263
|
+
var delFn = soy.$$DELEGATE_REGISTRY_FUNCTIONS_['key_' + delTemplateId];
|
264
|
+
return delFn ? delFn : soy.$$EMPTY_TEMPLATE_FN_;
|
265
|
+
};
|
266
|
+
|
267
|
+
|
268
|
+
/**
|
269
|
+
* Private helper soy.$$getDelegateFn(). This is the empty template function
|
270
|
+
* that is returned whenever there's no delegate implementation found.
|
271
|
+
*
|
272
|
+
* @param {Object.<string, *>=} opt_data
|
273
|
+
* @param {soy.StringBuilder=} opt_sb
|
274
|
+
* @param {Object.<string, *>=} opt_ijData
|
275
|
+
* @return {string}
|
276
|
+
* @private
|
277
|
+
*/
|
278
|
+
soy.$$EMPTY_TEMPLATE_FN_ = function(opt_data, opt_sb, opt_ijData) {
|
279
|
+
return '';
|
280
|
+
};
|
281
|
+
|
282
|
+
|
283
|
+
/**
|
284
|
+
* Used for temporary fix. See GenJsCodeVisitor.java.
|
285
|
+
* TODO: Remove when i18n plurals team provides a better # processing option.
|
286
|
+
* @param {string} str The string to escape.
|
287
|
+
* @return {string} The escaped string.
|
288
|
+
*/
|
289
|
+
soy.$$tempHashEscape = function(str) {
|
290
|
+
return str.replace(soy.$$HASH_RE_, '__HashLit__');
|
291
|
+
};
|
292
|
+
|
293
|
+
/**
|
294
|
+
* Used by soy.$$tempHashEscape().
|
295
|
+
* @type {RegExp}
|
296
|
+
* @private
|
297
|
+
*/
|
298
|
+
soy.$$HASH_RE_ = /#/g;
|
299
|
+
|
300
|
+
|
301
|
+
/**
|
302
|
+
* Used for temporary fix. See GenJsCodeVisitor.java.
|
303
|
+
* TODO: Remove when i18n plurals team provides a better # processing option.
|
304
|
+
* @param {string} str The string to unescape.
|
305
|
+
* @return {string} The unescaped string.
|
306
|
+
*/
|
307
|
+
soy.$$tempHashUnescape = function(str) {
|
308
|
+
return str.replace(soy.$$HASH_ESCAPED_RE_, '#');
|
309
|
+
};
|
310
|
+
|
311
|
+
/**
|
312
|
+
* Used by soy.$$tempHashUnescape().
|
313
|
+
* @type {RegExp}
|
314
|
+
* @private
|
315
|
+
*/
|
316
|
+
soy.$$HASH_ESCAPED_RE_ = /__HashLit__/g;
|
317
|
+
|
318
|
+
|
319
|
+
// -----------------------------------------------------------------------------
|
320
|
+
// Escape/filter/normalize.
|
321
|
+
|
322
|
+
|
323
|
+
/**
|
324
|
+
* Escapes HTML special characters in a string. Escapes double quote '"' in
|
125
325
|
* addition to '&', '<', and '>' so that a string can be included in an HTML
|
126
326
|
* tag attribute value within double quotes.
|
327
|
+
* Will emit known safe HTML as-is.
|
328
|
+
*
|
329
|
+
* @param {*} value The string-like value to be escaped. May not be a string,
|
330
|
+
* but the value will be coerced to a string.
|
331
|
+
* @return {string} An escaped version of value.
|
332
|
+
*/
|
333
|
+
soy.$$escapeHtml = function(value) {
|
334
|
+
if (typeof value === 'object' && value &&
|
335
|
+
value.contentKind === soydata.SanitizedContentKind.HTML) {
|
336
|
+
return value.content;
|
337
|
+
}
|
338
|
+
return soy.esc.$$escapeHtmlHelper(value);
|
339
|
+
};
|
340
|
+
|
341
|
+
|
342
|
+
/**
|
343
|
+
* Escapes HTML special characters in a string so that it can be embedded in
|
344
|
+
* RCDATA.
|
345
|
+
* <p>
|
346
|
+
* Escapes HTML special characters so that the value will not prematurely end
|
347
|
+
* the body of a tag like {@code <textarea>} or {@code <title>}. RCDATA tags
|
348
|
+
* cannot contain other HTML entities, so it is not strictly necessary to escape
|
349
|
+
* HTML special characters except when part of that text looks like an HTML
|
350
|
+
* entity or like a close tag : {@code </textarea>}.
|
351
|
+
* <p>
|
352
|
+
* Will normalize known safe HTML to make sure that sanitized HTML (which could
|
353
|
+
* contain an innocuous {@code </textarea>} don't prematurely end an RCDATA
|
354
|
+
* element.
|
355
|
+
*
|
356
|
+
* @param {*} value The string-like value to be escaped. May not be a string,
|
357
|
+
* but the value will be coerced to a string.
|
358
|
+
* @return {string} An escaped version of value.
|
359
|
+
*/
|
360
|
+
soy.$$escapeHtmlRcdata = function(value) {
|
361
|
+
if (typeof value === 'object' && value &&
|
362
|
+
value.contentKind === soydata.SanitizedContentKind.HTML) {
|
363
|
+
return soy.esc.$$normalizeHtmlHelper(value.content);
|
364
|
+
}
|
365
|
+
return soy.esc.$$escapeHtmlHelper(value);
|
366
|
+
};
|
367
|
+
|
368
|
+
|
369
|
+
/**
|
370
|
+
* Removes HTML tags from a string of known safe HTML so it can be used as an
|
371
|
+
* attribute value.
|
372
|
+
*
|
373
|
+
* @param {*} value The HTML to be escaped. May not be a string, but the
|
374
|
+
* value will be coerced to a string.
|
375
|
+
* @return {string} A representation of value without tags, HTML comments, or
|
376
|
+
* other content.
|
377
|
+
*/
|
378
|
+
soy.$$stripHtmlTags = function(value) {
|
379
|
+
return String(value).replace(soy.esc.$$HTML_TAG_REGEX_, '');
|
380
|
+
};
|
381
|
+
|
382
|
+
|
383
|
+
/**
|
384
|
+
* Escapes HTML special characters in an HTML attribute value.
|
127
385
|
*
|
128
|
-
* @param {*}
|
386
|
+
* @param {*} value The HTML to be escaped. May not be a string, but the
|
387
|
+
* value will be coerced to a string.
|
388
|
+
* @return {string} An escaped version of value.
|
389
|
+
*/
|
390
|
+
soy.$$escapeHtmlAttribute = function(value) {
|
391
|
+
if (typeof value === 'object' && value &&
|
392
|
+
value.contentKind === soydata.SanitizedContentKind.HTML) {
|
393
|
+
return soy.esc.$$normalizeHtmlHelper(soy.$$stripHtmlTags(value.content));
|
394
|
+
}
|
395
|
+
return soy.esc.$$escapeHtmlHelper(value);
|
396
|
+
};
|
397
|
+
|
398
|
+
|
399
|
+
/**
|
400
|
+
* Escapes HTML special characters in a string including space and other
|
401
|
+
* characters that can end an unquoted HTML attribute value.
|
402
|
+
*
|
403
|
+
* @param {*} value The HTML to be escaped. May not be a string, but the
|
404
|
+
* value will be coerced to a string.
|
405
|
+
* @return {string} An escaped version of value.
|
406
|
+
*/
|
407
|
+
soy.$$escapeHtmlAttributeNospace = function(value) {
|
408
|
+
if (typeof value === 'object' && value &&
|
409
|
+
value.contentKind === soydata.SanitizedContentKind.HTML) {
|
410
|
+
return soy.esc.$$normalizeHtmlNospaceHelper(
|
411
|
+
soy.$$stripHtmlTags(value.content));
|
412
|
+
}
|
413
|
+
return soy.esc.$$escapeHtmlNospaceHelper(value);
|
414
|
+
};
|
415
|
+
|
416
|
+
|
417
|
+
/**
|
418
|
+
* Filters out strings that cannot be a substring of a valid HTML attribute.
|
419
|
+
*
|
420
|
+
* @param {*} value The value to escape. May not be a string, but the value
|
421
|
+
* will be coerced to a string.
|
422
|
+
* @return {string} A valid HTML attribute name part or name/value pair.
|
423
|
+
* {@code "zSoyz"} if the input is invalid.
|
424
|
+
*/
|
425
|
+
soy.$$filterHtmlAttribute = function(value) {
|
426
|
+
if (typeof value === 'object' && value &&
|
427
|
+
value.contentKind === soydata.SanitizedContentKind.HTML_ATTRIBUTE) {
|
428
|
+
return value.content.replace(/=([^"']*)$/, '="$1"');
|
429
|
+
}
|
430
|
+
return soy.esc.$$filterHtmlAttributeHelper(value);
|
431
|
+
};
|
432
|
+
|
433
|
+
|
434
|
+
/**
|
435
|
+
* Filters out strings that cannot be a substring of a valid HTML element name.
|
436
|
+
*
|
437
|
+
* @param {*} value The value to escape. May not be a string, but the value
|
438
|
+
* will be coerced to a string.
|
439
|
+
* @return {string} A valid HTML element name part.
|
440
|
+
* {@code "zSoyz"} if the input is invalid.
|
441
|
+
*/
|
442
|
+
soy.$$filterHtmlElementName = function(value) {
|
443
|
+
return soy.esc.$$filterHtmlElementNameHelper(value);
|
444
|
+
};
|
445
|
+
|
446
|
+
|
447
|
+
/**
|
448
|
+
* Escapes characters in the value to make it valid content for a JS string
|
449
|
+
* literal.
|
450
|
+
*
|
451
|
+
* @param {*} value The value to escape. May not be a string, but the value
|
129
452
|
* will be coerced to a string.
|
130
|
-
* @return {string} An escaped
|
131
|
-
|
132
|
-
|
133
|
-
|
453
|
+
* @return {string} An escaped version of value.
|
454
|
+
* @deprecated
|
455
|
+
*/
|
456
|
+
soy.$$escapeJs = function(value) {
|
457
|
+
return soy.$$escapeJsString(value);
|
134
458
|
};
|
135
459
|
|
136
460
|
|
137
461
|
/**
|
138
|
-
* Escapes characters in the
|
462
|
+
* Escapes characters in the value to make it valid content for a JS string
|
463
|
+
* literal.
|
139
464
|
*
|
140
|
-
* @param {*}
|
465
|
+
* @param {*} value The value to escape. May not be a string, but the value
|
141
466
|
* will be coerced to a string.
|
142
|
-
* @return {string} An escaped
|
143
|
-
*/
|
144
|
-
soy.$$
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
467
|
+
* @return {string} An escaped version of value.
|
468
|
+
*/
|
469
|
+
soy.$$escapeJsString = function(value) {
|
470
|
+
if (typeof value === 'object' &&
|
471
|
+
value.contentKind === soydata.SanitizedContentKind.JS_STR_CHARS) {
|
472
|
+
return value.content;
|
473
|
+
}
|
474
|
+
return soy.esc.$$escapeJsStringHelper(value);
|
475
|
+
};
|
476
|
+
|
477
|
+
|
478
|
+
/**
|
479
|
+
* Encodes a value as a JavaScript literal.
|
480
|
+
*
|
481
|
+
* @param {*} value The value to escape. May not be a string, but the value
|
482
|
+
* will be coerced to a string.
|
483
|
+
* @return {string} A JavaScript code representation of the input.
|
484
|
+
*/
|
485
|
+
soy.$$escapeJsValue = function(value) {
|
486
|
+
// We surround values with spaces so that they can't be interpolated into
|
487
|
+
// identifiers by accident.
|
488
|
+
// We could use parentheses but those might be interpreted as a function call.
|
489
|
+
if (value == null) { // Intentionally matches undefined.
|
490
|
+
// Java returns null from maps where there is no corresponding key while
|
491
|
+
// JS returns undefined.
|
492
|
+
// We always output null for compatibility with Java which does not have a
|
493
|
+
// distinct undefined value.
|
494
|
+
return ' null ';
|
495
|
+
}
|
496
|
+
switch (typeof value) {
|
497
|
+
case 'boolean': case 'number':
|
498
|
+
return ' ' + value + ' ';
|
499
|
+
default:
|
500
|
+
return "'" + soy.esc.$$escapeJsStringHelper(String(value)) + "'";
|
149
501
|
}
|
150
|
-
return sb.join('');
|
151
502
|
};
|
152
503
|
|
153
504
|
|
154
505
|
/**
|
155
|
-
* Escapes
|
506
|
+
* Escapes characters in the string to make it valid content for a JS regular
|
507
|
+
* expression literal.
|
156
508
|
*
|
157
|
-
* @param {*}
|
509
|
+
* @param {*} value The value to escape. May not be a string, but the value
|
158
510
|
* will be coerced to a string.
|
159
|
-
* @return {string} An escaped
|
160
|
-
*/
|
161
|
-
soy.$$
|
162
|
-
return
|
511
|
+
* @return {string} An escaped version of value.
|
512
|
+
*/
|
513
|
+
soy.$$escapeJsRegex = function(value) {
|
514
|
+
return soy.esc.$$escapeJsRegexHelper(value);
|
515
|
+
};
|
516
|
+
|
517
|
+
|
518
|
+
/**
|
519
|
+
* Matches all URI mark characters that conflict with HTML attribute delimiters
|
520
|
+
* or that cannot appear in a CSS uri.
|
521
|
+
* From <a href="http://www.w3.org/TR/CSS2/grammar.html">G.2: CSS grammar</a>
|
522
|
+
* <pre>
|
523
|
+
* url ([!#$%&*-~]|{nonascii}|{escape})*
|
524
|
+
* </pre>
|
525
|
+
*
|
526
|
+
* @type {RegExp}
|
527
|
+
* @private
|
528
|
+
*/
|
529
|
+
soy.$$problematicUriMarks_ = /['()]/g;
|
530
|
+
|
531
|
+
/**
|
532
|
+
* @param {string} ch A single character in {@link soy.$$problematicUriMarks_}.
|
533
|
+
* @return {string}
|
534
|
+
* @private
|
535
|
+
*/
|
536
|
+
soy.$$pctEncode_ = function(ch) {
|
537
|
+
return '%' + ch.charCodeAt(0).toString(16);
|
538
|
+
};
|
539
|
+
|
540
|
+
/**
|
541
|
+
* Escapes a string so that it can be safely included in a URI.
|
542
|
+
*
|
543
|
+
* @param {*} value The value to escape. May not be a string, but the value
|
544
|
+
* will be coerced to a string.
|
545
|
+
* @return {string} An escaped version of value.
|
546
|
+
*/
|
547
|
+
soy.$$escapeUri = function(value) {
|
548
|
+
if (typeof value === 'object' &&
|
549
|
+
value.contentKind === soydata.SanitizedContentKind.URI) {
|
550
|
+
return soy.$$normalizeUri(value);
|
551
|
+
}
|
552
|
+
// Apostophes and parentheses are not matched by encodeURIComponent.
|
553
|
+
// They are technically special in URIs, but only appear in the obsolete mark
|
554
|
+
// production in Appendix D.2 of RFC 3986, so can be encoded without changing
|
555
|
+
// semantics.
|
556
|
+
var encoded = soy.esc.$$escapeUriHelper(value);
|
557
|
+
soy.$$problematicUriMarks_.lastIndex = 0;
|
558
|
+
if (soy.$$problematicUriMarks_.test(encoded)) {
|
559
|
+
return encoded.replace(soy.$$problematicUriMarks_, soy.$$pctEncode_);
|
560
|
+
}
|
561
|
+
return encoded;
|
562
|
+
};
|
563
|
+
|
564
|
+
|
565
|
+
/**
|
566
|
+
* Removes rough edges from a URI by escaping any raw HTML/JS string delimiters.
|
567
|
+
*
|
568
|
+
* @param {*} value The value to escape. May not be a string, but the value
|
569
|
+
* will be coerced to a string.
|
570
|
+
* @return {string} An escaped version of value.
|
571
|
+
*/
|
572
|
+
soy.$$normalizeUri = function(value) {
|
573
|
+
return soy.esc.$$normalizeUriHelper(value);
|
574
|
+
};
|
575
|
+
|
576
|
+
|
577
|
+
/**
|
578
|
+
* Vets a URI's protocol and removes rough edges from a URI by escaping
|
579
|
+
* any raw HTML/JS string delimiters.
|
580
|
+
*
|
581
|
+
* @param {*} value The value to escape. May not be a string, but the value
|
582
|
+
* will be coerced to a string.
|
583
|
+
* @return {string} An escaped version of value.
|
584
|
+
*/
|
585
|
+
soy.$$filterNormalizeUri = function(value) {
|
586
|
+
return soy.esc.$$filterNormalizeUriHelper(value);
|
587
|
+
};
|
588
|
+
|
589
|
+
|
590
|
+
/**
|
591
|
+
* Escapes a string so it can safely be included inside a quoted CSS string.
|
592
|
+
*
|
593
|
+
* @param {*} value The value to escape. May not be a string, but the value
|
594
|
+
* will be coerced to a string.
|
595
|
+
* @return {string} An escaped version of value.
|
596
|
+
*/
|
597
|
+
soy.$$escapeCssString = function(value) {
|
598
|
+
return soy.esc.$$escapeCssStringHelper(value);
|
599
|
+
};
|
600
|
+
|
601
|
+
|
602
|
+
/**
|
603
|
+
* Encodes a value as a CSS identifier part, keyword, or quantity.
|
604
|
+
*
|
605
|
+
* @param {*} value The value to escape. May not be a string, but the value
|
606
|
+
* will be coerced to a string.
|
607
|
+
* @return {string} A safe CSS identifier part, keyword, or quanitity.
|
608
|
+
*/
|
609
|
+
soy.$$filterCssValue = function(value) {
|
610
|
+
// Uses == to intentionally match null and undefined for Java compatibility.
|
611
|
+
if (value == null) {
|
612
|
+
return '';
|
613
|
+
}
|
614
|
+
return soy.esc.$$filterCssValueHelper(value);
|
615
|
+
};
|
616
|
+
|
617
|
+
|
618
|
+
// -----------------------------------------------------------------------------
|
619
|
+
// Basic directives/functions.
|
620
|
+
|
621
|
+
|
622
|
+
/**
|
623
|
+
* Converts \r\n, \r, and \n to <br>s
|
624
|
+
* @param {*} str The string in which to convert newlines.
|
625
|
+
* @return {string} A copy of {@code str} with converted newlines.
|
626
|
+
*/
|
627
|
+
soy.$$changeNewlineToBr = function(str) {
|
628
|
+
return goog.string.newLineToBr(String(str), false);
|
163
629
|
};
|
164
630
|
|
165
631
|
|
@@ -181,19 +647,80 @@ soy.$$insertWordBreaks = function(str, maxCharsBetweenWordBreaks) {
|
|
181
647
|
|
182
648
|
|
183
649
|
/**
|
184
|
-
*
|
185
|
-
*
|
186
|
-
*
|
650
|
+
* Truncates a string to a given max length (if it's currently longer),
|
651
|
+
* optionally adding ellipsis at the end.
|
652
|
+
*
|
653
|
+
* @param {*} str The string to truncate. Can be other types, but the value will
|
654
|
+
* be coerced to a string.
|
655
|
+
* @param {number} maxLen The maximum length of the string after truncation
|
656
|
+
* (including ellipsis, if applicable).
|
657
|
+
* @param {boolean} doAddEllipsis Whether to add ellipsis if the string needs
|
658
|
+
* truncation.
|
659
|
+
* @return {string} The string after truncation.
|
187
660
|
*/
|
188
|
-
soy.$$
|
189
|
-
|
661
|
+
soy.$$truncate = function(str, maxLen, doAddEllipsis) {
|
662
|
+
|
663
|
+
str = String(str);
|
664
|
+
if (str.length <= maxLen) {
|
665
|
+
return str; // no need to truncate
|
666
|
+
}
|
667
|
+
|
668
|
+
// If doAddEllipsis, either reduce maxLen to compensate, or else if maxLen is
|
669
|
+
// too small, just turn off doAddEllipsis.
|
670
|
+
if (doAddEllipsis) {
|
671
|
+
if (maxLen > 3) {
|
672
|
+
maxLen -= 3;
|
673
|
+
} else {
|
674
|
+
doAddEllipsis = false;
|
675
|
+
}
|
676
|
+
}
|
677
|
+
|
678
|
+
// Make sure truncating at maxLen doesn't cut up a unicode surrogate pair.
|
679
|
+
if (soy.$$isHighSurrogate_(str.charAt(maxLen - 1)) &&
|
680
|
+
soy.$$isLowSurrogate_(str.charAt(maxLen))) {
|
681
|
+
maxLen -= 1;
|
682
|
+
}
|
683
|
+
|
684
|
+
// Truncate.
|
685
|
+
str = str.substring(0, maxLen);
|
686
|
+
|
687
|
+
// Add ellipsis.
|
688
|
+
if (doAddEllipsis) {
|
689
|
+
str += '...';
|
690
|
+
}
|
691
|
+
|
692
|
+
return str;
|
693
|
+
};
|
694
|
+
|
695
|
+
/**
|
696
|
+
* Private helper for $$truncate() to check whether a char is a high surrogate.
|
697
|
+
* @param {string} ch The char to check.
|
698
|
+
* @return {boolean} Whether the given char is a unicode high surrogate.
|
699
|
+
* @private
|
700
|
+
*/
|
701
|
+
soy.$$isHighSurrogate_ = function(ch) {
|
702
|
+
return 0xD800 <= ch && ch <= 0xDBFF;
|
190
703
|
};
|
191
704
|
|
705
|
+
/**
|
706
|
+
* Private helper for $$truncate() to check whether a char is a low surrogate.
|
707
|
+
* @param {string} ch The char to check.
|
708
|
+
* @return {boolean} Whether the given char is a unicode low surrogate.
|
709
|
+
* @private
|
710
|
+
*/
|
711
|
+
soy.$$isLowSurrogate_ = function(ch) {
|
712
|
+
return 0xDC00 <= ch && ch <= 0xDFFF;
|
713
|
+
};
|
714
|
+
|
715
|
+
|
716
|
+
// -----------------------------------------------------------------------------
|
717
|
+
// Bidi directives/functions.
|
718
|
+
|
192
719
|
|
193
720
|
/**
|
194
721
|
* Cache of bidi formatter by context directionality, so we don't keep on
|
195
722
|
* creating new objects.
|
196
|
-
* @type {Object}
|
723
|
+
* @type {!Object.<!goog.i18n.BidiFormatter>}
|
197
724
|
* @private
|
198
725
|
*/
|
199
726
|
soy.$$bidiFormatterCache_ = {};
|
@@ -206,13 +733,37 @@ soy.$$bidiFormatterCache_ = {};
|
|
206
733
|
* @return {goog.i18n.BidiFormatter} A formatter for bidiGlobalDir.
|
207
734
|
* @private
|
208
735
|
*/
|
209
|
-
soy.$$
|
736
|
+
soy.$$getBidiFormatterInstance_ = function(bidiGlobalDir) {
|
210
737
|
return soy.$$bidiFormatterCache_[bidiGlobalDir] ||
|
211
738
|
(soy.$$bidiFormatterCache_[bidiGlobalDir] =
|
212
739
|
new goog.i18n.BidiFormatter(bidiGlobalDir));
|
213
740
|
};
|
214
741
|
|
215
742
|
|
743
|
+
/**
|
744
|
+
* Returns the leading horizontal edge, i.e. "left" or "right", depending on
|
745
|
+
* bidiGlobalDir.
|
746
|
+
* @param {number} bidiGlobalDir The global directionality context: 1 if ltr, -1
|
747
|
+
* if rtl, 0 if unknown.
|
748
|
+
* @return {string} "right" for RTL context and "left" otherwise.
|
749
|
+
*/
|
750
|
+
soy.$$bidiStartEdge = function(bidiGlobalDir) {
|
751
|
+
return soy.$$getBidiFormatterInstance_(bidiGlobalDir).startEdge();
|
752
|
+
};
|
753
|
+
|
754
|
+
|
755
|
+
/**
|
756
|
+
* Returns the trailing horizontal edge, i.e. "right" or "left", depending on
|
757
|
+
* bidiGlobalDir.
|
758
|
+
* @param {number} bidiGlobalDir The global directionality context: 1 if ltr, -1
|
759
|
+
* if rtl, 0 if unknown.
|
760
|
+
* @return {string} "left" for RTL context and "right" otherwise.
|
761
|
+
*/
|
762
|
+
soy.$$bidiEndEdge = function(bidiGlobalDir) {
|
763
|
+
return soy.$$getBidiFormatterInstance_(bidiGlobalDir).endEdge();
|
764
|
+
};
|
765
|
+
|
766
|
+
|
216
767
|
/**
|
217
768
|
* Estimate the overall directionality of text. If opt_isHtml, makes sure to
|
218
769
|
* ignore the LTR nature of the mark-up and escapes in text, making the logic
|
@@ -241,12 +792,26 @@ soy.$$bidiTextDir = function(text, opt_isHtml) {
|
|
241
792
|
* @param {string} text The text whose directionality is to be estimated.
|
242
793
|
* @param {boolean=} opt_isHtml Whether text is HTML/HTML-escaped.
|
243
794
|
* Default: false.
|
244
|
-
* @return {
|
245
|
-
* text in non-LTR context;
|
795
|
+
* @return {soydata.SanitizedHtmlAttribute} "dir=rtl" for RTL text in non-RTL
|
796
|
+
* context; "dir=ltr" for LTR text in non-LTR context;
|
797
|
+
* else, the empty string.
|
246
798
|
*/
|
247
799
|
soy.$$bidiDirAttr = function(bidiGlobalDir, text, opt_isHtml) {
|
248
|
-
|
249
|
-
|
800
|
+
return new soydata.SanitizedHtmlAttribute(
|
801
|
+
soy.$$getBidiFormatterInstance_(bidiGlobalDir).dirAttr(text, opt_isHtml));
|
802
|
+
};
|
803
|
+
|
804
|
+
|
805
|
+
/**
|
806
|
+
* Returns a Unicode BiDi mark matching bidiGlobalDir (LRM or RLM), or an empty
|
807
|
+
* string if bidiGlobalDir is 0 (unknown).
|
808
|
+
* @param {number} bidiGlobalDir The global directionality context: 1 if ltr, -1
|
809
|
+
* if rtl, 0 if unknown.
|
810
|
+
* @return {string} A Unicode bidi mark matching bidiGlobalDir, or the empty
|
811
|
+
* string when bidiGlobalDir is 0 (unknown).
|
812
|
+
*/
|
813
|
+
soy.$$bidiMark = function(bidiGlobalDir) {
|
814
|
+
return soy.$$getBidiFormatterInstance_(bidiGlobalDir).mark();
|
250
815
|
};
|
251
816
|
|
252
817
|
|
@@ -261,12 +826,12 @@ soy.$$bidiDirAttr = function(bidiGlobalDir, text, opt_isHtml) {
|
|
261
826
|
* @param {string} text The text whose directionality is to be estimated.
|
262
827
|
* @param {boolean=} opt_isHtml Whether text is HTML/HTML-escaped.
|
263
828
|
* Default: false.
|
264
|
-
* @return {string} A Unicode bidi mark matching bidiGlobalDir, or
|
265
|
-
*
|
266
|
-
* bidiGlobalDir.
|
829
|
+
* @return {string} A Unicode bidi mark matching bidiGlobalDir, or the empty
|
830
|
+
* string when text's overall and exit directionalities both match
|
831
|
+
* bidiGlobalDir, or bidiGlobalDir is 0 (unknown).
|
267
832
|
*/
|
268
833
|
soy.$$bidiMarkAfter = function(bidiGlobalDir, text, opt_isHtml) {
|
269
|
-
var formatter = soy.$$
|
834
|
+
var formatter = soy.$$getBidiFormatterInstance_(bidiGlobalDir);
|
270
835
|
return formatter.markAfter(text, opt_isHtml);
|
271
836
|
};
|
272
837
|
|
@@ -284,7 +849,7 @@ soy.$$bidiMarkAfter = function(bidiGlobalDir, text, opt_isHtml) {
|
|
284
849
|
* @return {string} The wrapped string.
|
285
850
|
*/
|
286
851
|
soy.$$bidiSpanWrap = function(bidiGlobalDir, str) {
|
287
|
-
var formatter = soy.$$
|
852
|
+
var formatter = soy.$$getBidiFormatterInstance_(bidiGlobalDir);
|
288
853
|
return formatter.spanWrap(str + '', true);
|
289
854
|
};
|
290
855
|
|
@@ -303,6 +868,488 @@ soy.$$bidiSpanWrap = function(bidiGlobalDir, str) {
|
|
303
868
|
* @return {string} The wrapped string.
|
304
869
|
*/
|
305
870
|
soy.$$bidiUnicodeWrap = function(bidiGlobalDir, str) {
|
306
|
-
var formatter = soy.$$
|
871
|
+
var formatter = soy.$$getBidiFormatterInstance_(bidiGlobalDir);
|
307
872
|
return formatter.unicodeWrap(str + '', true);
|
308
873
|
};
|
874
|
+
|
875
|
+
|
876
|
+
// -----------------------------------------------------------------------------
|
877
|
+
// Generated code.
|
878
|
+
|
879
|
+
|
880
|
+
|
881
|
+
|
882
|
+
// START GENERATED CODE FOR ESCAPERS.
|
883
|
+
|
884
|
+
/**
|
885
|
+
* @type {function (*) : string}
|
886
|
+
*/
|
887
|
+
soy.esc.$$escapeUriHelper = function(v) {
|
888
|
+
return goog.string.urlEncode(String(v));
|
889
|
+
};
|
890
|
+
|
891
|
+
/**
|
892
|
+
* Maps charcters to the escaped versions for the named escape directives.
|
893
|
+
* @type {Object.<string, string>}
|
894
|
+
* @private
|
895
|
+
*/
|
896
|
+
soy.esc.$$ESCAPE_MAP_FOR_ESCAPE_HTML__AND__NORMALIZE_HTML__AND__ESCAPE_HTML_NOSPACE__AND__NORMALIZE_HTML_NOSPACE_ = {
|
897
|
+
'\x00': '\x26#0;',
|
898
|
+
'\x22': '\x26quot;',
|
899
|
+
'\x26': '\x26amp;',
|
900
|
+
'\x27': '\x26#39;',
|
901
|
+
'\x3c': '\x26lt;',
|
902
|
+
'\x3e': '\x26gt;',
|
903
|
+
'\x09': '\x26#9;',
|
904
|
+
'\x0a': '\x26#10;',
|
905
|
+
'\x0b': '\x26#11;',
|
906
|
+
'\x0c': '\x26#12;',
|
907
|
+
'\x0d': '\x26#13;',
|
908
|
+
' ': '\x26#32;',
|
909
|
+
'-': '\x26#45;',
|
910
|
+
'\/': '\x26#47;',
|
911
|
+
'\x3d': '\x26#61;',
|
912
|
+
'`': '\x26#96;',
|
913
|
+
'\x85': '\x26#133;',
|
914
|
+
'\xa0': '\x26#160;',
|
915
|
+
'\u2028': '\x26#8232;',
|
916
|
+
'\u2029': '\x26#8233;'
|
917
|
+
};
|
918
|
+
|
919
|
+
/**
|
920
|
+
* A function that can be used with String.replace..
|
921
|
+
* @param {string} ch A single character matched by a compatible matcher.
|
922
|
+
* @return {string} A token in the output language.
|
923
|
+
* @private
|
924
|
+
*/
|
925
|
+
soy.esc.$$REPLACER_FOR_ESCAPE_HTML__AND__NORMALIZE_HTML__AND__ESCAPE_HTML_NOSPACE__AND__NORMALIZE_HTML_NOSPACE_ = function(ch) {
|
926
|
+
return soy.esc.$$ESCAPE_MAP_FOR_ESCAPE_HTML__AND__NORMALIZE_HTML__AND__ESCAPE_HTML_NOSPACE__AND__NORMALIZE_HTML_NOSPACE_[ch];
|
927
|
+
};
|
928
|
+
|
929
|
+
/**
|
930
|
+
* Maps charcters to the escaped versions for the named escape directives.
|
931
|
+
* @type {Object.<string, string>}
|
932
|
+
* @private
|
933
|
+
*/
|
934
|
+
soy.esc.$$ESCAPE_MAP_FOR_ESCAPE_JS_STRING__AND__ESCAPE_JS_REGEX_ = {
|
935
|
+
'\x00': '\\x00',
|
936
|
+
'\x08': '\\x08',
|
937
|
+
'\x09': '\\t',
|
938
|
+
'\x0a': '\\n',
|
939
|
+
'\x0b': '\\x0b',
|
940
|
+
'\x0c': '\\f',
|
941
|
+
'\x0d': '\\r',
|
942
|
+
'\x22': '\\x22',
|
943
|
+
'\x26': '\\x26',
|
944
|
+
'\x27': '\\x27',
|
945
|
+
'\/': '\\\/',
|
946
|
+
'\x3c': '\\x3c',
|
947
|
+
'\x3d': '\\x3d',
|
948
|
+
'\x3e': '\\x3e',
|
949
|
+
'\\': '\\\\',
|
950
|
+
'\x85': '\\x85',
|
951
|
+
'\u2028': '\\u2028',
|
952
|
+
'\u2029': '\\u2029',
|
953
|
+
'$': '\\x24',
|
954
|
+
'(': '\\x28',
|
955
|
+
')': '\\x29',
|
956
|
+
'*': '\\x2a',
|
957
|
+
'+': '\\x2b',
|
958
|
+
',': '\\x2c',
|
959
|
+
'-': '\\x2d',
|
960
|
+
'.': '\\x2e',
|
961
|
+
':': '\\x3a',
|
962
|
+
'?': '\\x3f',
|
963
|
+
'[': '\\x5b',
|
964
|
+
']': '\\x5d',
|
965
|
+
'^': '\\x5e',
|
966
|
+
'{': '\\x7b',
|
967
|
+
'|': '\\x7c',
|
968
|
+
'}': '\\x7d'
|
969
|
+
};
|
970
|
+
|
971
|
+
/**
|
972
|
+
* A function that can be used with String.replace..
|
973
|
+
* @param {string} ch A single character matched by a compatible matcher.
|
974
|
+
* @return {string} A token in the output language.
|
975
|
+
* @private
|
976
|
+
*/
|
977
|
+
soy.esc.$$REPLACER_FOR_ESCAPE_JS_STRING__AND__ESCAPE_JS_REGEX_ = function(ch) {
|
978
|
+
return soy.esc.$$ESCAPE_MAP_FOR_ESCAPE_JS_STRING__AND__ESCAPE_JS_REGEX_[ch];
|
979
|
+
};
|
980
|
+
|
981
|
+
/**
|
982
|
+
* Maps charcters to the escaped versions for the named escape directives.
|
983
|
+
* @type {Object.<string, string>}
|
984
|
+
* @private
|
985
|
+
*/
|
986
|
+
soy.esc.$$ESCAPE_MAP_FOR_ESCAPE_CSS_STRING_ = {
|
987
|
+
'\x00': '\\0 ',
|
988
|
+
'\x08': '\\8 ',
|
989
|
+
'\x09': '\\9 ',
|
990
|
+
'\x0a': '\\a ',
|
991
|
+
'\x0b': '\\b ',
|
992
|
+
'\x0c': '\\c ',
|
993
|
+
'\x0d': '\\d ',
|
994
|
+
'\x22': '\\22 ',
|
995
|
+
'\x26': '\\26 ',
|
996
|
+
'\x27': '\\27 ',
|
997
|
+
'(': '\\28 ',
|
998
|
+
')': '\\29 ',
|
999
|
+
'*': '\\2a ',
|
1000
|
+
'\/': '\\2f ',
|
1001
|
+
':': '\\3a ',
|
1002
|
+
';': '\\3b ',
|
1003
|
+
'\x3c': '\\3c ',
|
1004
|
+
'\x3d': '\\3d ',
|
1005
|
+
'\x3e': '\\3e ',
|
1006
|
+
'@': '\\40 ',
|
1007
|
+
'\\': '\\5c ',
|
1008
|
+
'{': '\\7b ',
|
1009
|
+
'}': '\\7d ',
|
1010
|
+
'\x85': '\\85 ',
|
1011
|
+
'\xa0': '\\a0 ',
|
1012
|
+
'\u2028': '\\2028 ',
|
1013
|
+
'\u2029': '\\2029 '
|
1014
|
+
};
|
1015
|
+
|
1016
|
+
/**
|
1017
|
+
* A function that can be used with String.replace..
|
1018
|
+
* @param {string} ch A single character matched by a compatible matcher.
|
1019
|
+
* @return {string} A token in the output language.
|
1020
|
+
* @private
|
1021
|
+
*/
|
1022
|
+
soy.esc.$$REPLACER_FOR_ESCAPE_CSS_STRING_ = function(ch) {
|
1023
|
+
return soy.esc.$$ESCAPE_MAP_FOR_ESCAPE_CSS_STRING_[ch];
|
1024
|
+
};
|
1025
|
+
|
1026
|
+
/**
|
1027
|
+
* Maps charcters to the escaped versions for the named escape directives.
|
1028
|
+
* @type {Object.<string, string>}
|
1029
|
+
* @private
|
1030
|
+
*/
|
1031
|
+
soy.esc.$$ESCAPE_MAP_FOR_NORMALIZE_URI__AND__FILTER_NORMALIZE_URI_ = {
|
1032
|
+
'\x00': '%00',
|
1033
|
+
'\x01': '%01',
|
1034
|
+
'\x02': '%02',
|
1035
|
+
'\x03': '%03',
|
1036
|
+
'\x04': '%04',
|
1037
|
+
'\x05': '%05',
|
1038
|
+
'\x06': '%06',
|
1039
|
+
'\x07': '%07',
|
1040
|
+
'\x08': '%08',
|
1041
|
+
'\x09': '%09',
|
1042
|
+
'\x0a': '%0A',
|
1043
|
+
'\x0b': '%0B',
|
1044
|
+
'\x0c': '%0C',
|
1045
|
+
'\x0d': '%0D',
|
1046
|
+
'\x0e': '%0E',
|
1047
|
+
'\x0f': '%0F',
|
1048
|
+
'\x10': '%10',
|
1049
|
+
'\x11': '%11',
|
1050
|
+
'\x12': '%12',
|
1051
|
+
'\x13': '%13',
|
1052
|
+
'\x14': '%14',
|
1053
|
+
'\x15': '%15',
|
1054
|
+
'\x16': '%16',
|
1055
|
+
'\x17': '%17',
|
1056
|
+
'\x18': '%18',
|
1057
|
+
'\x19': '%19',
|
1058
|
+
'\x1a': '%1A',
|
1059
|
+
'\x1b': '%1B',
|
1060
|
+
'\x1c': '%1C',
|
1061
|
+
'\x1d': '%1D',
|
1062
|
+
'\x1e': '%1E',
|
1063
|
+
'\x1f': '%1F',
|
1064
|
+
' ': '%20',
|
1065
|
+
'\x22': '%22',
|
1066
|
+
'\x27': '%27',
|
1067
|
+
'(': '%28',
|
1068
|
+
')': '%29',
|
1069
|
+
'\x3c': '%3C',
|
1070
|
+
'\x3e': '%3E',
|
1071
|
+
'\\': '%5C',
|
1072
|
+
'{': '%7B',
|
1073
|
+
'}': '%7D',
|
1074
|
+
'\x7f': '%7F',
|
1075
|
+
'\x85': '%C2%85',
|
1076
|
+
'\xa0': '%C2%A0',
|
1077
|
+
'\u2028': '%E2%80%A8',
|
1078
|
+
'\u2029': '%E2%80%A9',
|
1079
|
+
'\uff01': '%EF%BC%81',
|
1080
|
+
'\uff03': '%EF%BC%83',
|
1081
|
+
'\uff04': '%EF%BC%84',
|
1082
|
+
'\uff06': '%EF%BC%86',
|
1083
|
+
'\uff07': '%EF%BC%87',
|
1084
|
+
'\uff08': '%EF%BC%88',
|
1085
|
+
'\uff09': '%EF%BC%89',
|
1086
|
+
'\uff0a': '%EF%BC%8A',
|
1087
|
+
'\uff0b': '%EF%BC%8B',
|
1088
|
+
'\uff0c': '%EF%BC%8C',
|
1089
|
+
'\uff0f': '%EF%BC%8F',
|
1090
|
+
'\uff1a': '%EF%BC%9A',
|
1091
|
+
'\uff1b': '%EF%BC%9B',
|
1092
|
+
'\uff1d': '%EF%BC%9D',
|
1093
|
+
'\uff1f': '%EF%BC%9F',
|
1094
|
+
'\uff20': '%EF%BC%A0',
|
1095
|
+
'\uff3b': '%EF%BC%BB',
|
1096
|
+
'\uff3d': '%EF%BC%BD'
|
1097
|
+
};
|
1098
|
+
|
1099
|
+
/**
|
1100
|
+
* A function that can be used with String.replace..
|
1101
|
+
* @param {string} ch A single character matched by a compatible matcher.
|
1102
|
+
* @return {string} A token in the output language.
|
1103
|
+
* @private
|
1104
|
+
*/
|
1105
|
+
soy.esc.$$REPLACER_FOR_NORMALIZE_URI__AND__FILTER_NORMALIZE_URI_ = function(ch) {
|
1106
|
+
return soy.esc.$$ESCAPE_MAP_FOR_NORMALIZE_URI__AND__FILTER_NORMALIZE_URI_[ch];
|
1107
|
+
};
|
1108
|
+
|
1109
|
+
/**
|
1110
|
+
* Matches characters that need to be escaped for the named directives.
|
1111
|
+
* @type RegExp
|
1112
|
+
* @private
|
1113
|
+
*/
|
1114
|
+
soy.esc.$$MATCHER_FOR_ESCAPE_HTML_ = /[\x00\x22\x26\x27\x3c\x3e]/g;
|
1115
|
+
|
1116
|
+
/**
|
1117
|
+
* Matches characters that need to be escaped for the named directives.
|
1118
|
+
* @type RegExp
|
1119
|
+
* @private
|
1120
|
+
*/
|
1121
|
+
soy.esc.$$MATCHER_FOR_NORMALIZE_HTML_ = /[\x00\x22\x27\x3c\x3e]/g;
|
1122
|
+
|
1123
|
+
/**
|
1124
|
+
* Matches characters that need to be escaped for the named directives.
|
1125
|
+
* @type RegExp
|
1126
|
+
* @private
|
1127
|
+
*/
|
1128
|
+
soy.esc.$$MATCHER_FOR_ESCAPE_HTML_NOSPACE_ = /[\x00\x09-\x0d \x22\x26\x27\x2d\/\x3c-\x3e`\x85\xa0\u2028\u2029]/g;
|
1129
|
+
|
1130
|
+
/**
|
1131
|
+
* Matches characters that need to be escaped for the named directives.
|
1132
|
+
* @type RegExp
|
1133
|
+
* @private
|
1134
|
+
*/
|
1135
|
+
soy.esc.$$MATCHER_FOR_NORMALIZE_HTML_NOSPACE_ = /[\x00\x09-\x0d \x22\x27\x2d\/\x3c-\x3e`\x85\xa0\u2028\u2029]/g;
|
1136
|
+
|
1137
|
+
/**
|
1138
|
+
* Matches characters that need to be escaped for the named directives.
|
1139
|
+
* @type RegExp
|
1140
|
+
* @private
|
1141
|
+
*/
|
1142
|
+
soy.esc.$$MATCHER_FOR_ESCAPE_JS_STRING_ = /[\x00\x08-\x0d\x22\x26\x27\/\x3c-\x3e\\\x85\u2028\u2029]/g;
|
1143
|
+
|
1144
|
+
/**
|
1145
|
+
* Matches characters that need to be escaped for the named directives.
|
1146
|
+
* @type RegExp
|
1147
|
+
* @private
|
1148
|
+
*/
|
1149
|
+
soy.esc.$$MATCHER_FOR_ESCAPE_JS_REGEX_ = /[\x00\x08-\x0d\x22\x24\x26-\/\x3a\x3c-\x3f\x5b-\x5e\x7b-\x7d\x85\u2028\u2029]/g;
|
1150
|
+
|
1151
|
+
/**
|
1152
|
+
* Matches characters that need to be escaped for the named directives.
|
1153
|
+
* @type RegExp
|
1154
|
+
* @private
|
1155
|
+
*/
|
1156
|
+
soy.esc.$$MATCHER_FOR_ESCAPE_CSS_STRING_ = /[\x00\x08-\x0d\x22\x26-\x2a\/\x3a-\x3e@\\\x7b\x7d\x85\xa0\u2028\u2029]/g;
|
1157
|
+
|
1158
|
+
/**
|
1159
|
+
* Matches characters that need to be escaped for the named directives.
|
1160
|
+
* @type RegExp
|
1161
|
+
* @private
|
1162
|
+
*/
|
1163
|
+
soy.esc.$$MATCHER_FOR_NORMALIZE_URI__AND__FILTER_NORMALIZE_URI_ = /[\x00- \x22\x27-\x29\x3c\x3e\\\x7b\x7d\x7f\x85\xa0\u2028\u2029\uff01\uff03\uff04\uff06-\uff0c\uff0f\uff1a\uff1b\uff1d\uff1f\uff20\uff3b\uff3d]/g;
|
1164
|
+
|
1165
|
+
/**
|
1166
|
+
* A pattern that vets values produced by the named directives.
|
1167
|
+
* @type RegExp
|
1168
|
+
* @private
|
1169
|
+
*/
|
1170
|
+
soy.esc.$$FILTER_FOR_FILTER_CSS_VALUE_ = /^(?!-*(?:expression|(?:moz-)?binding))(?:[.#]?-?(?:[_a-z0-9-]+)(?:-[_a-z0-9-]+)*-?|-?(?:[0-9]+(?:\.[0-9]*)?|\.[0-9]+)(?:[a-z]{1,2}|%)?|!important|)$/i;
|
1171
|
+
|
1172
|
+
/**
|
1173
|
+
* A pattern that vets values produced by the named directives.
|
1174
|
+
* @type RegExp
|
1175
|
+
* @private
|
1176
|
+
*/
|
1177
|
+
soy.esc.$$FILTER_FOR_FILTER_NORMALIZE_URI_ = /^(?:(?:https?|mailto):|[^&:\/?#]*(?:[\/?#]|$))/i;
|
1178
|
+
|
1179
|
+
/**
|
1180
|
+
* A pattern that vets values produced by the named directives.
|
1181
|
+
* @type RegExp
|
1182
|
+
* @private
|
1183
|
+
*/
|
1184
|
+
soy.esc.$$FILTER_FOR_FILTER_HTML_ATTRIBUTE_ = /^(?!style|on|action|archive|background|cite|classid|codebase|data|dsync|href|longdesc|src|usemap)(?:[a-z0-9_$:-]*)$/i;
|
1185
|
+
|
1186
|
+
/**
|
1187
|
+
* A pattern that vets values produced by the named directives.
|
1188
|
+
* @type RegExp
|
1189
|
+
* @private
|
1190
|
+
*/
|
1191
|
+
soy.esc.$$FILTER_FOR_FILTER_HTML_ELEMENT_NAME_ = /^(?!script|style|title|textarea|xmp|no)[a-z0-9_$:-]*$/i;
|
1192
|
+
|
1193
|
+
/**
|
1194
|
+
* A helper for the Soy directive |escapeHtml
|
1195
|
+
* @param {*} value Can be of any type but will be coerced to a string.
|
1196
|
+
* @return {string} The escaped text.
|
1197
|
+
*/
|
1198
|
+
soy.esc.$$escapeHtmlHelper = function(value) {
|
1199
|
+
var str = String(value);
|
1200
|
+
return str.replace(
|
1201
|
+
soy.esc.$$MATCHER_FOR_ESCAPE_HTML_,
|
1202
|
+
soy.esc.$$REPLACER_FOR_ESCAPE_HTML__AND__NORMALIZE_HTML__AND__ESCAPE_HTML_NOSPACE__AND__NORMALIZE_HTML_NOSPACE_);
|
1203
|
+
};
|
1204
|
+
|
1205
|
+
/**
|
1206
|
+
* A helper for the Soy directive |normalizeHtml
|
1207
|
+
* @param {*} value Can be of any type but will be coerced to a string.
|
1208
|
+
* @return {string} The escaped text.
|
1209
|
+
*/
|
1210
|
+
soy.esc.$$normalizeHtmlHelper = function(value) {
|
1211
|
+
var str = String(value);
|
1212
|
+
return str.replace(
|
1213
|
+
soy.esc.$$MATCHER_FOR_NORMALIZE_HTML_,
|
1214
|
+
soy.esc.$$REPLACER_FOR_ESCAPE_HTML__AND__NORMALIZE_HTML__AND__ESCAPE_HTML_NOSPACE__AND__NORMALIZE_HTML_NOSPACE_);
|
1215
|
+
};
|
1216
|
+
|
1217
|
+
/**
|
1218
|
+
* A helper for the Soy directive |escapeHtmlNospace
|
1219
|
+
* @param {*} value Can be of any type but will be coerced to a string.
|
1220
|
+
* @return {string} The escaped text.
|
1221
|
+
*/
|
1222
|
+
soy.esc.$$escapeHtmlNospaceHelper = function(value) {
|
1223
|
+
var str = String(value);
|
1224
|
+
return str.replace(
|
1225
|
+
soy.esc.$$MATCHER_FOR_ESCAPE_HTML_NOSPACE_,
|
1226
|
+
soy.esc.$$REPLACER_FOR_ESCAPE_HTML__AND__NORMALIZE_HTML__AND__ESCAPE_HTML_NOSPACE__AND__NORMALIZE_HTML_NOSPACE_);
|
1227
|
+
};
|
1228
|
+
|
1229
|
+
/**
|
1230
|
+
* A helper for the Soy directive |normalizeHtmlNospace
|
1231
|
+
* @param {*} value Can be of any type but will be coerced to a string.
|
1232
|
+
* @return {string} The escaped text.
|
1233
|
+
*/
|
1234
|
+
soy.esc.$$normalizeHtmlNospaceHelper = function(value) {
|
1235
|
+
var str = String(value);
|
1236
|
+
return str.replace(
|
1237
|
+
soy.esc.$$MATCHER_FOR_NORMALIZE_HTML_NOSPACE_,
|
1238
|
+
soy.esc.$$REPLACER_FOR_ESCAPE_HTML__AND__NORMALIZE_HTML__AND__ESCAPE_HTML_NOSPACE__AND__NORMALIZE_HTML_NOSPACE_);
|
1239
|
+
};
|
1240
|
+
|
1241
|
+
/**
|
1242
|
+
* A helper for the Soy directive |escapeJsString
|
1243
|
+
* @param {*} value Can be of any type but will be coerced to a string.
|
1244
|
+
* @return {string} The escaped text.
|
1245
|
+
*/
|
1246
|
+
soy.esc.$$escapeJsStringHelper = function(value) {
|
1247
|
+
var str = String(value);
|
1248
|
+
return str.replace(
|
1249
|
+
soy.esc.$$MATCHER_FOR_ESCAPE_JS_STRING_,
|
1250
|
+
soy.esc.$$REPLACER_FOR_ESCAPE_JS_STRING__AND__ESCAPE_JS_REGEX_);
|
1251
|
+
};
|
1252
|
+
|
1253
|
+
/**
|
1254
|
+
* A helper for the Soy directive |escapeJsRegex
|
1255
|
+
* @param {*} value Can be of any type but will be coerced to a string.
|
1256
|
+
* @return {string} The escaped text.
|
1257
|
+
*/
|
1258
|
+
soy.esc.$$escapeJsRegexHelper = function(value) {
|
1259
|
+
var str = String(value);
|
1260
|
+
return str.replace(
|
1261
|
+
soy.esc.$$MATCHER_FOR_ESCAPE_JS_REGEX_,
|
1262
|
+
soy.esc.$$REPLACER_FOR_ESCAPE_JS_STRING__AND__ESCAPE_JS_REGEX_);
|
1263
|
+
};
|
1264
|
+
|
1265
|
+
/**
|
1266
|
+
* A helper for the Soy directive |escapeCssString
|
1267
|
+
* @param {*} value Can be of any type but will be coerced to a string.
|
1268
|
+
* @return {string} The escaped text.
|
1269
|
+
*/
|
1270
|
+
soy.esc.$$escapeCssStringHelper = function(value) {
|
1271
|
+
var str = String(value);
|
1272
|
+
return str.replace(
|
1273
|
+
soy.esc.$$MATCHER_FOR_ESCAPE_CSS_STRING_,
|
1274
|
+
soy.esc.$$REPLACER_FOR_ESCAPE_CSS_STRING_);
|
1275
|
+
};
|
1276
|
+
|
1277
|
+
/**
|
1278
|
+
* A helper for the Soy directive |filterCssValue
|
1279
|
+
* @param {*} value Can be of any type but will be coerced to a string.
|
1280
|
+
* @return {string} The escaped text.
|
1281
|
+
*/
|
1282
|
+
soy.esc.$$filterCssValueHelper = function(value) {
|
1283
|
+
var str = String(value);
|
1284
|
+
if (!soy.esc.$$FILTER_FOR_FILTER_CSS_VALUE_.test(str)) {
|
1285
|
+
goog.asserts.fail('Bad value `%s` for |filterCssValue', [str]);
|
1286
|
+
return 'zSoyz';
|
1287
|
+
}
|
1288
|
+
return str;
|
1289
|
+
};
|
1290
|
+
|
1291
|
+
/**
|
1292
|
+
* A helper for the Soy directive |normalizeUri
|
1293
|
+
* @param {*} value Can be of any type but will be coerced to a string.
|
1294
|
+
* @return {string} The escaped text.
|
1295
|
+
*/
|
1296
|
+
soy.esc.$$normalizeUriHelper = function(value) {
|
1297
|
+
var str = String(value);
|
1298
|
+
return str.replace(
|
1299
|
+
soy.esc.$$MATCHER_FOR_NORMALIZE_URI__AND__FILTER_NORMALIZE_URI_,
|
1300
|
+
soy.esc.$$REPLACER_FOR_NORMALIZE_URI__AND__FILTER_NORMALIZE_URI_);
|
1301
|
+
};
|
1302
|
+
|
1303
|
+
/**
|
1304
|
+
* A helper for the Soy directive |filterNormalizeUri
|
1305
|
+
* @param {*} value Can be of any type but will be coerced to a string.
|
1306
|
+
* @return {string} The escaped text.
|
1307
|
+
*/
|
1308
|
+
soy.esc.$$filterNormalizeUriHelper = function(value) {
|
1309
|
+
var str = String(value);
|
1310
|
+
if (!soy.esc.$$FILTER_FOR_FILTER_NORMALIZE_URI_.test(str)) {
|
1311
|
+
goog.asserts.fail('Bad value `%s` for |filterNormalizeUri', [str]);
|
1312
|
+
return 'zSoyz';
|
1313
|
+
}
|
1314
|
+
return str.replace(
|
1315
|
+
soy.esc.$$MATCHER_FOR_NORMALIZE_URI__AND__FILTER_NORMALIZE_URI_,
|
1316
|
+
soy.esc.$$REPLACER_FOR_NORMALIZE_URI__AND__FILTER_NORMALIZE_URI_);
|
1317
|
+
};
|
1318
|
+
|
1319
|
+
/**
|
1320
|
+
* A helper for the Soy directive |filterHtmlAttribute
|
1321
|
+
* @param {*} value Can be of any type but will be coerced to a string.
|
1322
|
+
* @return {string} The escaped text.
|
1323
|
+
*/
|
1324
|
+
soy.esc.$$filterHtmlAttributeHelper = function(value) {
|
1325
|
+
var str = String(value);
|
1326
|
+
if (!soy.esc.$$FILTER_FOR_FILTER_HTML_ATTRIBUTE_.test(str)) {
|
1327
|
+
goog.asserts.fail('Bad value `%s` for |filterHtmlAttribute', [str]);
|
1328
|
+
return 'zSoyz';
|
1329
|
+
}
|
1330
|
+
return str;
|
1331
|
+
};
|
1332
|
+
|
1333
|
+
/**
|
1334
|
+
* A helper for the Soy directive |filterHtmlElementName
|
1335
|
+
* @param {*} value Can be of any type but will be coerced to a string.
|
1336
|
+
* @return {string} The escaped text.
|
1337
|
+
*/
|
1338
|
+
soy.esc.$$filterHtmlElementNameHelper = function(value) {
|
1339
|
+
var str = String(value);
|
1340
|
+
if (!soy.esc.$$FILTER_FOR_FILTER_HTML_ELEMENT_NAME_.test(str)) {
|
1341
|
+
goog.asserts.fail('Bad value `%s` for |filterHtmlElementName', [str]);
|
1342
|
+
return 'zSoyz';
|
1343
|
+
}
|
1344
|
+
return str;
|
1345
|
+
};
|
1346
|
+
|
1347
|
+
/**
|
1348
|
+
* Matches all tags, HTML comments, and DOCTYPEs in tag soup HTML.
|
1349
|
+
*
|
1350
|
+
* @type {RegExp}
|
1351
|
+
* @private
|
1352
|
+
*/
|
1353
|
+
soy.esc.$$HTML_TAG_REGEX_ = /<(?:!|\/?[a-zA-Z])(?:[^>'"]|"[^"]*"|'[^']*')*>/g;
|
1354
|
+
|
1355
|
+
// END GENERATED CODE
|