Skip to content
This repository has been archived by the owner on Apr 4, 2019. It is now read-only.

Commit

Permalink
SimpleDOM perf optimization for setMorphHTML
Browse files Browse the repository at this point in the history
When running in the browser, we rely on the browser’s built-in HTML
parsing for cases when users provide unescaped HTML content as dynamic
values in their templates (i.e., `{{{unsafeHTML}}}`). Because the final
output is a DOM tree, we ask the browser to parse the HTML and turn it
into a document fragment, then insert into the appropriate location in
the rendered element.

However, for server-side rendering, the final output is serialized HTML,
not a DOM tree. In the case of raw HTML provided by the user, we’d be
doing extra work to go from raw HTML -> parsed DOM -> serialized HTML.
(That we’d need an HTML parser also adds complexity.)

This patch allows us to detect an extension to the DOM API we’ve added
to SimpleDOM that allows us to insert a node in the DOM tree that means
“raw HTML” (similar to CDATA). When we go to serialize the DOM tree, any
raw HTML nodes are written as the HTML that was provided when created.
  • Loading branch information
tomdale committed Dec 8, 2015
1 parent 7f7ceeb commit e92d8c9
Showing 1 changed file with 16 additions and 3 deletions.
19 changes: 16 additions & 3 deletions packages/dom-helper/lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ function DOMHelper(_document){
this.canClone = canClone;
this.namespace = null;

installProtocolForURL(this);
installEnvironmentSpecificMethods(this);
}

var prototype = DOMHelper.prototype;
Expand Down Expand Up @@ -571,7 +571,7 @@ prototype.parseHTML = function(html, contextualElement) {
var URL;
var parsingNode;

function installProtocolForURL(domHelper) {
function installEnvironmentSpecificMethods(domHelper) {
var protocol = browserProtocolForURL.call(domHelper, 'foobar:baz');

// Test to see if our DOM implementation parses
Expand All @@ -580,15 +580,28 @@ function installProtocolForURL(domHelper) {
// Swap in the method that doesn't do this test now that
// we know it works.
domHelper.protocolForURL = browserProtocolForURL;
} else {
} else if (typeof module === 'object' && typeof module.require === 'function') {
// Otherwise, we need to fall back to our own URL parsing.
// Global `require` is shadowed by Ember's loader so we have to use the fully
// qualified `module.require`.
URL = module.require('url');
domHelper.protocolForURL = nodeProtocolForURL;
} else {
throw new Error("DOM Helper could not find valid URL parsing mechanism");
}

// A SimpleDOM-specific extension that allows us to place HTML directly
// into the DOM tree, for when the output target is always serialized HTML.
if (domHelper.document.createRawHTMLSection) {
domHelper.setMorphHTML = nodeSetMorphHTML;
}
}

function nodeSetMorphHTML(morph, html) {
var section = this.document.createRawHTMLSection(html);
morph.setNode(section);
}

function browserProtocolForURL(url) {
if (!parsingNode) {
parsingNode = this.document.createElement('a');
Expand Down

0 comments on commit e92d8c9

Please sign in to comment.