(function () { var none = [0, "", ""], table = [1, "", "
"], tbody = [2, "", "
"], tr = [3, "", "
"], select = [1, ""], lookup = { 'thead': table, 'tbody': table, 'tfoot': table, 'tr': tbody, 'td': tr, 'th': tr, 'option': select, 'optgroup': select }; function getWrap(tags) { var m = tags.match(/^(?:\s*?)*?<([a-z]+)[\s>]/); return (m && lookup[m[1]]) || none; } function simpleHtmlParse(html, documentContext) { documentContext || (documentContext = document); var windowContext = documentContext['parentWindow'] || documentContext['defaultView'] || window; // Based on jQuery's "clean" function, but only accounting for table-related elements. // Trim whitespace, otherwise indexOf won't work as expected var tags = ko.utils.stringTrim(html).toLowerCase(), div = documentContext.createElement("div"), wrap = getWrap(tags), depth = wrap[0]; // Go to html and back, then peel off extra wrappers // Note that we always prefix with some dummy text, because otherwise, IE<9 will strip out leading comment nodes in descendants. Total madness. var markup = "ignored
" + wrap[1] + html + wrap[2] + "
"; if (typeof windowContext['innerShiv'] == "function") { // Note that innerShiv is deprecated in favour of html5shiv. We should consider adding // support for html5shiv (except if no explicit support is needed, e.g., if html5shiv // somehow shims the native APIs so it just works anyway) div.append(windowContext['innerShiv'](markup)); } else { div.innerHTML = markup; } // Move to the right depth while (depth--) div = div.lastChild; return ko.utils.makeArray(div.lastChild.childNodes); } ko.utils.parseHtmlFragment = function(html, documentContext) { return simpleHtmlParse(html, documentContext); // ... otherwise, this simple logic will do in most common cases. }; ko.utils.parseHtmlForTemplateNodes = function(html, documentContext) { var nodes = ko.utils.parseHtmlFragment(html, documentContext); return (nodes.length && nodes[0].parentElement) || ko.utils.moveCleanedNodesToContainerElement(nodes); }; ko.utils.setHtml = function(node, html) { ko.utils.emptyDomNode(node); // There's no legitimate reason to display a stringified observable without unwrapping it, so we'll unwrap it html = ko.utils.unwrapObservable(html); if ((html !== null) && (html !== undefined)) { if (typeof html != 'string') html = html.toString(); // jQuery contains a lot of sophisticated code to parse arbitrary HTML fragments, // for example 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. // ... otherwise, use KO's own parsing logic. var parsedNodes = ko.utils.parseHtmlFragment(html, node.ownerDocument); for (var i = 0; i < parsedNodes.length; i++) node.appendChild(parsedNodes[i]); } }; })(); ko.exportSymbol('utils.parseHtmlFragment', ko.utils.parseHtmlFragment); ko.exportSymbol('utils.setHtml', ko.utils.setHtml);