73 lines
3.5 KiB
JavaScript
73 lines
3.5 KiB
JavaScript
// If you want to make a custom template engine,
|
|
//
|
|
// [1] Inherit from this class (like ko.nativeTemplateEngine does)
|
|
// [2] Override 'renderTemplateSource', supplying a function with this signature:
|
|
//
|
|
// function (templateSource, bindingContext, options) {
|
|
// // - templateSource.text() is the text of the template you should render
|
|
// // - bindingContext.$data is the data you should pass into the template
|
|
// // - you might also want to make bindingContext.$parent, bindingContext.$parents,
|
|
// // and bindingContext.$root available in the template too
|
|
// // - options gives you access to any other properties set on "data-bind: { template: options }"
|
|
// // - templateDocument is the document object of the template
|
|
// //
|
|
// // Return value: an array of DOM nodes
|
|
// }
|
|
//
|
|
// [3] Override 'createJavaScriptEvaluatorBlock', supplying a function with this signature:
|
|
//
|
|
// function (script) {
|
|
// // Return value: Whatever syntax means "Evaluate the JavaScript statement 'script' and output the result"
|
|
// // For example, the jquery.tmpl template engine converts 'someScript' to '${ someScript }'
|
|
// }
|
|
//
|
|
// This is only necessary if you want to allow data-bind attributes to reference arbitrary template variables.
|
|
// If you don't want to allow that, you can set the property 'allowTemplateRewriting' to false (like ko.nativeTemplateEngine does)
|
|
// and then you don't need to override 'createJavaScriptEvaluatorBlock'.
|
|
|
|
ko.templateEngine = function () { };
|
|
|
|
ko.templateEngine.prototype['renderTemplateSource'] = function (templateSource, bindingContext, options, templateDocument) {
|
|
throw new Error("Override renderTemplateSource");
|
|
};
|
|
|
|
ko.templateEngine.prototype['createJavaScriptEvaluatorBlock'] = function (script) {
|
|
throw new Error("Override createJavaScriptEvaluatorBlock");
|
|
};
|
|
|
|
ko.templateEngine.prototype['makeTemplateSource'] = function(template, templateDocument) {
|
|
// Named template
|
|
if (typeof template == "string") {
|
|
templateDocument = templateDocument || document;
|
|
var elem = templateDocument.getElementById(template);
|
|
if (!elem)
|
|
throw new Error("Cannot find template with ID " + template);
|
|
return new ko.templateSources.domElement(elem);
|
|
} else if ((template.nodeType == 1) || (template.nodeType == 8)) {
|
|
// Anonymous template
|
|
return new ko.templateSources.anonymousTemplate(template);
|
|
} else
|
|
throw new Error("Unknown template type: " + template);
|
|
};
|
|
|
|
ko.templateEngine.prototype['renderTemplate'] = function (template, bindingContext, options, templateDocument) {
|
|
var templateSource = this['makeTemplateSource'](template, templateDocument);
|
|
return this['renderTemplateSource'](templateSource, bindingContext, options, templateDocument);
|
|
};
|
|
|
|
ko.templateEngine.prototype['isTemplateRewritten'] = function (template, templateDocument) {
|
|
// Skip rewriting if requested
|
|
if (this['allowTemplateRewriting'] === false)
|
|
return true;
|
|
return this['makeTemplateSource'](template, templateDocument)['data']("isRewritten");
|
|
};
|
|
|
|
ko.templateEngine.prototype['rewriteTemplate'] = function (template, rewriterCallback, templateDocument) {
|
|
var templateSource = this['makeTemplateSource'](template, templateDocument);
|
|
var rewritten = rewriterCallback(templateSource['text']());
|
|
templateSource['text'](rewritten);
|
|
templateSource['data']("isRewritten", true);
|
|
};
|
|
|
|
ko.exportSymbol('templateEngine', ko.templateEngine);
|