Skip to content

Commit 73df30c

Browse files
committed
✨ svg support
1 parent 7b5956e commit 73df30c

File tree

6 files changed

+83
-12
lines changed

6 files changed

+83
-12
lines changed

client/render.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { anchorableElement } from './anchorableNode'
55
import { generateCallback, generateSubject } from './events'
66
import { ref } from './ref'
77

8-
export default function render(node, options) {
8+
export default function render(node, isSvg = false) {
99
if (isFalse(node) || node.type === 'head') {
1010
node.element = document.createComment('')
1111
return node.element
@@ -16,9 +16,8 @@ export default function render(node, options) {
1616
return node.element
1717
}
1818

19-
const svg = (options && options.svg) || node.type === 'svg'
20-
21-
if (svg) {
19+
isSvg = isSvg || node.type === 'svg'
20+
if (isSvg) {
2221
node.element = document.createElementNS('http://www.w3.org/2000/svg', node.type)
2322
} else {
2423
node.element = document.createElement(node.type)
@@ -58,7 +57,7 @@ export default function render(node, options) {
5857

5958
if (!node.attributes.html) {
6059
for (let i = 0; i < node.children.length; i++) {
61-
const child = render(node.children[i], { svg })
60+
const child = render(node.children[i], isSvg)
6261
node.element.appendChild(child)
6362
}
6463

client/rerender.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,16 +100,18 @@ function updateHeadChildren(currentChildren, nextChildren) {
100100
}
101101
}
102102

103-
function _rerender(current, next) {
103+
function _rerender(current, next, isParentSvg = false) {
104104
const selector = current.element
105105
next.element = current.element
106106

107107
if (isFalse(current) && isFalse(next)) {
108108
return
109109
}
110110

111+
const isSvg = isParentSvg || next.type === 'svg'
112+
111113
if (current.type !== next.type) {
112-
const nextSelector = render(next)
114+
const nextSelector = render(next, isSvg)
113115
selector.replaceWith(nextSelector)
114116
return
115117
}
@@ -132,22 +134,22 @@ function _rerender(current, next) {
132134
const limit = Math.max(current.children.length, next.children.length)
133135
if (next.children.length > current.children.length) {
134136
for (let i = 0; i < current.children.length; i++) {
135-
_rerender(current.children[i], next.children[i])
137+
_rerender(current.children[i], next.children[i], isSvg)
136138
}
137139
for (let i = current.children.length; i < next.children.length; i++) {
138-
const nextSelector = render(next.children[i])
140+
const nextSelector = render(next.children[i], isSvg)
139141
selector.appendChild(nextSelector)
140142
}
141143
} else if (current.children.length > next.children.length) {
142144
for (let i = 0; i < next.children.length; i++) {
143-
_rerender(current.children[i], next.children[i])
145+
_rerender(current.children[i], next.children[i], isSvg)
144146
}
145147
for (let i = current.children.length - 1; i >= next.children.length; i--) {
146148
selector.childNodes[i].remove()
147149
}
148150
} else {
149151
for (let i = limit - 1; i > -1; i--) {
150-
_rerender(current.children[i], next.children[i])
152+
_rerender(current.children[i], next.children[i], isSvg)
151153
}
152154
}
153155
}

shared/nodes.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,5 @@ export function isFunction(node) {
1818
}
1919

2020
export function isText(node) {
21-
return node.type === 'text'
21+
return node.type === 'text' && node.attributes === undefined
2222
}

tests/src/Application.njs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ import LazyComponentLoader from './LazyComponentLoader'
6363
import NestedFolder from './nested/NestedFolder'
6464
import ChildComponentWithoutServerFunctions from './ChildComponentWithoutServerFunctions'
6565
import ObjectEventScope from './ObjectEventScope'
66+
import SvgSupport from './SvgSupport.njs'
6667
import './Application.css'
6768

6869
class Application extends Nullstack {
@@ -156,6 +157,7 @@ class Application extends Nullstack {
156157
<LazyComponent route="/lazy-importer" prop="works" />
157158
<ChildComponentWithoutServerFunctions route="/child-component-without-server-functions" />
158159
<ObjectEventScope route="/object-event-scope" />
160+
<SvgSupport route="/svg-support" />
159161
<ErrorPage route="*" />
160162
</body>
161163
)

tests/src/SvgSupport.njs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import Nullstack from 'nullstack';
2+
3+
function Close({ size }) {
4+
return (
5+
<svg width={size} height={size} viewBox="0 0 482 482">
6+
<path d="M124 124L358 358" stroke="#000" stroke-width="70.2055" stroke-linecap="round" stroke-linejoin="round" />
7+
<path d="M358 124L124 358" stroke="#000" stroke-width="70.2055" stroke-linecap="round" stroke-linejoin="round" />
8+
</svg>
9+
)
10+
}
11+
12+
function Hamburger({ size }) {
13+
return (
14+
<svg width={size} height={size} viewBox="0 0 482 482">
15+
<path d="M92.5 150H386.5" stroke="#000" stroke-width="42" stroke-linecap="round" stroke-linejoin="round" />
16+
<path d="M92.5 241H386.5" stroke="#000" stroke-width="42" stroke-linecap="round" stroke-linejoin="round" />
17+
<path d="M92.5 332H386.5" stroke="#000" stroke-width="42" stroke-linecap="round" stroke-linejoin="round" />
18+
</svg>
19+
)
20+
}
21+
22+
class SvgSupport extends Nullstack {
23+
24+
open = false
25+
visible = false
26+
27+
render() {
28+
return (
29+
<div>
30+
<svg viewBox="0 0 240 80" xmlns="http://www.w3.org/2000/svg">
31+
<text x="20" y="35" class="small">I</text>
32+
<text x="40" y="35" class="heavy">love</text>
33+
<text x="55" y="55" class="small">my</text>
34+
<text x="60" y="55" class="tiny">cat!</text>
35+
</svg>
36+
{this.open ? <Close size={30} /> : <Hamburger size={30} />}
37+
<button onclick={{open: !this.open}}> toggle </button>
38+
{this.visible && <Hamburger size={69} />}
39+
<button onclick={{visible: !this.visible}}> show </button>
40+
</div>
41+
)
42+
}
43+
44+
}
45+
46+
export default SvgSupport;

tests/src/SvgSupport.test.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
describe('SvgSupport', () => {
2+
beforeEach(async () => {
3+
await page.goto('http://localhost:6969/svg-support')
4+
await page.waitForSelector('[data-hydrated]')
5+
})
6+
7+
test('svg can render text', async () => {
8+
expect(true).toBeTruthy()
9+
})
10+
11+
test('svg can add new paths while rerendering', async () => {
12+
expect(true).toBeTruthy()
13+
})
14+
15+
test('svg can render in short circuit statements', async () => {
16+
expect(true).toBeTruthy()
17+
})
18+
19+
test('svg can render in ternary statements', async () => {
20+
expect(true).toBeTruthy()
21+
})
22+
})

0 commit comments

Comments
 (0)