Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add functionnalities to switch between templateEngine and set custom binding attribute name #2202

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
12 changes: 9 additions & 3 deletions src/binding/bindingProvider.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
(function() {
var defaultBindingAttributeName = "data-bind";

ko.bindingProvider = function() {
ko.bindingProvider = function(bindingAttributeName) {
this.bindingCache = {};
this.bindingAttributeName = bindingAttributeName || defaultBindingAttributeName;
};

ko.utils.extend(ko.bindingProvider.prototype, {
'nodeHasBindings': function(node) {
switch (node.nodeType) {
case 1: // Element
return node.getAttribute(defaultBindingAttributeName) != null
return node.getAttribute(this.bindingAttributeName) != null
|| ko.components['getComponentNameForNode'](node);
case 8: // Comment node
return ko.virtualElements.hasBindingValue(node);
Expand All @@ -33,7 +34,7 @@
// It's not part of the interface definition for a general binding provider.
'getBindingsString': function(node, bindingContext) {
switch (node.nodeType) {
case 1: return node.getAttribute(defaultBindingAttributeName); // Element
case 1: return node.getAttribute(this.bindingAttributeName); // Element
case 8: return ko.virtualElements.virtualNodeBindingValue(node); // Comment node
default: return null;
}
Expand All @@ -49,7 +50,12 @@
ex.message = "Unable to parse bindings.\nBindings value: " + bindingsString + "\nMessage: " + ex.message;
throw ex;
}
},

'setBindingAttributeName': function(attrName) {
this.bindingAttributeName = attrName;
}

});

ko.bindingProvider['instance'] = new ko.bindingProvider();
Expand Down
7 changes: 6 additions & 1 deletion src/templating/jquery.tmpl/jqueryTmplTemplateEngine.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@
document.write("<script type='text/html' id='" + templateName + "'>" + templateMarkup + "<" + "/script>");
};

this['contentType'] = "text/jquery-tmpl";

if (jQueryTmplVersion > 0) {
jQueryInstance['tmpl']['tag']['ko_code'] = {
open: "__.push($1 || '');"
Expand All @@ -77,8 +79,11 @@

// Use this one by default *only if jquery.tmpl is referenced*
var jqueryTmplTemplateEngineInstance = new ko.jqueryTmplTemplateEngine();
if (jqueryTmplTemplateEngineInstance.jQueryTmplVersion > 0)
if (jqueryTmplTemplateEngineInstance.jQueryTmplVersion > 0) {
ko.setTemplateEngine(jqueryTmplTemplateEngineInstance);
ko.setTemplateEngineContentType(jqueryTmplTemplateEngineInstance.contentType, jqueryTmplTemplateEngineInstance);
ko.jqueryTmplTemplateEngine.instance = jqueryTmplTemplateEngineInstance;
}

ko.exportSymbol('jqueryTmplTemplateEngine', ko.jqueryTmplTemplateEngine);
})();
3 changes: 3 additions & 0 deletions src/templating/native/nativeTemplateEngine.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ ko.nativeTemplateEngine.prototype['renderTemplateSource'] = function (templateSo
}
};

ko.nativeTemplateEngine.prototype['contentType'] = "text/ko-template";

ko.nativeTemplateEngine.instance = new ko.nativeTemplateEngine();
ko.setTemplateEngine(ko.nativeTemplateEngine.instance);
ko.setTemplateEngineContentType(ko.nativeTemplateEngine.instance.contentType, ko.nativeTemplateEngine.instance);

ko.exportSymbol('nativeTemplateEngine', ko.nativeTemplateEngine);
5 changes: 4 additions & 1 deletion src/templating/templateRewriting.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@

ko.templateRewriting = (function () {
var memoizeDataBindingAttributeSyntaxRegex = /(<([a-z]+\d*)(?:\s+(?!data-bind\s*=\s*)[a-z0-9\-]+(?:=(?:\"[^\"]*\"|\'[^\']*\'|[^>]*))?)*\s+)data-bind\s*=\s*(["'])([\s\S]*?)\3/gi;

var bindingAttrName = ko.bindingProvider.bindingAttributeName;

var memoizeDataBindingAttributeSyntaxRegex = new RegExp("(<([a-z]+\d*)(?:\s+(?!" + bindingAttrName + "\s*=\s*)[a-z0-9\-]+(?:=(?:\"[^\"]*\"|\'[^\']*\'|[^>]*))?)*\s+)" + bindingAttrName + "\s*=\s*([\"'])([\s\S]*?)\3", "gi");
var memoizeVirtualContainerBindingSyntaxRegex = /<!--\s*ko\b\s*([\s\S]*?)\s*-->/g;

function validateDataBindValuesForRewriting(keyValueArray) {
Expand Down
46 changes: 45 additions & 1 deletion src/templating/templating.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
(function () {
var _templateEngine;
var _templateEngineContentTypes = {};

ko.setTemplateEngineContentType = function(contentType, templateEngine) {
if(!contentType) {
throw new Error("contentType is not set");
}
if(_templateEngineContentTypes[contentType]) {
throw new Error("a templateEngine is already set for this contentType + '" + contentType + "'");
}
_templateEngineContentTypes[contentType] = templateEngine;
}

ko.getTemplateEngineFromContentType = function(contentType) {
return _templateEngineContentTypes[contentType];
}

ko.setTemplateEngine = function (templateEngine) {
if ((templateEngine != undefined) && !(templateEngine instanceof ko.templateEngine))
throw new Error("templateEngine must inherit from ko.templateEngine");
Expand Down Expand Up @@ -77,11 +93,37 @@
: null;
}

function resolveTemplateEngineToUse(template, options) {

var templateEngine;
// Option setting is prior
if(options['templateEngine']) {
templateEngine = options['templateEngine'];
} else {
// Check type attribute of script tag
if(typeof(template) == "string") {
var domElement = document.getElementById(template);
if(domElement) {
if(domElement.nodeType == 1 && domElement.type) { // script
templateEngine = domElement.type;
}
}
}
}

if(templateEngine && typeof(templateEngine) == "string") {
templateEngine = ko.getTemplateEngineFromContentType(templateEngine);
}

// Return default template engine
return templateEngine || _templateEngine;
}

function executeTemplate(targetNodeOrNodeArray, renderMode, template, bindingContext, options) {
options = options || {};
var firstTargetNode = targetNodeOrNodeArray && getFirstNodeFromPossibleArray(targetNodeOrNodeArray);
var templateDocument = (firstTargetNode || template || {}).ownerDocument;
var templateEngineToUse = (options['templateEngine'] || _templateEngine);
var templateEngineToUse = resolveTemplateEngineToUse(template, options);
ko.templateRewriting.ensureTemplateIsRewritten(template, templateEngineToUse, templateDocument);
var renderedNodesArray = templateEngineToUse['renderTemplate'](template, bindingContext, options, templateDocument);

Expand Down Expand Up @@ -298,4 +340,6 @@
})();

ko.exportSymbol('setTemplateEngine', ko.setTemplateEngine);
ko.exportSymbol('setTemplateEngineContentType', ko.setTemplateEngineContentType);
ko.exportSymbol('getTemplateEngineContentType', ko.getTemplateEngineContentType);
ko.exportSymbol('renderTemplate', ko.renderTemplate);