diff --git a/packages/htmlbars-runtime/lib/render.js b/packages/htmlbars-runtime/lib/render.js
index b559fa74..7841112c 100644
--- a/packages/htmlbars-runtime/lib/render.js
+++ b/packages/htmlbars-runtime/lib/render.js
@@ -4,6 +4,7 @@ import ExpressionVisitor from "./expression-visitor";
import { AlwaysDirtyVisitor } from "./expression-visitor";
import Morph from "./morph";
import { clearMorph } from "../htmlbars-util/template-utils";
+import voidMap from '../htmlbars-util/void-tag-names';
var svgNamespace = "http://www.w3.org/2000/svg";
@@ -102,9 +103,13 @@ export function manualElement(tagName, attributes) {
dom.setAttribute(el1, key, attributes[key]);
}
- var el2 = dom.createComment("");
- dom.appendChild(el1, el2);
+ if (!voidMap[tagName]) {
+ var el2 = dom.createComment("");
+ dom.appendChild(el1, el2);
+ }
+
dom.appendChild(el0, el1);
+
return el0;
},
buildRenderNodes: function buildRenderNodes(dom, fragment) {
diff --git a/packages/htmlbars-runtime/tests/main-test.js b/packages/htmlbars-runtime/tests/main-test.js
index 60e9c997..d75e5435 100644
--- a/packages/htmlbars-runtime/tests/main-test.js
+++ b/packages/htmlbars-runtime/tests/main-test.js
@@ -100,3 +100,15 @@ test("manualElement function honors namespaces", function() {
ok(result.fragment.childNodes[1].childNodes[0] instanceof SVGLinearGradientElement);
equalTokens(result.fragment, '');
});
+
+test("manualElement function honors void elements", function() {
+ var attributes = {
+ class: 'foo-bar'
+ };
+ var layout = manualElement('input', attributes);
+ var fragment = layout.buildFragment(new DOMHelper());
+
+ equal(fragment.childNodes.length, 1, 'includes a single element');
+ equal(fragment.childNodes[0].childNodes.length, 0, 'no child nodes were added to `` because it is a void tag');
+ equalTokens(fragment, '');
+});
diff --git a/packages/htmlbars-syntax/lib/token-handlers.js b/packages/htmlbars-syntax/lib/token-handlers.js
index 6c141d3e..8771093e 100644
--- a/packages/htmlbars-syntax/lib/token-handlers.js
+++ b/packages/htmlbars-syntax/lib/token-handlers.js
@@ -1,20 +1,9 @@
-import { forEach } from "../htmlbars-util/array-utils";
import { buildProgram, buildComponent, buildElement, buildComment, buildText } from "./builders";
import {
appendChild,
parseComponentBlockParams
} from "./utils";
-
-// The HTML elements in this list are speced by
-// http://www.w3.org/TR/html-markup/syntax.html#syntax-elements,
-// and will be forced to close regardless of if they have a
-// self-closing /> at the end.
-var voidTagNames = "area base br col command embed hr img input keygen link meta param source track wbr";
-var voidMap = {};
-
-forEach(voidTagNames.split(" "), function(tagName) {
- voidMap[tagName] = true;
-});
+import voidMap from '../htmlbars-util/void-tag-names';
// Except for `mustache`, all tokens are only allowed outside of
// a start or end tag.
diff --git a/packages/htmlbars-util/lib/void-tag-names.js b/packages/htmlbars-util/lib/void-tag-names.js
new file mode 100644
index 00000000..08ce3bf5
--- /dev/null
+++ b/packages/htmlbars-util/lib/void-tag-names.js
@@ -0,0 +1,14 @@
+import { forEach } from "./array-utils";
+
+// The HTML elements in this list are speced by
+// http://www.w3.org/TR/html-markup/syntax.html#syntax-elements,
+// and will be forced to close regardless of if they have a
+// self-closing /> at the end.
+var voidTagNames = "area base br col command embed hr img input keygen link meta param source track wbr";
+var voidMap = {};
+
+forEach(voidTagNames.split(" "), function(tagName) {
+ voidMap[tagName] = true;
+});
+
+export default voidMap;