为了做到这一点,需要做两件事:
- 类的
escape
方法Template
必须知道转义 HTML 实体
escapeHTML
Prototype.js 添加到String
对象的方法必须扩展为将引号编码为"
实体。(可能还有更多。现在太简单了......)
这两者都可以通过以下代码实现:
String.prototype.escapeHTML = String.prototype.escapeHTML.wrap(function(proceed){
return proceed().replace(/"/g,'"');
});
Template.addMethods({
evaluateEscapeHTML: function(object) {
if (object && Object.isFunction(object.toTemplateReplacements))
object = object.toTemplateReplacements();
return this.template.gsub(this.pattern, function(match) {
if (object == null) return (match[1] + '');
var before = match[1] || '';
if (before == '\\') return match[2];
var ctx = object, expr = match[3],
pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
match = pattern.exec(expr);
if (match == null) return before;
while (match != null) {
var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1];
ctx = ctx[comp];
if (null == ctx || '' == match[3]) break;
expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
match = pattern.exec(expr);
}
return before + String.interpret(ctx).escapeHTML();
});
}
});
这段代码将扩展 Prototype.jsevaluateEscapeHTML
并向 Templates 添加一个新方法,所以这段代码应该运行一次,从那时起,任何一个Template
都会有一个新evaluateEscapeHTML
方法:
var template = new Template(
'<div><label>Name: <input name=\"name\" value=\"#{name}\"></label></div>'+
'<div><label>URL: <input name=\"url\" value=\"#{url}\"></label></div>'+
'<div><label>Personal Statement: <input name=\"statement\" value=\"#{statement}\"></label></div>'
);
$('test').update(template.evaluate(data));
JSFiddle 来测试这个
请注意,我必须从prototype.js 1.7 版的类中复制整个方法。这有一个主要缺点,如果该方法的未来版本得到改进,我的代码也需要改进。但是,我找不到更好的方法来做到这一点。 evaluate
Template
evaluate
对我所做的方法的具体修改evaluate
是更改此行:
return before + String.interpret(ctx);
至:
return before + String.interpret(ctx).escapeHTML();
就是这样,这就是为什么我无法以某种方式extend
或wrap
其余代码如此遗憾的原因......