diff --git a/client/render.js b/client/render.js
index 7fee3434..e137652f 100644
--- a/client/render.js
+++ b/client/render.js
@@ -5,7 +5,7 @@ import { anchorableElement } from './anchorableNode'
import { generateCallback, generateSubject } from './events'
import { ref } from './ref'
-export default function render(node, options) {
+export default function render(node, isSvg = false) {
if (isFalse(node) || node.type === 'head') {
node.element = document.createComment('')
return node.element
@@ -16,9 +16,8 @@ export default function render(node, options) {
return node.element
}
- const svg = (options && options.svg) || node.type === 'svg'
-
- if (svg) {
+ isSvg = isSvg || node.type === 'svg'
+ if (isSvg) {
node.element = document.createElementNS('http://www.w3.org/2000/svg', node.type)
} else {
node.element = document.createElement(node.type)
@@ -58,7 +57,7 @@ export default function render(node, options) {
if (!node.attributes.html) {
for (let i = 0; i < node.children.length; i++) {
- const child = render(node.children[i], { svg })
+ const child = render(node.children[i], isSvg)
node.element.appendChild(child)
}
diff --git a/client/rerender.js b/client/rerender.js
index cd788f67..512f9d69 100644
--- a/client/rerender.js
+++ b/client/rerender.js
@@ -100,7 +100,7 @@ function updateHeadChildren(currentChildren, nextChildren) {
}
}
-function _rerender(current, next) {
+function _rerender(current, next, isParentSvg = false) {
const selector = current.element
next.element = current.element
@@ -108,8 +108,10 @@ function _rerender(current, next) {
return
}
+ const isSvg = isParentSvg || next.type === 'svg'
+
if (current.type !== next.type) {
- const nextSelector = render(next)
+ const nextSelector = render(next, isSvg)
selector.replaceWith(nextSelector)
return
}
@@ -132,22 +134,22 @@ function _rerender(current, next) {
const limit = Math.max(current.children.length, next.children.length)
if (next.children.length > current.children.length) {
for (let i = 0; i < current.children.length; i++) {
- _rerender(current.children[i], next.children[i])
+ _rerender(current.children[i], next.children[i], isSvg)
}
for (let i = current.children.length; i < next.children.length; i++) {
- const nextSelector = render(next.children[i])
+ const nextSelector = render(next.children[i], isSvg)
selector.appendChild(nextSelector)
}
} else if (current.children.length > next.children.length) {
for (let i = 0; i < next.children.length; i++) {
- _rerender(current.children[i], next.children[i])
+ _rerender(current.children[i], next.children[i], isSvg)
}
for (let i = current.children.length - 1; i >= next.children.length; i--) {
selector.childNodes[i].remove()
}
} else {
for (let i = limit - 1; i > -1; i--) {
- _rerender(current.children[i], next.children[i])
+ _rerender(current.children[i], next.children[i], isSvg)
}
}
}
diff --git a/package.json b/package.json
index 005279b0..970fece1 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "nullstack",
- "version": "0.20.1",
+ "version": "0.20.4",
"description": "Feature-Driven Full Stack JavaScript Components",
"main": "./types/index.d.ts",
"author": "Mortaro",
@@ -35,10 +35,8 @@
"swc-loader": "0.2.3",
"swc-plugin-nullstack": "0.1.3",
"terser-webpack-plugin": "5.3.6",
- "webpack": "5.88.1",
- "webpack-hot-middleware": "2.25.4"
- },
- "devDependencies": {
- "webpack-dev-middleware": "github:Mortaro/webpack-dev-middleware#fix-write-to-disk-cleanup"
+ "webpack": "5.88.2",
+ "webpack-hot-middleware": "2.25.4",
+ "webpack-dev-middleware": "6.1.1"
}
}
\ No newline at end of file
diff --git a/server/render.js b/server/render.js
index e1b565d2..06e416cf 100644
--- a/server/render.js
+++ b/server/render.js
@@ -1,4 +1,4 @@
-import { isFalse } from '../shared/nodes'
+import { isFalse, isText } from '../shared/nodes'
import { sanitizeHtml } from '../shared/sanitizeString'
import renderAttributes from './renderAttributes'
@@ -25,7 +25,7 @@ function renderBody(node, scope, next) {
if (isFalse(node)) {
return ''
}
- if (node.type === 'text') {
+ if (isText(node)) {
const text = node.text === '' ? ' ' : sanitizeHtml(node.text.toString())
return next && next.type === 'text' ? `${text}` : text
}
diff --git a/shared/nodes.js b/shared/nodes.js
index f1d3363e..4da25648 100644
--- a/shared/nodes.js
+++ b/shared/nodes.js
@@ -18,5 +18,5 @@ export function isFunction(node) {
}
export function isText(node) {
- return node.type === 'text'
+ return node.type === 'text' && node.attributes === undefined
}
diff --git a/tests/src/Application.njs b/tests/src/Application.njs
index 58691b9e..5bd8201a 100644
--- a/tests/src/Application.njs
+++ b/tests/src/Application.njs
@@ -63,6 +63,7 @@ import LazyComponentLoader from './LazyComponentLoader'
import NestedFolder from './nested/NestedFolder'
import ChildComponentWithoutServerFunctions from './ChildComponentWithoutServerFunctions'
import ObjectEventScope from './ObjectEventScope'
+import SvgSupport from './SvgSupport.njs'
import './Application.css'
class Application extends Nullstack {
@@ -156,6 +157,7 @@ class Application extends Nullstack {
+