Skip to content

Commit 26cae85

Browse files
committed
Introduce “UnforgivingHtml” parser.
Goals of the parser: * Tighten control over things like double-quotes & closing tags. * Improve error messaging for malformed markup. * Improve performance.
1 parent d7b3a48 commit 26cae85

File tree

9 files changed

+1546
-274
lines changed

9 files changed

+1546
-274
lines changed

demo/chess/index.js

Lines changed: 62 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,67 @@
11
import XElement from '../../x-element.js';
22

33
class ChessPieceElement extends XElement {
4+
static get styles() {
5+
const styleSheet = new CSSStyleSheet();
6+
styleSheet.replaceSync(`\
7+
:host {
8+
display: block;
9+
width: var(--hello-size, 8rem);
10+
height: var(--hello-size, 8rem);
11+
background-color: cyan;
12+
border-radius: 50%;
13+
margin: 0.25rem;
14+
box-sizing: border-box;
15+
transition-duration: 250ms;
16+
transition-timing-function: cubic-bezier(0.77, 0, 0.175, 1);
17+
transition-property: transform, border;
18+
will-change: transform;
19+
cursor: pointer;
20+
}
21+
22+
#container {
23+
display: flex;
24+
align-items: center;
25+
justify-content: center;
26+
height: 100%;
27+
font-size: calc(var(--hello-size, 8rem) * calc(5/11));
28+
}
29+
30+
:host([rank="\\2655"]) {
31+
border: 4px dotted hsl(120, 100%, 50%);
32+
background-color: yellow;
33+
transform: rotateX(15deg) rotateY(15deg);
34+
}
35+
36+
:host([rank="\\2654"]) {
37+
border: 3px solid hsl(270, 100%, 50%);
38+
background-color: magenta;
39+
color: blue;
40+
transform: rotateX(-10deg) rotateY(-15deg);
41+
}
42+
43+
:host(:not([rank])),
44+
:host([rank=""]) {
45+
background-color: #ccc;
46+
}
47+
48+
:host(:hover) {
49+
border: 3px solid hsl(180, 100%, 50%);
50+
transform: translateZ(-25px);
51+
}
52+
53+
:host(:focus) {
54+
border: 12px solid hsl(90, 100%, 50%);
55+
outline: none;
56+
}
57+
58+
#container:empty::before {
59+
content: '\\265F';
60+
}
61+
`);
62+
return [styleSheet];
63+
}
64+
465
static get properties() {
566
return {
667
rank: {
@@ -17,65 +78,7 @@ class ChessPieceElement extends XElement {
1778

1879
static template(html) {
1980
return ({ rank }) => {
20-
return html`
21-
<style>
22-
:host {
23-
display: block;
24-
width: var(--hello-size, 8rem);
25-
height: var(--hello-size, 8rem);
26-
background-color: cyan;
27-
border-radius: 50%;
28-
margin: 0.25rem;
29-
box-sizing: border-box;
30-
transition-duration: 250ms;
31-
transition-timing-function: cubic-bezier(0.77, 0, 0.175, 1);
32-
transition-property: transform, border;
33-
will-change: transform;
34-
cursor: pointer;
35-
}
36-
37-
#container {
38-
display: flex;
39-
align-items: center;
40-
justify-content: center;
41-
height: 100%;
42-
font-size: calc(var(--hello-size, 8rem) * calc(5/11));
43-
}
44-
45-
:host([rank="\u2655"]) {
46-
border: 4px dotted hsl(120, 100%, 50%);
47-
background-color: yellow;
48-
transform: rotateX(15deg) rotateY(15deg);
49-
}
50-
51-
:host([rank="\u2654"]) {
52-
border: 3px solid hsl(270, 100%, 50%);
53-
background-color: magenta;
54-
color: blue;
55-
transform: rotateX(-10deg) rotateY(-15deg);
56-
}
57-
58-
:host(:not([rank])),
59-
:host([rank=""]) {
60-
background-color: #ccc;
61-
}
62-
63-
:host(:hover) {
64-
border: 3px solid hsl(180, 100%, 50%);
65-
transform: translateZ(-25px);
66-
}
67-
68-
:host(:focus) {
69-
border: 12px solid hsl(90, 100%, 50%);
70-
outline: none;
71-
}
72-
73-
#container:empty::before {
74-
content: '\u265F';
75-
}
76-
</style>
77-
<div id="container">${rank}</div>
78-
`;
81+
return html`<div id="container">${rank}</div>`;
7982
};
8083
}
8184
}

demo/index.js

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,42 +9,45 @@ const logo = `\
99
`;
1010

1111
class HelloElement extends XElement {
12-
static template(html) {
13-
return () => {
14-
return html`
15-
<style>
16-
:host {
17-
display: contents;
18-
}
12+
static get styles() {
13+
const styleSheet = new CSSStyleSheet();
14+
styleSheet.replaceSync(`\
15+
:host {
16+
display: contents;
17+
}
18+
19+
#container {
20+
position: fixed;
21+
--width: 150px;
22+
--height: 150px;
23+
--font-size: 13px;
24+
font-weight: bold;
25+
line-height: calc(var(--font-size) * 1.8);
26+
font-size: var(--font-size);
27+
top: calc(0px - var(--width) / 2);
28+
left: calc(0px - var(--height) / 2);
29+
display: flex;
30+
align-items: center;
31+
justify-content: center;
32+
width: var(--width);
33+
height: var(--height);
34+
transform: translate(calc(0vw - var(--width)), 50vh) rotate(0deg);
35+
opacity: 1;
36+
transform-origin: center;
37+
border-radius: 100vmax;
38+
cursor: default;
39+
}
1940
20-
#container {
21-
position: fixed;
22-
--width: 150px;
23-
--height: 150px;
24-
--font-size: 13px;
25-
font-weight: bold;
26-
line-height: calc(var(--font-size) * 1.8);
27-
font-size: var(--font-size);
28-
top: calc(0px - var(--width) / 2);
29-
left: calc(0px - var(--height) / 2);
30-
display: flex;
31-
align-items: center;
32-
justify-content: center;
33-
width: var(--width);
34-
height: var(--height);
35-
transform: translate(calc(0vw - var(--width)), 50vh) rotate(0deg);
36-
opacity: 1;
37-
transform-origin: center;
38-
border-radius: 100vmax;
39-
cursor: default;
40-
}
41+
#logo {
42+
padding-bottom: var(--font-size);
43+
}
44+
`);
45+
return [styleSheet];
46+
}
4147

42-
#logo {
43-
padding-bottom: var(--font-size);
44-
}
45-
</style>
46-
<div id="container"><pre id="logo">${logo}</pre></div>
47-
`;
48+
static template(html) {
49+
return () => {
50+
return html`<div id="container"><pre id="logo">${logo}</pre></div>`;
4851
};
4952
}
5053

test/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import '../x-template.js';
66

77
// Set a high bar for code coverage!
88
coverage(new URL('../x-element.js', import.meta.url).href, 100);
9-
coverage(new URL('../x-template.js', import.meta.url).href, 100);
9+
10+
// TODO: Increase code coverage to 100 here.
11+
coverage(new URL('../x-template.js', import.meta.url).href, 95);
1012

1113
test('./test-analysis-errors.html');
1214
test('./test-initialization-errors.html');

test/test-computed-properties.js

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,29 @@ import { it, assert } from './x-test.js';
44
let _count = 0;
55

66
class TestElement extends XElement {
7+
static get styles() {
8+
const styleSheet = new CSSStyleSheet();
9+
styleSheet.replaceSync(`\
10+
#calculation {
11+
background-color: lightgreen;
12+
padding: 10px;
13+
}
14+
15+
:host([negative]) #calculation {
16+
background-color: lightcoral;
17+
}
18+
19+
:host([underline]) #calculation {
20+
text-decoration: underline;
21+
}
22+
23+
:host([italic]) #calculation {
24+
font-style: italic;
25+
}
26+
`);
27+
return [styleSheet];
28+
}
29+
730
static get properties() {
831
return {
932
c: {
@@ -84,27 +107,7 @@ class TestElement extends XElement {
84107

85108
static template(html) {
86109
return ({ a, b, c }) => {
87-
return html`
88-
<style>
89-
#calculation {
90-
background-color: lightgreen;
91-
padding: 10px;
92-
}
93-
94-
:host([negative]) #calculation {
95-
background-color: lightcoral;
96-
}
97-
98-
:host([underline]) #calculation {
99-
text-decoration: underline;
100-
}
101-
102-
:host([italic]) #calculation {
103-
font-style: italic;
104-
}
105-
</style>
106-
<span id="calculation">${a} + ${b} = ${c}</span>
107-
`;
110+
return html`<span id="calculation">${a} + ${b} = ${c}</span>`;
108111
};
109112
}
110113
}

test/test-observed-properties.js

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,24 @@ import XElement from '../x-element.js';
22
import { assert, it } from './x-test.js';
33

44
class TestElement extends XElement {
5+
static get styles() {
6+
const styleSheet = new CSSStyleSheet();
7+
styleSheet.replaceSync(`\
8+
:host #container {
9+
transition-property: box-shadow;
10+
transition-duration: 300ms;
11+
transition-timing-function: linear;
12+
box-shadow: 0 0 0 1px black;
13+
padding: 10px;
14+
}
15+
16+
:host([popped]) #container {
17+
box-shadow: 0 0 10px 0 black;
18+
}
19+
`);
20+
return [styleSheet];
21+
}
22+
523
static get properties() {
624
return {
725
a: {
@@ -64,19 +82,6 @@ class TestElement extends XElement {
6482
static template(html) {
6583
return ({ changes }) => {
6684
return html`
67-
<style>
68-
:host #container {
69-
transition-property: box-shadow;
70-
transition-duration: 300ms;
71-
transition-timing-function: linear;
72-
box-shadow: 0 0 0 1px black;
73-
padding: 10px;
74-
}
75-
76-
:host([popped]) #container {
77-
box-shadow: 0 0 10px 0 black;
78-
}
79-
</style>
8085
<div id="container">
8186
<div>Changes:</div>
8287
<ul>

0 commit comments

Comments
 (0)