Permalink
Browse files

Demonstration of futher requirement for 'html' binding

  • Loading branch information...
1 parent e1473e8 commit 623cdd130398bef3122fbbff3660348d671dad10 @SteveSanderson SteveSanderson committed May 12, 2011
Showing with 42 additions and 6 deletions.
  1. +17 −0 spec/defaultBindingsBehaviors.js
  2. +24 −5 src/utils.domManipulation.js
  3. +1 −1 src/utils.js
@@ -128,6 +128,23 @@ describe('Binding: HTML', {
testNode.innerHTML = "<p data-bind='html:textProp'></p>";
ko.applyBindings(model, testNode);
value_of(testNode.childNodes[0]).should_contain_html(model.textProp);
+ },
+
+ 'Should be able to write arbitrary HTML, including <tr> elements into tables': function() {
+ // Some HTML elements are awkward, because the browser implicitly adds surrounding
+ // elements, or won't allow those elements to be direct children of others.
+ // The most common examples relate to tables.
+ var model = { textProp: "<tr><td>hello</td></tr>" };
+ testNode.innerHTML = "<table data-bind='html:textProp'></table>";
+ ko.applyBindings(model, testNode);
+
+ // Accept either of the following outcomes - there may or may not be an implicitly added <tbody>.
+ var tr = testNode.childNodes[0].childNodes[0];
+ if (tr.tagName == 'TBODY')
+ tr = tr.childNodes[0];
+ value_of(tr.tagName).should_be("TR");
+ value_of(tr.childNodes[0].tagName).should_be("TD");
+ value_of(tr.childNodes[0].innerText).should_be("hello");
}
});
@@ -1,15 +1,34 @@
(function () {
+ function simpleHtmlParse(html) {
+ // This code is to be replaced in a moment with something more intelligent
+ var dummy = document.createElement("div");
+ dummy.innerHTML = html;
+ return ko.utils.makeArray(dummy.childNodes);
+ }
+
+ ko.utils.parseHtmlFragment = function(html) {
+ return typeof jQuery != 'undefined' ? jQuery['clean']([html]) // As below, benefit from jQuery's optimisations where possible
+ : simpleHtmlParse(html); // ... otherwise, this simple logic will do in most common cases.
+ };
+
ko.utils.setHtml = function(node, html) {
ko.utils.emptyDomNode(node);
if ((html !== null) && (html !== undefined)) {
if (typeof html != 'string')
html = html.toString();
-
- var dummy = document.createElement("div");
- dummy.innerHTML = html;
- while (dummy.firstChild)
- node.appendChild(dummy.firstChild);
+
+ // jQuery contains a lot of sophisticated code to parse arbitrary HTML fragments,
+ // for example <tr> elements which are not normally allowed to exist on their own.
+ // If you've referenced jQuery we'll use that rather than duplicating its code.
+ if (typeof jQuery != 'undefined') {
+ jQuery(node)['html'](html);
+ } else {
+ // ... otherwise, use KO's own parsing logic.
+ var parsedNodes = ko.utils.parseHtmlFragment(html);
+ for (var i = 0; i < parsedNodes.length; i++)
+ node.appendChild(parsedNodes[i]);
+ }
}
};
})();
View
@@ -263,7 +263,7 @@ ko.utils = new (function () {
makeArray: function(arrayLikeObject) {
var result = [];
- for (var i = arrayLikeObject.length - 1; i >= 0; i--){
+ for (var i = 0, j = arrayLikeObject.length; i < j; i++) {
result.push(arrayLikeObject[i]);
};
return result;

0 comments on commit 623cdd1

Please sign in to comment.