Skip to content

Commit

Permalink
Re knockout#1880 add <template> parser and more parser tests
Browse files Browse the repository at this point in the history
  • Loading branch information
brianmhunt committed Sep 17, 2015
1 parent 23db72d commit 0696316
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 1 deletion.
17 changes: 16 additions & 1 deletion spec/parseHtmlFragment.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ describe('Parse HTML fragment', function() {
temporarilyRegisteredComponents = [];
});

// See: https://github.com/knockout/knockout/issues/1880
ko.utils.arrayForEach(
[
{ html: '<tr-component></tr-component>', parsed: ['<tr-component></tr-component>'] },
Expand All @@ -25,7 +26,11 @@ describe('Parse HTML fragment', function() {
{ html: '<table><tbody></tbody></table>', parsed: ['<table><tbody></tbody></table>'] },
{ html: '<div></div><div></div>', parsed: ['<div></div>', '<div></div>'] },
{ html: '<optgroup label=x><option>text</option></optgroup>', parsed: ['<optgroup label=x><option>text</option></optgroup>'] },
{ html: '<option>text</option>', parsed: [ '<option>text</option>' ] }
{ html: '<option>text</option>', parsed: [ '<option>text</option>' ] },
{ html: '<colgroup><col></colgroup>', parsed: ['<colgroup><col></colgroup>'] },
{ html: '<param>', parsed: ['<param>'] },
{ html: '<area>', parsed: ['<area>'] },
{ html: '<legend>lgt</legend>', parsed: ['<legend>lgt</legend>'] }
], function (data) {
it('should parse ' + data.html + ' correctly', function () {
// IE 6-8 has a lot of trouble with custom elements. We have several strategies for dealing with
Expand Down Expand Up @@ -88,4 +93,14 @@ describe('Parse HTML fragment', function() {
}
});
});

it("returns copies of the nodes", function () {
var html = '<div><i></i></div>';
var parsedNodes1 = ko.utils.parseHtmlFragment(html, document);
var parsedNodes2 = ko.utils.parseHtmlFragment(html, document);
expect(parsedNodes1).toNotEqual(parsedNodes2);
expect(parsedNodes1[0]).toNotEqual(parsedNodes2[0]);
// We need to test for deep inequality
expect(parsedNodes1[0].children[0]).toNotEqual(parsedNodes2[0].children[0]);
})
});
12 changes: 12 additions & 0 deletions src/utils.domManipulation.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
tr = [3, "<table><tbody><tr>", "</tr></tbody></table>"],
select = [1, "<select multiple='multiple'>", "</select>"],
lookup = {
'colgroup': table,
'thead': table,
'tbody': table,
'tfoot': table,
Expand All @@ -18,6 +19,9 @@
// This is needed for old IE if you're *not* using either jQuery or innerShiv. Doesn't affect other cases.
mayRequireCreateElementHack = ko.utils.ieVersion <= 8,

// The canonical way to test that the HTML5 <template> tag is supported
supportsTemplateTag = 'content' in document.createElement('template'),

// We prefer not to use jQuery's HTML parsing, because it fails on element names like tr-*, even
// on the latest browsers (not even just on IE). But we retain use of jQuery HTML parsing for old
// IE, to avoid breaking compatibility with parsing edge-cases. Strangely, jQuery's HTML parsing
Expand Down Expand Up @@ -75,6 +79,13 @@
return ko.utils.makeArray(div.lastChild.childNodes);
}

function templateHtmlParse(html, documentContext) {
if (!documentContext) { documentContext = document; }
var template = documentContext.createElement('template');
template.innerHTML = html;
return ko.utils.makeArray(template.content.childNodes);
}

function jQueryHtmlParse(html, documentContext) {
// jQuery's "parseHTML" function was introduced in jQuery 1.8.0 and is a documented public API.
if (jQueryInstance['parseHTML']) {
Expand Down Expand Up @@ -103,6 +114,7 @@
ko.utils.parseHtmlFragment = function(html, documentContext) {
return allowJQueryHtmlParsing && jQueryInstance ?
jQueryHtmlParse(html, documentContext) : // As below, benefit from jQuery's optimisations where possible
supportsTemplateTag ? templateHtmlParse(html, documentContext) :
simpleHtmlParse(html, documentContext); // ... otherwise, this simple logic will do in most common cases.
};

Expand Down

0 comments on commit 0696316

Please sign in to comment.