From b25f67fda9d449bb513890dc95de70ac2a233cde Mon Sep 17 00:00:00 2001 From: Patrick Steele-Idem Date: Fri, 19 May 2017 16:03:19 -0600 Subject: [PATCH] Code size reduction --- benchmark/size/package.json | 2 +- src/components/Component.js | 4 +-- src/components/ComponentsContext.js | 8 ++--- src/components/index.js | 4 +-- src/components/renderer.js | 4 +-- .../taglib/helpers/getCurrentComponent.js | 2 +- src/components/taglib/init-components-tag.js | 2 +- src/components/taglib/preserve-tag-browser.js | 2 +- src/morphdom/index.js | 10 +++---- src/morphdom/specialElHandlers.js | 4 +-- src/runtime/RenderResult.js | 2 +- src/runtime/vdom/VDocumentFragment.js | 2 +- src/runtime/vdom/VElement.js | 4 +-- src/runtime/vdom/VNode.js | 30 +++++++++---------- src/taglibs/cache/cached-fragment-tag.js | 6 ++-- test/AsyncVDOMBuilder-test.js | 10 +++---- .../cloneNode-documentFragment/index.js | 4 +-- .../vdom-create/createAttributes/index.js | 4 +-- .../vdom-create/static-tree/index.js | 6 ++-- test/server-tests-runner/cli.js | 4 ++- test/util/domToHTML.js | 22 +++++++++----- test/util/domToString.js | 29 +++++++++++------- test/util/runRenderTest.js | 4 +++ test/util/toHTML.js | 16 +++++++--- 24 files changed, 107 insertions(+), 78 deletions(-) diff --git a/benchmark/size/package.json b/benchmark/size/package.json index 717234b32..e43de2598 100644 --- a/benchmark/size/package.json +++ b/benchmark/size/package.json @@ -9,7 +9,7 @@ "build-marko": "npm run bundle-marko --silent && node minify.js marko", "build-inferno": "npm run bundle-inferno --silent && node minify.js inferno", "bundle": "mkdir -p build/bundles && npm run bundle-marko && npm run bundle-react && npm run bundle-vue && npm run bundle-preact && npm run bundle-inferno", - "bundle-marko": "NODE_ENV=production rollup -c marko/rollup.config.js", + "bundle-marko": "node ../../scripts/build && NODE_ENV=production rollup -c marko/rollup.config.js", "bundle-react": "NODE_ENV=production rollup -c react/rollup.config.js", "bundle-preact": "NODE_ENV=production rollup -c preact/rollup.config.js", "bundle-vue": "NODE_ENV=production rollup -c vue/rollup.config.js", diff --git a/src/components/Component.js b/src/components/Component.js index 6ada6411a..9a020e962 100644 --- a/src/components/Component.js +++ b/src/components/Component.js @@ -546,7 +546,7 @@ Component.prototype = componentProto = { var fromEl; - var targetEl = targetNode.firstChild; + var targetEl = targetNode.___firstChild; while(targetEl) { var id = targetEl.id; @@ -564,7 +564,7 @@ Component.prototype = componentProto = { onBeforeElChildrenUpdated); } - targetEl = targetEl.nextSibling; + targetEl = targetEl.___nextSibling; } } } diff --git a/src/components/ComponentsContext.js b/src/components/ComponentsContext.js index 7b2188b6a..2d83c54e5 100644 --- a/src/components/ComponentsContext.js +++ b/src/components/ComponentsContext.js @@ -39,7 +39,7 @@ GlobalComponentsContext.prototype = { // Reset things stored in global since global is retained for // future renders - this.___out.global.components = undefined; + this.___out.global.___components = undefined; return topLevelComponentDefs; }, @@ -75,9 +75,9 @@ function ComponentsContext(out, parentComponentsContext, shouldAddGlobalRoot) { var globalComponentsContext; if (parentComponentsContext === undefined) { - globalComponentsContext = out.global.components; + globalComponentsContext = out.global.___components; if (globalComponentsContext === undefined) { - out.global.components = globalComponentsContext = new GlobalComponentsContext(out); + out.global.___components = globalComponentsContext = new GlobalComponentsContext(out); } root = new ComponentDef(null, null, globalComponentsContext); @@ -136,7 +136,7 @@ ComponentsContext.prototype = { }; function getComponentsContext(out) { - return out.data.components || (out.data.components = new ComponentsContext(out)); + return out.data.___components || (out.data.___components = new ComponentsContext(out)); } module.exports = exports = ComponentsContext; diff --git a/src/components/index.js b/src/components/index.js index a5a40f706..6da4a563d 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -104,13 +104,13 @@ function getRenderedComponents(out, shouldIncludeAll) { var outGlobal = out.global; if (shouldIncludeAll === true) { - globalComponentsContext = outGlobal.components; + globalComponentsContext = outGlobal.___components; if (globalComponentsContext === undefined) { return undefined; } } else { - let componentsContext = out.data.components; + let componentsContext = out.data.___components; if (componentsContext === undefined) { return undefined; } diff --git a/src/components/renderer.js b/src/components/renderer.js index 094e3e9a2..68f08b5ad 100644 --- a/src/components/renderer.js +++ b/src/components/renderer.js @@ -47,7 +47,7 @@ function preserveComponentEls(existingComponent, out, globalComponentsContext) { function handleBeginAsync(event) { var parentOut = event.parentOut; var asyncOut = event.out; - var componentsContext = parentOut.data.components; + var componentsContext = parentOut.data.___components; if (componentsContext !== undefined) { // All of the components in this async block should be @@ -59,7 +59,7 @@ function handleBeginAsync(event) { // of the async block being added as children of the component in the // parent block. var nestedComponentsContext = componentsContext.___createNestedComponentsContext(asyncOut); - asyncOut.data.components = nestedComponentsContext; + asyncOut.data.___components = nestedComponentsContext; } // Carry along the component arguments asyncOut.___componentArgs = parentOut.___componentArgs; diff --git a/src/components/taglib/helpers/getCurrentComponent.js b/src/components/taglib/helpers/getCurrentComponent.js index 20e8b1f05..c1e750da7 100644 --- a/src/components/taglib/helpers/getCurrentComponent.js +++ b/src/components/taglib/helpers/getCurrentComponent.js @@ -5,7 +5,7 @@ * @return {ComponentDef} The ComponentDef instance */ module.exports = function getCurrentComponent(out) { - var componentsContext = out.data.components; + var componentsContext = out.data.___components; var componentStack; var len; diff --git a/src/components/taglib/init-components-tag.js b/src/components/taglib/init-components-tag.js index 320098b5e..69c752cb8 100644 --- a/src/components/taglib/init-components-tag.js +++ b/src/components/taglib/init-components-tag.js @@ -7,7 +7,7 @@ var ComponentsContext = require('../ComponentsContext'); function handleAwaitBeforeRender(eventArgs) { if (eventArgs.clientReorder) { var asyncFragmentOut = eventArgs.out; - asyncFragmentOut.data.components = new ComponentsContext(asyncFragmentOut, undefined, false); + asyncFragmentOut.data.___components = new ComponentsContext(asyncFragmentOut, undefined, false); } } diff --git a/src/components/taglib/preserve-tag-browser.js b/src/components/taglib/preserve-tag-browser.js index d39d1250d..a5e7bfcb2 100644 --- a/src/components/taglib/preserve-tag-browser.js +++ b/src/components/taglib/preserve-tag-browser.js @@ -1,7 +1,7 @@ var getElementById = require('../util').___getElementById; module.exports = function render(input, out) { - var globalComponentsContext = out.global.components; + var globalComponentsContext = out.global.___components; if (globalComponentsContext && globalComponentsContext.___isRerenderInBrowser !== true && globalComponentsContext.___rerenderComponent !== undefined) { var id = input.id; diff --git a/src/morphdom/index.js b/src/morphdom/index.js index 9ef36b3cf..a37f28fe5 100644 --- a/src/morphdom/index.js +++ b/src/morphdom/index.js @@ -54,7 +54,7 @@ function morphdom( onNodeAdded(realEl, context); - var vCurChild = vEl.firstChild; + var vCurChild = vEl.___firstChild; while (vCurChild) { var realCurChild = null; @@ -71,7 +71,7 @@ function morphdom( addVirtualNode(vCurChild, realEl); } - vCurChild = vCurChild.nextSibling; + vCurChild = vCurChild.___nextSibling; } if (vEl.___nodeType === 1) { @@ -116,7 +116,7 @@ function morphdom( } if (nodeName !== 'TEXTAREA') { - var curToNodeChild = toEl.firstChild; + var curToNodeChild = toEl.___firstChild; var curFromNodeChild = fromEl.firstChild; var curToNodeKey; var curFromNodeKey; @@ -126,7 +126,7 @@ function morphdom( var matchingFromEl; outer: while (curToNodeChild) { - toNextSibling = curToNodeChild.nextSibling; + toNextSibling = curToNodeChild.___nextSibling; curToNodeKey = curToNodeChild.id; while (curFromNodeChild) { @@ -169,7 +169,7 @@ function morphdom( fromEl.insertBefore(matchingFromEl, curFromNodeChild); - var curToNodeChildNextSibling = curToNodeChild.nextSibling; + var curToNodeChildNextSibling = curToNodeChild.___nextSibling; if (curToNodeChildNextSibling && curToNodeChildNextSibling.id === curFromNodeKey) { fromNextSibling = curFromNodeChild; } else { diff --git a/src/morphdom/specialElHandlers.js b/src/morphdom/specialElHandlers.js index d01b37517..191e11be6 100644 --- a/src/morphdom/specialElHandlers.js +++ b/src/morphdom/specialElHandlers.js @@ -59,7 +59,7 @@ module.exports = { if (!toEl.___hasAttribute('multiple')) { var selectedIndex = -1; var i = 0; - var curChild = toEl.firstChild; + var curChild = toEl.___firstChild; while(curChild) { if (curChild.___nodeName == 'OPTION') { if (curChild.___hasAttribute('selected')) { @@ -68,7 +68,7 @@ module.exports = { } i++; } - curChild = curChild.nextSibling; + curChild = curChild.___nextSibling; } fromEl.selectedIndex = i; diff --git a/src/runtime/RenderResult.js b/src/runtime/RenderResult.js index 1d7facf9c..78a7c73b7 100644 --- a/src/runtime/RenderResult.js +++ b/src/runtime/RenderResult.js @@ -41,7 +41,7 @@ var proto = RenderResult.prototype = { afterInsert: function(doc) { var out = this.___out; - var globalComponentsContext = out.global.components; + var globalComponentsContext = out.global.___components; if (globalComponentsContext) { this.___components = globalComponentsContext.___initComponents(doc); } else { diff --git a/src/runtime/vdom/VDocumentFragment.js b/src/runtime/vdom/VDocumentFragment.js index ac8624fa6..dbcf95f10 100644 --- a/src/runtime/vdom/VDocumentFragment.js +++ b/src/runtime/vdom/VDocumentFragment.js @@ -5,7 +5,7 @@ var extend = require('raptor-util/extend'); function VDocumentFragmentClone(other) { extend(this, other); this.___parentNode = null; - this.___nextSibling = null; + this.___nextSiblingInternal = null; } function VDocumentFragment(documentFragment) { diff --git a/src/runtime/vdom/VElement.js b/src/runtime/vdom/VElement.js index cf8d0a9d7..ead0b1ab4 100644 --- a/src/runtime/vdom/VElement.js +++ b/src/runtime/vdom/VElement.js @@ -41,9 +41,9 @@ function removeAttribute(el, namespaceURI, name) { } function VElementClone(other) { - this.___firstChild = other.___firstChild; + this.___firstChildInternal = other.___firstChildInternal; this.___parentNode = null; - this.___nextSibling = null; + this.___nextSiblingInternal = null; this.___attributes = other.___attributes; this.___properties = other.___properties; diff --git a/src/runtime/vdom/VNode.js b/src/runtime/vdom/VNode.js index 7511539f3..01e161a9a 100644 --- a/src/runtime/vdom/VNode.js +++ b/src/runtime/vdom/VNode.js @@ -7,39 +7,39 @@ VNode.prototype = { ___VNode: function(finalChildCount) { this.___finalChildCount = finalChildCount; this.___childCount = 0; - this.___firstChild = null; + this.___firstChildInternal = null; this.___lastChild = null; this.___parentNode = null; - this.___nextSibling = null; + this.___nextSiblingInternal = null; }, - get firstChild() { - var firstChild = this.___firstChild; + get ___firstChild() { + var firstChild = this.___firstChildInternal; if (firstChild && firstChild.___DocumentFragment) { - var nestedFirstChild = firstChild.firstChild; + var nestedFirstChild = firstChild.___firstChild; // The first child is a DocumentFragment node. // If the DocumentFragment node has a first child then we will return that. // Otherwise, the DocumentFragment node is not *really* the first child and // we need to skip to its next sibling - return nestedFirstChild || firstChild.nextSibling; + return nestedFirstChild || firstChild.___nextSibling; } return firstChild; }, - get nextSibling() { - var nextSibling = this.___nextSibling; + get ___nextSibling() { + var nextSibling = this.___nextSiblingInternal; if (nextSibling) { if (nextSibling.___DocumentFragment) { - var firstChild = nextSibling.firstChild; - return firstChild || nextSibling.nextSibling; + var firstChild = nextSibling.___firstChild; + return firstChild || nextSibling.___nextSibling; } } else { var parentNode = this.___parentNode; if (parentNode && parentNode.___DocumentFragment) { - return parentNode.nextSibling; + return parentNode.___nextSibling; } } @@ -62,9 +62,9 @@ VNode.prototype = { child.___parentNode = this; if (lastChild) { - lastChild.___nextSibling = child; + lastChild.___nextSiblingInternal = child; } else { - this.___firstChild = child; + this.___firstChildInternal = child; } this.___lastChild = child; @@ -84,11 +84,11 @@ VNode.prototype = { actualize: function(doc) { var actualNode = this.___actualize(doc); - var curChild = this.firstChild; + var curChild = this.___firstChild; while(curChild) { actualNode.appendChild(curChild.actualize(doc)); - curChild = curChild.nextSibling; + curChild = curChild.___nextSibling; } if (this.___nodeType === 1) { diff --git a/src/taglibs/cache/cached-fragment-tag.js b/src/taglibs/cache/cached-fragment-tag.js index cec5c5ff7..378c07ec8 100644 --- a/src/taglibs/cache/cached-fragment-tag.js +++ b/src/taglibs/cache/cached-fragment-tag.js @@ -19,7 +19,7 @@ module.exports = { if (input.renderBody) { input.renderBody(nestedOut); - } + } nestedOut .on('error', callback) @@ -35,10 +35,10 @@ module.exports = { } if (result.___cloneNode) { - var curChild = result.firstChild; + var curChild = result.___firstChild; while(curChild) { asyncOut.node(curChild.___cloneNode()); - curChild = curChild.nextSibling; + curChild = curChild.___nextSibling; } asyncOut.end(); } else { diff --git a/test/AsyncVDOMBuilder-test.js b/test/AsyncVDOMBuilder-test.js index b299633ce..62da24281 100644 --- a/test/AsyncVDOMBuilder-test.js +++ b/test/AsyncVDOMBuilder-test.js @@ -6,10 +6,10 @@ var expect = require('chai').expect; function getChildNodes(parentNode) { var childNodes = []; - var curChild = parentNode.firstChild; + var curChild = parentNode.___firstChild; while(curChild) { childNodes.push(curChild); - curChild = curChild.nextSibling; + curChild = curChild.___nextSibling; } return childNodes; @@ -48,9 +48,9 @@ describe('AsyncVDOMBuilder', function() { out.on('finish', function(result) { var tree = result.getOutput(); expect(getChildNodes(tree).length).to.equal(3); - expect(tree.firstChild.___nodeName).to.equal('div'); - expect(tree.firstChild.nextSibling.___nodeName).to.equal('span'); - expect(tree.firstChild.nextSibling.nextSibling.___nodeName).to.equal('section'); + expect(tree.___firstChild.___nodeName).to.equal('div'); + expect(tree.___firstChild.___nextSibling.___nodeName).to.equal('span'); + expect(tree.___firstChild.___nextSibling.___nextSibling.___nodeName).to.equal('section'); done(); }); }); diff --git a/test/autotests/vdom-create/cloneNode-documentFragment/index.js b/test/autotests/vdom-create/cloneNode-documentFragment/index.js index c89d6b536..4b46a0fd1 100644 --- a/test/autotests/vdom-create/cloneNode-documentFragment/index.js +++ b/test/autotests/vdom-create/cloneNode-documentFragment/index.js @@ -11,8 +11,8 @@ module.exports = function(helpers) { expect(svg.___namespaceURI).to.equal('http://www.w3.org/2000/svg'); var docFragmentClone = docFragment.___cloneNode(); - expect(docFragmentClone.nextSibling).to.equal(null); - expect(docFragmentClone.parentNode == null).to.equal(true); + expect(docFragmentClone.___nextSibling).to.equal(null); + expect(docFragmentClone.___parentNode == null).to.equal(true); return svg; }; diff --git a/test/autotests/vdom-create/createAttributes/index.js b/test/autotests/vdom-create/createAttributes/index.js index 618ca4bbf..9f3afe902 100644 --- a/test/autotests/vdom-create/createAttributes/index.js +++ b/test/autotests/vdom-create/createAttributes/index.js @@ -12,7 +12,7 @@ module.exports = function(helpers) { .t('eBay') .e('footer', null, 0); - expect(el.firstChild.firstChild.id).to.equal('link'); + expect(el.___firstChild.___firstChild.id).to.equal('link'); return el; -}; \ No newline at end of file +}; diff --git a/test/autotests/vdom-create/static-tree/index.js b/test/autotests/vdom-create/static-tree/index.js index 301f13bd2..31ac85b5a 100644 --- a/test/autotests/vdom-create/static-tree/index.js +++ b/test/autotests/vdom-create/static-tree/index.js @@ -8,14 +8,14 @@ module.exports = function(helpers) { .n(link) .e('span', null, 0); - var linkClone = el.firstChild; + var linkClone = el.___firstChild; expect(linkClone).to.not.equal(link); expect(link.___parentNode).to.equal(null); - expect(link.nextSibling).to.equal(null); + expect(link.___nextSibling).to.equal(null); - expect(linkClone.nextSibling.___nodeName).to.equal('span'); + expect(linkClone.___nextSibling.___nodeName).to.equal('span'); expect(linkClone.___parentNode.___nodeName).to.equal('div'); diff --git a/test/server-tests-runner/cli.js b/test/server-tests-runner/cli.js index 33a5f6430..aa2be0651 100644 --- a/test/server-tests-runner/cli.js +++ b/test/server-tests-runner/cli.js @@ -7,6 +7,8 @@ const testDir = path.join(rootDir, isDebug ? 'test' : 'test-dist'); const { spawnSync } = require('child_process'); const mochaPath = path.join(rootDir, 'node_modules/.bin/mocha'); -spawnSync(mochaPath, ['--ui', 'bdd', '--reporter', 'spec', testDir], { +var result = spawnSync(mochaPath, ['--ui', 'bdd', '--reporter', 'spec', testDir], { stdio: 'inherit' }); + +process.exit(result.status); diff --git a/test/util/domToHTML.js b/test/util/domToHTML.js index 661911014..f1e42951d 100644 --- a/test/util/domToHTML.js +++ b/test/util/domToHTML.js @@ -25,10 +25,18 @@ var openTagOnly = {}; openTagOnly[tagName] = true; }); -function nodeValue(node) { +function getNodeValue(node) { return node.___nodeValue || node.nodeValue; } +function getFirstChild(node) { + return node.___firstChild || node.firstChild; +} + +function getNextSibling(node) { + return node.___nextSibling || node.nextSibling; +} + function vdomToHTML(node, options) { @@ -101,7 +109,7 @@ function vdomToHTML(node, options) { if (tagName.toUpperCase() === 'TEXTAREA') { html += el.value; } else { - var curChild = el.firstChild; + var curChild = getFirstChild(el); if (curChild) { while(curChild) { let nodeType = curChild.nodeType || curChild.___nodeType; @@ -112,7 +120,7 @@ function vdomToHTML(node, options) { serializeHelper(curChild); } - curChild = curChild.nextSibling; + curChild = getNextSibling(curChild); } } else if (openTagOnly[tagName.toLowerCase()]) { hasEndTag = false; @@ -125,21 +133,21 @@ function vdomToHTML(node, options) { } function serializeTextHelper(node, escape) { - html += escape !== false ? escapeXml(nodeValue(node)) : nodeValue(node); + html += escape !== false ? escapeXml(getNodeValue(node)) : getNodeValue(node); } function serializeCommentHelper(node) { - html += ''; + html += ''; } let nodeType = node.nodeType || node.___nodeType; if (nodeType === 11 /* DocumentFragment */ || (options && options.childrenOnly)) { - var curChild = node.firstChild; + var curChild = getFirstChild(node); while(curChild) { serializeHelper(curChild); - curChild = curChild.nextSibling; + curChild = getNextSibling(curChild); } } else { serializeHelper(node); diff --git a/test/util/domToString.js b/test/util/domToString.js index 33cbfcd3a..3bc8056f4 100644 --- a/test/util/domToString.js +++ b/test/util/domToString.js @@ -6,10 +6,18 @@ function getNodeType(node) { return node.nodeType || node.___nodeType; } -function nodeValue(node) { +function getNodeValue(node) { return node.___nodeValue || node.nodeValue; } +function getFirstChild(node) { + return node.___firstChild || node.firstChild; +} + +function getNextSibling(node) { + return node.___nextSibling || node.nextSibling; +} + function vdomToHTML(node, options) { // NOTE: We don't use XMLSerializer because we need to sort the attributes to correctly compare output HTML strings @@ -93,33 +101,32 @@ function vdomToHTML(node, options) { if (tagName.toUpperCase() === 'TEXTAREA') { html += indent + ' VALUE: ' + JSON.stringify(ltrim(el.value)) + '\n'; } else { - - // if (tagName.toUpperCase() === 'PRE' && el.firstChild && getNodeType(el.firstChild) === 3) { - // nodeValue(el.firstChild) = ltrim(nodeValue(el.firstChild)); - // } - var curChild = el.firstChild; + var curChild = getFirstChild(el); while(curChild) { serializeHelper(curChild, indent + ' '); - curChild = curChild.nextSibling; + curChild = getNextSibling(curChild); } } } function serializeTextHelper(node, indent) { - html += indent + JSON.stringify(nodeValue(node)) + '\n'; + html += indent + JSON.stringify(getNodeValue(node)) + '\n'; } function serializeCommentHelper(node, indent) { - html += indent + '\n'; + html += indent + '\n'; } if (getNodeType(node) === 11 /* DocumentFragment */ || (options && options.childrenOnly)) { - var curChild = node.firstChild; + var curChild = getFirstChild(node); + while(curChild) { serializeHelper(curChild, ''); - curChild = curChild.nextSibling; + curChild = getNextSibling(curChild); } } else { + + serializeHelper(node, ''); } diff --git a/test/util/runRenderTest.js b/test/util/runRenderTest.js index 8343fded7..d68cbab5f 100644 --- a/test/util/runRenderTest.js +++ b/test/util/runRenderTest.js @@ -182,6 +182,10 @@ module.exports = function runRenderTest(dir, helpers, done, options) { getExpectedHtml(function(err, expectedHtml) { + if (err) { + return done(err); + } + fs.writeFileSync(path.join(dir, 'vdom-expected.generated.html'), expectedHtml, { encoding: 'utf8' }); let actualizedDom = vdomTree.actualize(defaultDocument); diff --git a/test/util/toHTML.js b/test/util/toHTML.js index bae65525c..5b6d3b611 100644 --- a/test/util/toHTML.js +++ b/test/util/toHTML.js @@ -6,6 +6,14 @@ function getNodeValue(node) { return node.___nodeValue || node.nodeValue; } +function getFirstChild(node) { + return node.___firstChild || node.firstChild; +} + +function getNextSibling(node) { + return node.___nextSibling || node.nextSibling; +} + function toHTML(node) { // NOTE: We don't use XMLSerializer because we need to sort the attributes to correctly compare output HTML strings @@ -81,10 +89,10 @@ function toHTML(node) { if (tagName.toUpperCase() === 'TEXTAREA') { html += indent + ' VALUE: ' + JSON.stringify(el.value) + '\n'; } else { - var curChild = el.firstChild; + var curChild = getFirstChild(el); while(curChild) { serializeHelper(curChild, indent + ' '); - curChild = curChild.nextSibling; + curChild = getNextSibling(curChild); } } @@ -108,10 +116,10 @@ function toHTML(node) { } if (getNodeType(node) === 11 /* DocumentFragment */) { - var curChild = node.firstChild; + var curChild = getFirstChild(node); while(curChild) { serializeHelper(curChild, ''); - curChild = curChild.nextSibling; + curChild = getNextSibling(curChild); } } else { serializeHelper(node, '');