From bb86adef8cf6d98f0272a20c3bdf3b0262b74a14 Mon Sep 17 00:00:00 2001 From: Peter Sutherland Date: Tue, 17 Jan 2017 12:07:19 +0000 Subject: [PATCH] Add ability to create comment nodes --- src/htmldomapi.ts | 6 ++++++ src/snabbdom.ts | 7 ++++++- test/core.js | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/htmldomapi.ts b/src/htmldomapi.ts index 6d6906b..3dc6fcf 100644 --- a/src/htmldomapi.ts +++ b/src/htmldomapi.ts @@ -2,6 +2,7 @@ export interface DOMAPI { createElement: (tagName: any) => HTMLElement; createElementNS: (namespaceURI: string, qualifiedName: string) => Element; createTextNode: (text: string) => Text; + createComment: (text: string) => Comment; insertBefore: (parentNode: Node, newNode: Node, referenceNode: Node | null) => void; removeChild: (node: Node, child: Node) => void; appendChild: (node: Node, child: Node) => void; @@ -23,6 +24,10 @@ function createTextNode(text: string): Text { return document.createTextNode(text); } +function createComment(text: string): Comment { + return document.createComment(text); +} + function insertBefore(parentNode: Node, newNode: Node, referenceNode: Node | null): void { parentNode.insertBefore(newNode, referenceNode); } @@ -55,6 +60,7 @@ export const htmlDomApi = { createElement, createElementNS, createTextNode, + createComment, insertBefore, removeChild, appendChild, diff --git a/src/snabbdom.ts b/src/snabbdom.ts index e89b66b..081c8b9 100644 --- a/src/snabbdom.ts +++ b/src/snabbdom.ts @@ -81,7 +81,12 @@ export function init(modules: Array>, domApi?: DOMAPI) { } } let children = vnode.children, sel = vnode.sel; - if (sel !== undefined) { + if (sel === '!') { + if (isUndef(vnode.text)) { + vnode.text = ''; + } + vnode.elm = api.createComment(vnode.text as string); + } else if (sel !== undefined) { // Parse selector const hashIdx = sel.indexOf('#'); const dotIdx = sel.indexOf('.', hashIdx); diff --git a/test/core.js b/test/core.js index 13435b4..1e5d590 100644 --- a/test/core.js +++ b/test/core.js @@ -64,6 +64,11 @@ describe('snabbdom', function() { var vnode = h('a', {}, 'I am a string'); assert.equal(vnode.text, 'I am a string'); }); + it('can create vnode for comment', function() { + var vnode = h('!', 'test'); + assert.equal(vnode.sel, '!'); + assert.equal(vnode.text, 'test'); + }); }); describe('created element', function() { it('has tag', function() { @@ -165,6 +170,11 @@ describe('snabbdom', function() { assert.equal(elm.id, 'id'); assert.equal(elm.className, 'class'); }); + it('can create comments', function() { + elm = patch(vnode0, h('!', 'test')).elm; + assert.equal(elm.nodeType, document.COMMENT_NODE); + assert.equal(elm.textContent, 'test'); + }); }); describe('patching an element', function() { it('changes the elements classes', function() { @@ -497,6 +507,30 @@ describe('snabbdom', function() { elm = patch(vnode1, vnode2).elm; assert.equal(elm.childNodes[0].textContent, 'Text2'); }); + it('handles unmoved comment nodes', function() { + var vnode1 = h('div', [h('!', 'Text'), h('span', 'Span')]); + var vnode2 = h('div', [h('!', 'Text'), h('span', 'Span')]); + elm = patch(vnode0, vnode1).elm; + assert.equal(elm.childNodes[0].textContent, 'Text'); + elm = patch(vnode1, vnode2).elm; + assert.equal(elm.childNodes[0].textContent, 'Text'); + }); + it('handles changing comment text', function() { + var vnode1 = h('div', [h('!', 'Text'), h('span', 'Span')]); + var vnode2 = h('div', [h('!', 'Text2'), h('span', 'Span')]); + elm = patch(vnode0, vnode1).elm; + assert.equal(elm.childNodes[0].textContent, 'Text'); + elm = patch(vnode1, vnode2).elm; + assert.equal(elm.childNodes[0].textContent, 'Text2'); + }); + it('handles changing empty comment', function() { + var vnode1 = h('div', [h('!'), h('span', 'Span')]); + var vnode2 = h('div', [h('!', 'Test'), h('span', 'Span')]); + elm = patch(vnode0, vnode1).elm; + assert.equal(elm.childNodes[0].textContent, ''); + elm = patch(vnode1, vnode2).elm; + assert.equal(elm.childNodes[0].textContent, 'Test'); + }); it('prepends element', function() { var vnode1 = h('div', [h('span', 'World')]); var vnode2 = h('div', [h('span', 'Hello'), h('span', 'World')]);