Skip to content

Commit 196f49a

Browse files
hbroeryandeu
andauthored
Feature: Shadow DOM without wrapping DIV element (#146)
* webcomponent shadowroot without div container * remove type casting of parentNode * Update browser.yml * Update webComponent.html * Update webComponent.html --------- Co-authored-by: Hauke Broer <[email protected]> Co-authored-by: yandeu <[email protected]>
1 parent 00c32e3 commit 196f49a

File tree

5 files changed

+25
-25
lines changed

5 files changed

+25
-25
lines changed

.github/workflows/browser.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ jobs:
3737
rm -f package.json
3838
rm -f package-lock.json
3939
npm init -y
40-
npm i -D rimraf typescript puppeteer
40+
npm i -D rimraf typescript@5.1.6 puppeteer
4141
npm i -D webpack webpack-cli ts-loader nyc coverage-istanbul-loader
4242
4343
- name: Prepare

src/component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ export class Component<P extends Object = any, S = any> {
114114
// console.log('new: ', this.elements)
115115

116116
// get valid parent node
117-
const parent = oldElements[0].parentElement as HTMLElement
117+
const parent = oldElements[0].parentNode
118118

119119
// make sure we have a parent
120120
if (!parent) console.warn('Component needs a parent element to get updated!')

src/customElementsMode.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,18 +74,11 @@ export const defineAsCustomElements: (
7474
}
7575

7676
private buildEl(contents: any) {
77-
// because nano-jsx update needs parentElement, we need
78-
// to wrap the element in a div when using shadow mode
79-
return h(this.shadowRoot ? 'div' : 'template', null, contents)
77+
return h('template', null, contents)
8078
}
8179

8280
private appendEl(el: any) {
83-
if (this.shadowRoot) {
84-
// el.dataset.wcRoot = true
85-
this.$root.append(el)
86-
} else {
87-
this.$root.append(...el.childNodes)
88-
}
81+
this.$root.append(...el.childNodes)
8982
}
9083

9184
private removeChildren() {

test/browser/webComponent.html

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,23 @@
4343
const myCustomElement = document.querySelector('my-custom-element')
4444
Test.error(myCustomElement.innerHTML === 'invisible', 'Should show text "invisible"')
4545
Test.error(
46-
myCustomElement?.shadowRoot?.innerHTML === '<div><div><h1>title</h1>bye123</div></div>',
46+
myCustomElement?.shadowRoot?.innerHTML === '<div><h1>title</h1>bye123</div>',
4747
'Shadow should contain "title" and "bye123"'
4848
)
49+
50+
// update attribute hello
51+
myCustomElement.setAttribute("hello", 456)
52+
Test.error(
53+
myCustomElement?.shadowRoot?.innerHTML === '<div><h1>title</h1>bye456</div>',
54+
'Shadow should contain "title" and "bye456"'
55+
)
4956
})
5057

5158
describe('slot-test', async () => {
5259
const myCustomElement = document.querySelector('slot-test')
5360
Test.error(myCustomElement.innerHTML === '<span slot="username">John Doe</span>', 'Should show span')
5461
Test.error(
55-
myCustomElement?.shadowRoot?.innerHTML === '<div><p>Hello: <slot name="username"></slot></p></div>',
62+
myCustomElement?.shadowRoot?.innerHTML === '<p>Hello: <slot name="username"></slot></p>',
5663
'Hello: John Doe'
5764
)
5865
})

test/nodejs/customElementsMode.test.tsx

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ test('should render with correct content', async () => {
4040
await wait()
4141

4242
const comp = document.querySelector('nano-test2')
43-
expect(comp?.shadowRoot?.innerHTML).toEqual('<div><div>test text</div></div>')
43+
expect(comp?.shadowRoot?.innerHTML).toEqual('<div>test text</div>')
4444
expect(spy).not.toHaveBeenCalled()
4545
})
4646

@@ -65,7 +65,7 @@ test('should render with props', async () => {
6565
await wait()
6666

6767
const comp = document.querySelector('nano-test3')
68-
expect(comp?.shadowRoot?.innerHTML).toEqual('<div><div>test : fuga</div></div>')
68+
expect(comp?.shadowRoot?.innerHTML).toEqual('<div>test : fuga</div>')
6969
expect(spy).not.toHaveBeenCalled()
7070
})
7171

@@ -90,11 +90,11 @@ test('should update render result with props change', async () => {
9090
await wait()
9191

9292
const comp = document.querySelector('nano-test4')
93-
expect(comp?.shadowRoot?.innerHTML).toEqual('<div><div>test : fuga</div></div>')
93+
expect(comp?.shadowRoot?.innerHTML).toEqual('<div>test : fuga</div>')
9494

9595
document.body.innerHTML = '<nano-test4 value="hoge"></nano-test4>'
9696
const compChanged = document.querySelector('nano-test4')
97-
expect(compChanged?.shadowRoot?.innerHTML).toEqual('<div><div>test : hoge</div></div>')
97+
expect(compChanged?.shadowRoot?.innerHTML).toEqual('<div>test : hoge</div>')
9898
expect(spy).not.toHaveBeenCalled()
9999
})
100100

@@ -123,10 +123,10 @@ test('should change render result with state change', async () => {
123123
await wait()
124124

125125
const comp = document.querySelector('nano-test5')
126-
expect(comp?.shadowRoot?.innerHTML).toEqual('<div><div><div>Counter: 0</div><button>Increment</button></div></div>')
126+
expect(comp?.shadowRoot?.innerHTML).toEqual('<div><div>Counter: 0</div><button>Increment</button></div>')
127127

128128
comp?.shadowRoot?.querySelector('button')?.click()
129-
expect(comp?.shadowRoot?.innerHTML).toEqual('<div><div><div>Counter: 1</div><button>Increment</button></div></div>')
129+
expect(comp?.shadowRoot?.innerHTML).toEqual('<div><div>Counter: 1</div><button>Increment</button></div>')
130130
expect(spy).not.toHaveBeenCalled()
131131
})
132132

@@ -163,17 +163,17 @@ test('should keep state with props change', async () => {
163163

164164
const comp = document.querySelector('nano-test6')
165165
expect(comp?.shadowRoot?.innerHTML).toEqual(
166-
'<div><div><div>Counter: 0</div><div>props: 1</div><button>Increment</button></div></div>'
166+
'<div><div>Counter: 0</div><div>props: 1</div><button>Increment</button></div>'
167167
)
168168

169169
comp?.shadowRoot?.querySelector('button')?.click()
170170
expect(comp?.shadowRoot?.innerHTML).toEqual(
171-
'<div><div><div>Counter: 1</div><div>props: 1</div><button>Increment</button></div></div>'
171+
'<div><div>Counter: 1</div><div>props: 1</div><button>Increment</button></div>'
172172
)
173173
// @ts-ignore
174174
comp.attributes.value?.value = 2
175175
expect(comp?.shadowRoot?.innerHTML).toEqual(
176-
'<div><div><div>Counter: 1</div><div>props: 2</div><button>Increment</button></div></div>'
176+
'<div><div>Counter: 1</div><div>props: 2</div><button>Increment</button></div>'
177177
)
178178
expect(spy).not.toHaveBeenCalled()
179179
})
@@ -190,10 +190,10 @@ test('should render also with functional component', async () => {
190190
await wait()
191191

192192
const comp = document.querySelector('nano-test7')
193-
expect(comp?.shadowRoot?.innerHTML).toEqual('<div><p>hoge</p></div>')
193+
expect(comp?.shadowRoot?.innerHTML).toEqual('<p>hoge</p>')
194194
// @ts-ignore
195195
comp.attributes.value?.value = 'bar'
196-
expect(comp?.shadowRoot?.innerHTML).toEqual('<div><p>bar</p></div>')
196+
expect(comp?.shadowRoot?.innerHTML).toEqual('<p>bar</p>')
197197
expect(spy).not.toHaveBeenCalled()
198198
})
199199

@@ -225,6 +225,6 @@ test('should render also with slot', async () => {
225225
await wait()
226226

227227
const comp = document.querySelector('nano-test8')
228-
expect(comp?.shadowRoot?.innerHTML).toEqual('<div><div><header>nano jsx</header><main><p>hoge</p></main></div></div>')
228+
expect(comp?.shadowRoot?.innerHTML).toEqual('<div><header>nano jsx</header><main><p>hoge</p></main></div>')
229229
expect(spy).not.toHaveBeenCalled()
230230
})

0 commit comments

Comments
 (0)