Skip to content

Commit a0f25e6

Browse files
refactor HTMLTemplateElement implementation to manage template tag creation for shadow roots
1 parent 9d59205 commit a0f25e6

File tree

21 files changed

+305
-324
lines changed

21 files changed

+305
-324
lines changed

docs/components/footer.js

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,36 @@
1-
const template = document.createElement('template');
2-
3-
template.innerHTML = `
4-
<style>
5-
footer {
6-
background-color: var(--accent);
7-
min-height: 30px;
8-
padding: 10px 0;
9-
grid-column: 1 / -1;
10-
text-align: center;
11-
}
1+
class Footer extends HTMLElement {
2+
connectedCallback() {
3+
this.innerHTML = this.render();
4+
}
125

13-
footer p {
14-
margin: 0 auto;
15-
font-weight: bold;
16-
}
6+
render() {
7+
return `
8+
<style>
9+
footer {
10+
background-color: var(--accent);
11+
min-height: 30px;
12+
padding: 10px 0;
13+
grid-column: 1 / -1;
14+
text-align: center;
15+
}
1716
18-
footer a, footer a:visited {
19-
color: #efefef;
20-
text-decoration: none;
21-
}
22-
</style>
17+
footer p {
18+
margin: 0 auto;
19+
font-weight: bold;
20+
}
2321
24-
<footer>
25-
<p>
26-
<a href="https://projectevergreen.github.io">WCC &#9672 Project Evergreen</a>
27-
</p>
28-
</footer>
29-
`;
22+
footer a, footer a:visited {
23+
color: #efefef;
24+
text-decoration: none;
25+
}
26+
</style>
3027
31-
class Footer extends HTMLElement {
32-
connectedCallback() {
33-
this.innerHTML = template.content.textContent;
28+
<footer>
29+
<p>
30+
<a href="https://projectevergreen.github.io">WCC &#9672 Project Evergreen</a>
31+
</p>
32+
</footer>
33+
`;
3434
}
3535
}
3636

docs/components/header.js

Lines changed: 53 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,67 @@
11
import './navigation.js';
22

3-
const template = document.createElement('template');
4-
5-
template.innerHTML = `
6-
<style>
7-
header {
8-
background-color: var(--accent);
9-
grid-column: 1 / -1;
10-
min-height: 150px;
11-
}
3+
class Header extends HTMLElement {
4+
connectedCallback() {
5+
this.innerHTML = this.render();
6+
}
127

13-
header .social {
14-
text-align: right;
15-
padding: 10px 10px 0 0;
16-
}
8+
render() {
9+
return `
10+
<style>
11+
header {
12+
background-color: var(--accent);
13+
grid-column: 1 / -1;
14+
min-height: 150px;
15+
}
1716
18-
header .social img{
19-
margin-top: 1%;
20-
}
17+
header .social {
18+
text-align: right;
19+
padding: 10px 10px 0 0;
20+
}
2121
22-
header .logo {
23-
width: 15%;
24-
filter: drop-shadow(0 0 0.75rem white);
25-
}
22+
header .social img{
23+
margin-top: 1%;
24+
}
2625
27-
header img.github-badge {
28-
float: right;
29-
display: inline-block;
30-
padding: 10px;
31-
align-items: top;
32-
}
26+
header .logo {
27+
width: 15%;
28+
filter: drop-shadow(0 0 0.75rem white);
29+
}
3330
34-
header div.container {
35-
max-width: 1200px;
36-
margin: auto;
37-
}
38-
</style>
31+
header img.github-badge {
32+
float: right;
33+
display: inline-block;
34+
padding: 10px;
35+
align-items: top;
36+
}
3937
40-
<header>
41-
<div class="container">
42-
<div>
43-
<a href="/">
44-
<img src="/assets/wcc-logo.png" alt="WCC logo" class="logo"/>
45-
</a>
38+
header div.container {
39+
max-width: 1200px;
40+
margin: auto;
41+
}
42+
</style>
4643
47-
<a href="https://github.com/ProjectEvergreen/wcc" class="social">
48-
<img
49-
src="https://img.shields.io/github/stars/ProjectEvergreen/wcc.svg?style=social&logo=github&label=github"
50-
alt="WCC GitHub badge"
51-
width="135px"
52-
class="github-badge"
53-
/>
54-
</a>
55-
</div>
44+
<header>
45+
<div class="container">
46+
<div>
47+
<a href="/">
48+
<img src="/assets/wcc-logo.png" alt="WCC logo" class="logo"/>
49+
</a>
5650
57-
<wcc-navigation></wcc-navigation>
58-
</div>
59-
</header>
60-
`;
51+
<a href="https://github.com/ProjectEvergreen/wcc" class="social">
52+
<img
53+
src="https://img.shields.io/github/stars/ProjectEvergreen/wcc.svg?style=social&logo=github&label=github"
54+
alt="WCC GitHub badge"
55+
width="135px"
56+
class="github-badge"
57+
/>
58+
</a>
59+
</div>
6160
62-
class Header extends HTMLElement {
63-
connectedCallback() {
64-
this.innerHTML = template.content.textContent;
61+
<wcc-navigation></wcc-navigation>
62+
</div>
63+
</header>
64+
`;
6565
}
6666
}
6767

docs/components/navigation.js

Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,40 @@
1-
// intentionally nested in the assets/ directory to test wcc nested dependency resolution logic
2-
const template = document.createElement('template');
3-
4-
template.innerHTML = `
5-
<style>
6-
nav ul {
7-
list-style-type: none;
8-
overflow: auto;
9-
grid-column: 1 / -1;
10-
width: 90%;
11-
}
1+
class Navigation extends HTMLElement {
2+
connectedCallback() {
3+
this.innerHTML = this.render();
4+
}
125

13-
nav ul li {
14-
float: left;
15-
width: 33.3%;
16-
text-align: center;
17-
}
6+
render() {
7+
return `
8+
<style>
9+
nav ul {
10+
list-style-type: none;
11+
overflow: auto;
12+
grid-column: 1 / -1;
13+
width: 90%;
14+
}
1815
19-
nav ul li a, nav ul li a:visited {
20-
display: inline-block;
21-
color: #efefef;
22-
min-height: 48px;
23-
font-size: 2.5rem;
24-
}
25-
</style>
16+
nav ul li {
17+
float: left;
18+
width: 33.3%;
19+
text-align: center;
20+
}
2621
27-
<nav>
28-
<ul>
29-
<li><a href="/">Home</a></li>
30-
<li><a href="/docs">Docs</a></li>
31-
<li><a href="/examples">Examples</a></li>
32-
</ul>
33-
</nav>
34-
`;
22+
nav ul li a, nav ul li a:visited {
23+
display: inline-block;
24+
color: #efefef;
25+
min-height: 48px;
26+
font-size: 2.5rem;
27+
}
28+
</style>
3529
36-
class Navigation extends HTMLElement {
37-
connectedCallback() {
38-
this.innerHTML = template.content.textContent;
30+
<nav>
31+
<ul>
32+
<li><a href="/">Home</a></li>
33+
<li><a href="/docs">Docs</a></li>
34+
<li><a href="/examples">Examples</a></li>
35+
</ul>
36+
</nav>
37+
`
3938
}
4039
}
4140

docs/layout.js

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,43 @@
11
import './components/footer.js';
22
import './components/header.js';
33

4-
const template = document.createElement('template');
5-
6-
template.innerHTML = `
7-
<style>
8-
:root {
9-
--accent: #367588;
10-
}
11-
12-
body {
13-
display: flex;
14-
flex-direction: column;
15-
}
16-
17-
main {
18-
max-width: 1200px;
19-
margin: 20px auto;
20-
width: 100%;
21-
padding: 0 1rem;
22-
}
23-
24-
a:visited {
25-
color: var(--accent);
26-
}
27-
</style>
28-
29-
<wcc-header></wcc-header>
30-
31-
<main>
32-
<slot name="content"></slot>
33-
</main>
34-
35-
<wcc-footer></wcc-footer>
36-
`;
37-
384
class Layout extends HTMLElement {
395
connectedCallback() {
40-
this.innerHTML = template.content.textContent;
6+
this.innerHTML = this.render();
7+
}
8+
9+
render() {
10+
return `
11+
<style>
12+
:root {
13+
--accent: #367588;
14+
}
15+
16+
body {
17+
display: flex;
18+
flex-direction: column;
19+
}
20+
21+
main {
22+
max-width: 1200px;
23+
margin: 20px auto;
24+
width: 100%;
25+
padding: 0 1rem;
26+
}
27+
28+
a:visited {
29+
color: var(--accent);
30+
}
31+
</style>
32+
33+
<wcc-header></wcc-header>
34+
35+
<main>
36+
<slot name="content"></slot>
37+
</main>
38+
39+
<wcc-footer></wcc-footer>
40+
`;
4141
}
4242
}
4343

src/dom-shim.js

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ class EventTarget { }
33

44
// https://developer.mozilla.org/en-US/docs/Web/API/Node
55
// EventTarget <- Node
6+
// TODO should be an interface?
67
class Node extends EventTarget {
78
constructor() {
89
super();
@@ -15,7 +16,7 @@ class Node extends EventTarget {
1516
}
1617

1718
appendChild(node) {
18-
this.innerHTML = this.innerHTML ? this.innerHTML += node.textContent : node.textContent;
19+
this.innerHTML = this.innerHTML ? this.innerHTML += node.innerHTML : node.innerHTML;
1920
}
2021
}
2122

@@ -63,14 +64,9 @@ class HTMLElement extends Element {
6364
}
6465

6566
// https://github.com/mfreed7/declarative-shadow-dom/blob/master/README.md#serialization
67+
// eslint-disable-next-line
6668
getInnerHTML(options = {}) {
67-
return options.includeShadowRoots
68-
? `
69-
<template shadowroot="${this.shadowRoot.mode}">
70-
${this.shadowRoot.innerHTML}
71-
</template>
72-
`
73-
: this.shadowRoot.innerHTML;
69+
return this.shadowRoot.innerHTML;
7470
}
7571
}
7672

@@ -101,11 +97,20 @@ class HTMLTemplateElement extends HTMLElement {
10197
super();
10298
// console.debug('HTMLTemplateElement constructor');
10399

104-
this.content = new DocumentFragment(this.innerHTML);
100+
this.content = new DocumentFragment();
105101
}
106102

103+
// TODO open vs closed shadow root
107104
set innerHTML(html) {
108-
this.content.textContent = html;
105+
this.content.innerHTML = `
106+
<template shadowroot="open">
107+
${html}
108+
</template>
109+
`;
110+
}
111+
112+
get innerHTML() {
113+
return this.content && this.content.innerHTML ? this.content.innerHTML : undefined;
109114
}
110115
}
111116

0 commit comments

Comments
 (0)