Skip to content

Commit 8a988f4

Browse files
authored
fix: bracket mismatch issue (#108)
1 parent 2bab580 commit 8a988f4

13 files changed

+158
-76
lines changed

.changeset/tidy-moles-train.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"htmljs-parser": patch
3+
---
4+
5+
Fix issue where parser would sometimes not consume enough characters and cause a bracket mismatch

package-lock.json

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,119 @@
1-
1╭─ <foo onclick(event) {
2-
│ │ │ ││ │╰─ attrMethod.body.value " \n console.log(\"hello\"); \n event.preventDefault();\n"
3-
│ │ │ ││ ╰─ attrMethod.body "{ \n console.log(\"hello\"); \n event.preventDefault();\n}"
1+
1╭─ <foo onclick(event){}/>
2+
│ │ │ ││ ││╰─ openTagEnd:selfClosed "/>"
3+
│ │ │ ││ │╰─ attrMethod.body.value
4+
│ │ │ ││ ╰─ attrMethod.body "{}"
45
│ │ │ │╰─ attrMethod.params.value "event"
56
│ │ │ ├─ attrMethod.params "(event)"
6-
│ │ │ ╰─ attrMethod "(event) { \n console.log(\"hello\"); \n event.preventDefault();\n}"
7+
│ │ │ ╰─ attrMethod "(event){}"
78
│ │ ╰─ attrName "onclick"
89
╰─ ╰─ tagName "foo"
9-
2├─ console.log("hello");
10-
3├─ event.preventDefault();
11-
4╭─ }/>
12-
╰─ ╰─ openTagEnd:selfClosed "/>"
13-
5├─
14-
6╭─ <foo onclick (event) {
15-
│ │ │ ││ │╰─ attrMethod.body.value " \n console.log(\"hello\"); \n event.preventDefault();\n"
16-
│ │ │ ││ ╰─ attrMethod.body "{ \n console.log(\"hello\"); \n event.preventDefault();\n}"
17-
│ │ │ │╰─ attrMethod.params.value "event"
18-
│ │ │ ├─ attrMethod.params "(event)"
19-
│ │ │ ╰─ attrMethod "(event) { \n console.log(\"hello\"); \n event.preventDefault();\n}"
10+
2├─
11+
3╭─ <foo onclick(event){
12+
│ │ │ ││ │╰─ attrMethod.body.value " \n console.log(\"hello\"); \n event.preventDefault();\n"
13+
│ │ │ ││ ╰─ attrMethod.body "{ \n console.log(\"hello\"); \n event.preventDefault();\n}"
14+
│ │ │ │╰─ attrMethod.params.value "event"
15+
│ │ │ ├─ attrMethod.params "(event)"
16+
│ │ │ ╰─ attrMethod "(event){ \n console.log(\"hello\"); \n event.preventDefault();\n}"
2017
│ │ ╰─ attrName "onclick"
2118
╰─ ╰─ tagName "foo"
22-
7├─ console.log("hello");
23-
8├─ event.preventDefault();
24-
9╭─ }/>
19+
4├─ console.log("hello");
20+
5├─ event.preventDefault();
21+
6╭─ }/>
2522
╰─ ╰─ openTagEnd:selfClosed "/>"
26-
10├─
27-
11╭─ <foo(event) {
23+
7├─
24+
8╭─ <foo onclick(event) {
25+
│ │ │ ││ │╰─ attrMethod.body.value " \n console.log(\"hello\"); \n event.preventDefault();\n"
26+
│ │ │ ││ ╰─ attrMethod.body "{ \n console.log(\"hello\"); \n event.preventDefault();\n}"
27+
│ │ │ │╰─ attrMethod.params.value "event"
28+
│ │ │ ├─ attrMethod.params "(event)"
29+
│ │ │ ╰─ attrMethod "(event) { \n console.log(\"hello\"); \n event.preventDefault();\n}"
30+
│ │ ╰─ attrName "onclick"
31+
╰─ ╰─ tagName "foo"
32+
9├─ console.log("hello");
33+
10├─ event.preventDefault();
34+
11╭─ }/>
35+
╰─ ╰─ openTagEnd:selfClosed "/>"
36+
12├─
37+
13╭─ <foo onclick (event) {
38+
│ │ │ ││ │╰─ attrMethod.body.value " \n console.log(\"hello\"); \n event.preventDefault();\n"
39+
│ │ │ ││ ╰─ attrMethod.body "{ \n console.log(\"hello\"); \n event.preventDefault();\n}"
40+
│ │ │ │╰─ attrMethod.params.value "event"
41+
│ │ │ ├─ attrMethod.params "(event)"
42+
│ │ │ ╰─ attrMethod "(event) { \n console.log(\"hello\"); \n event.preventDefault();\n}"
43+
│ │ ╰─ attrName "onclick"
44+
╰─ ╰─ tagName "foo"
45+
14├─ console.log("hello");
46+
15├─ event.preventDefault();
47+
16╭─ }/>
48+
╰─ ╰─ openTagEnd:selfClosed "/>"
49+
17├─
50+
18╭─ <foo(event){
51+
│ │ ││ │╰─ attrMethod.body.value " \n console.log(\"hello\"); \n event.preventDefault();\n"
52+
│ │ ││ ╰─ attrMethod.body "{ \n console.log(\"hello\"); \n event.preventDefault();\n}"
53+
│ │ │╰─ attrMethod.params.value "event"
54+
│ │ ├─ attrMethod.params "(event)"
55+
│ │ ├─ attrMethod "(event){ \n console.log(\"hello\"); \n event.preventDefault();\n}"
56+
│ │ ╰─ attrName
57+
╰─ ╰─ tagName "foo"
58+
19├─ console.log("hello");
59+
20├─ event.preventDefault();
60+
21╭─ }/>
61+
╰─ ╰─ openTagEnd:selfClosed "/>"
62+
22├─
63+
23╭─ <foo(event) {
2864
│ │ ││ │╰─ attrMethod.body.value " \n console.log(\"hello\"); \n event.preventDefault();\n"
2965
│ │ ││ ╰─ attrMethod.body "{ \n console.log(\"hello\"); \n event.preventDefault();\n}"
3066
│ │ │╰─ attrMethod.params.value "event"
3167
│ │ ├─ attrMethod.params "(event)"
3268
│ │ ├─ attrMethod "(event) { \n console.log(\"hello\"); \n event.preventDefault();\n}"
3369
│ │ ╰─ attrName
3470
╰─ ╰─ tagName "foo"
35-
12├─ console.log("hello");
36-
13├─ event.preventDefault();
37-
14╭─ }/>
71+
24├─ console.log("hello");
72+
25├─ event.preventDefault();
73+
26╭─ }/>
3874
╰─ ╰─ openTagEnd:selfClosed "/>"
39-
15├─
40-
16╭─ <foo (event) {
75+
27├─
76+
28╭─ <foo (event) {
4177
│ │ ││ │╰─ attrMethod.body.value " \n console.log(\"hello\"); \n event.preventDefault();\n"
4278
│ │ ││ ╰─ attrMethod.body "{ \n console.log(\"hello\"); \n event.preventDefault();\n}"
4379
│ │ │╰─ attrMethod.params.value "event"
4480
│ │ ├─ attrMethod.params "(event)"
4581
│ │ ├─ attrMethod "(event) { \n console.log(\"hello\"); \n event.preventDefault();\n}"
4682
│ │ ╰─ attrName
4783
╰─ ╰─ tagName "foo"
48-
17├─ console.log("hello");
49-
18├─ event.preventDefault();
50-
19╭─ }/>
84+
29├─ console.log("hello");
85+
30├─ event.preventDefault();
86+
31╭─ }/>
5187
╰─ ╰─ openTagEnd:selfClosed "/>"
52-
20├─
53-
21╭─ foo onclick(event) {
88+
32├─
89+
33╭─ foo onclick(event){
90+
│ │ │ ││ │╰─ attrMethod.body.value " \n console.log(\"hello\"); \n event.preventDefault();\n"
91+
│ │ │ ││ ╰─ attrMethod.body "{ \n console.log(\"hello\"); \n event.preventDefault();\n}"
92+
│ │ │ │╰─ attrMethod.params.value "event"
93+
│ │ │ ├─ attrMethod.params "(event)"
94+
│ │ │ ╰─ attrMethod "(event){ \n console.log(\"hello\"); \n event.preventDefault();\n}"
95+
│ │ ╰─ attrName "onclick"
96+
╰─ ╰─ tagName "foo"
97+
34├─ console.log("hello");
98+
35├─ event.preventDefault();
99+
36├─ }
100+
37╭─
101+
╰─ ╰─ openTagEnd
102+
38╭─ foo onclick(event) {
54103
│ │ │ ││ │╰─ attrMethod.body.value " \n console.log(\"hello\"); \n event.preventDefault();\n"
55104
│ │ │ ││ ╰─ attrMethod.body "{ \n console.log(\"hello\"); \n event.preventDefault();\n}"
56105
│ │ │ │╰─ attrMethod.params.value "event"
57106
│ │ │ ├─ attrMethod.params "(event)"
58107
│ │ │ ╰─ attrMethod "(event) { \n console.log(\"hello\"); \n event.preventDefault();\n}"
59108
│ │ ╰─ attrName "onclick"
109+
│ ├─ closeTag(foo)
60110
╰─ ╰─ tagName "foo"
61-
22├─ console.log("hello");
62-
23├─ event.preventDefault();
63-
24├─ }
64-
25╭─
111+
39├─ console.log("hello");
112+
40├─ event.preventDefault();
113+
41├─ }
114+
42╭─
65115
╰─ ╰─ openTagEnd
66-
26╭─ foo onclick (event) {
116+
43╭─ foo onclick (event) {
67117
│ │ │ ││ │╰─ attrMethod.body.value " \n console.log(\"hello\"); \n event.preventDefault();\n"
68118
│ │ │ ││ ╰─ attrMethod.body "{ \n console.log(\"hello\"); \n event.preventDefault();\n}"
69119
│ │ │ │╰─ attrMethod.params.value "event"
@@ -72,12 +122,26 @@
72122
│ │ ╰─ attrName "onclick"
73123
│ ├─ closeTag(foo)
74124
╰─ ╰─ tagName "foo"
75-
27├─ console.log("hello");
76-
28├─ event.preventDefault();
77-
29├─ }
78-
30╭─
125+
44├─ console.log("hello");
126+
45├─ event.preventDefault();
127+
46├─ }
128+
47╭─
129+
╰─ ╰─ openTagEnd
130+
48╭─ foo(event){
131+
│ │ ││ │╰─ attrMethod.body.value " \n console.log(\"hello\"); \n event.preventDefault();\n"
132+
│ │ ││ ╰─ attrMethod.body "{ \n console.log(\"hello\"); \n event.preventDefault();\n}"
133+
│ │ │╰─ attrMethod.params.value "event"
134+
│ │ ├─ attrMethod.params "(event)"
135+
│ │ ├─ attrMethod "(event){ \n console.log(\"hello\"); \n event.preventDefault();\n}"
136+
│ │ ╰─ attrName
137+
│ ├─ closeTag(foo)
138+
╰─ ╰─ tagName "foo"
139+
49├─ console.log("hello");
140+
50├─ event.preventDefault();
141+
51├─ }
142+
52╭─
79143
╰─ ╰─ openTagEnd
80-
31╭─ foo(event) {
144+
53╭─ foo(event) {
81145
│ │ ││ │╰─ attrMethod.body.value " \n console.log(\"hello\"); \n event.preventDefault();\n"
82146
│ │ ││ ╰─ attrMethod.body "{ \n console.log(\"hello\"); \n event.preventDefault();\n}"
83147
│ │ │╰─ attrMethod.params.value "event"
@@ -86,12 +150,12 @@
86150
│ │ ╰─ attrName
87151
│ ├─ closeTag(foo)
88152
╰─ ╰─ tagName "foo"
89-
32├─ console.log("hello");
90-
33├─ event.preventDefault();
91-
34├─ }
92-
35╭─
153+
54├─ console.log("hello");
154+
55├─ event.preventDefault();
155+
56├─ }
156+
57╭─
93157
╰─ ╰─ openTagEnd
94-
36╭─ foo (event) {
158+
58╭─ foo (event) {
95159
│ │ ││ │╰─ attrMethod.body.value " \n console.log(\"hello\"); \n event.preventDefault();\n"
96160
│ │ ││ ╰─ attrMethod.body "{ \n console.log(\"hello\"); \n event.preventDefault();\n}"
97161
│ │ │╰─ attrMethod.params.value "event"
@@ -100,8 +164,8 @@
100164
│ │ ╰─ attrName
101165
│ ├─ closeTag(foo)
102166
╰─ ╰─ tagName "foo"
103-
37├─ console.log("hello");
104-
38├─ event.preventDefault();
105-
39╭─ }
167+
59├─ console.log("hello");
168+
60├─ event.preventDefault();
169+
61╭─ }
106170
│ ├─ closeTag(foo)
107171
╰─ ╰─ openTagEnd

src/__tests__/fixtures/attr-method-shorthand/input.marko

+22
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
<foo onclick(event){}/>
2+
3+
<foo onclick(event){
4+
console.log("hello");
5+
event.preventDefault();
6+
}/>
7+
18
<foo onclick(event) {
29
console.log("hello");
310
event.preventDefault();
@@ -8,6 +15,11 @@
815
event.preventDefault();
916
}/>
1017

18+
<foo(event){
19+
console.log("hello");
20+
event.preventDefault();
21+
}/>
22+
1123
<foo(event) {
1224
console.log("hello");
1325
event.preventDefault();
@@ -18,6 +30,11 @@
1830
event.preventDefault();
1931
}/>
2032

33+
foo onclick(event){
34+
console.log("hello");
35+
event.preventDefault();
36+
}
37+
2138
foo onclick(event) {
2239
console.log("hello");
2340
event.preventDefault();
@@ -28,6 +45,11 @@ foo onclick (event) {
2845
event.preventDefault();
2946
}
3047

48+
foo(event){
49+
console.log("hello");
50+
event.preventDefault();
51+
}
52+
3153
foo(event) {
3254
console.log("hello");
3355
event.preventDefault();

src/__tests__/fixtures/testing/__snapshots__/testing.expected.txt

-7
This file was deleted.

src/__tests__/fixtures/testing/input.marko

-1
This file was deleted.

src/states/ATTRIBUTE.ts

+4-5
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ export const ATTRIBUTE: StateDefinition<AttrMeta> = {
9090
(code === CODE.PERIOD && this.lookAheadFor(".."))
9191
) {
9292
attr.valueStart = this.pos;
93+
this.forward = 0;
9394

9495
if (code === CODE.COLON) {
9596
ensureAttrName(this, attr);
@@ -111,31 +112,29 @@ export const ATTRIBUTE: StateDefinition<AttrMeta> = {
111112
expr.terminator = this.isConcise
112113
? CONCISE_VALUE_TERMINATORS
113114
: HTML_VALUE_TERMINATORS;
114-
115-
this.pos--;
116115
} else if (code === CODE.OPEN_PAREN) {
117116
ensureAttrName(this, attr);
118117
attr.stage = ATTR_STAGE.ARGUMENT;
119118
this.pos++; // skip (
119+
this.forward = 0;
120120
this.enterState(STATE.EXPRESSION).terminator = CODE.CLOSE_PAREN;
121-
this.pos--;
122121
} else if (code === CODE.OPEN_CURLY_BRACE && attr.args) {
123122
ensureAttrName(this, attr);
124123
attr.stage = ATTR_STAGE.BLOCK;
125124
this.pos++; // skip {
125+
this.forward = 0;
126126
const expr = this.enterState(STATE.EXPRESSION);
127127
expr.terminatedByWhitespace = false;
128128
expr.terminator = CODE.CLOSE_CURLY_BRACE;
129-
this.pos--;
130129
} else if (attr.stage === ATTR_STAGE.UNKNOWN) {
131130
attr.stage = ATTR_STAGE.NAME;
131+
this.forward = 0;
132132
const expr = this.enterState(STATE.EXPRESSION);
133133
expr.terminatedByWhitespace = true;
134134
expr.skipOperators = true;
135135
expr.terminator = this.isConcise
136136
? CONCISE_NAME_TERMINATORS
137137
: HTML_NAME_TERMINATORS;
138-
this.pos--;
139138
} else {
140139
this.exitState();
141140
}

src/states/BEGIN_DELIMITED_HTML_BLOCK.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ export const BEGIN_DELIMITED_HTML_BLOCK: StateDefinition<DelimitedHTMLBlockMeta>
3939
const startPos = this.pos;
4040
if (!this.consumeWhitespaceOnLine()) {
4141
this.pos = startPos + 1;
42+
this.forward = 0;
4243
this.beginHtmlBlock(undefined, true);
43-
this.pos--;
4444
}
4545
}
4646
},

src/states/CONCISE_HTML_CONTENT.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ export const CONCISE_HTML_CONTENT: StateDefinition = {
119119
}
120120

121121
this.enterState(STATE.OPEN_TAG);
122-
this.pos--; // START_TAG_NAME expects to start at the first character
122+
this.forward = 0; // START_TAG_NAME expects to start at the first character
123123
}
124124
},
125125

src/states/INLINE_SCRIPT.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,17 @@ export const INLINE_SCRIPT: StateDefinition<ScriptletMeta> = {
3838
eof() {},
3939

4040
char(code, inlineScript) {
41+
this.forward = 0;
42+
4143
if (code === CODE.OPEN_CURLY_BRACE) {
4244
inlineScript.block = true;
4345
this.pos++; // skip {
4446
const expr = this.enterState(STATE.EXPRESSION);
4547
expr.terminator = CODE.CLOSE_CURLY_BRACE;
4648
expr.skipOperators = true;
47-
this.pos--;
4849
} else {
4950
const expr = this.enterState(STATE.EXPRESSION);
5051
expr.terminatedByEOL = true;
51-
this.pos--;
5252
}
5353
},
5454

0 commit comments

Comments
 (0)