Skip to content

Commit

Permalink
fix: ensure unary expression continuation is a word boundary
Browse files Browse the repository at this point in the history
  • Loading branch information
DylanPiercey committed Mar 11, 2023
1 parent 785a593 commit 72b3379
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/stale-impalas-visit.md
@@ -0,0 +1,5 @@
---
"htmljs-parser": patch
---

Fix regression where the parser would continue unary keyword expressions even if the keyword was inside a word boundary. Eg `<div class=thing_new x>` would cause the parser to see the expression as `thing_` and `new x`.
@@ -0,0 +1,80 @@
1╭─ tag a = class b {}
│ │ │ │ ╰─ attrValue.value "class b {}"
│ │ │ ╰─ attrValue "= class b {}"
│ │ ╰─ attrName
╰─ ╰─ tagName "tag"
2╭─
╰─ ╰─ openTagEnd
3╭─ tag a = class, b
│ │ │ │ │ ╰─ attrName
│ │ │ │ ╰─ attrValue.value "class"
│ │ │ ╰─ attrValue "= class"
│ │ ╰─ attrName
│ ├─ closeTagEnd(tag)
╰─ ╰─ tagName "tag"
4╭─
╰─ ╰─ openTagEnd
5╭─ <tag a = class></tag>
│ ││ │ │ │ ││ │ ╰─ closeTagEnd(tag)
│ ││ │ │ │ ││ ╰─ closeTagName "tag"
│ ││ │ │ │ │╰─ closeTagStart "</"
│ ││ │ │ │ ╰─ openTagEnd
│ ││ │ │ ╰─ attrValue.value "class"
│ ││ │ ╰─ attrValue "= class"
│ ││ ╰─ attrName
│ │╰─ tagName "tag"
│ ├─ closeTagEnd(tag)
╰─ ╰─ openTagStart
6├─
7╭─ <tag a = class/>
│ ││ │ │ │ ╰─ openTagEnd:selfClosed "/>"
│ ││ │ │ ╰─ attrValue.value "class"
│ ││ │ ╰─ attrValue "= class"
│ ││ ╰─ attrName
│ │╰─ tagName "tag"
╰─ ╰─ openTagStart
8├─
9╭─ tag a = classthing b
│ │ │ │ │ ╰─ attrName
│ │ │ │ ╰─ attrValue.value "classthing"
│ │ │ ╰─ attrValue "= classthing"
│ │ ╰─ attrName
╰─ ╰─ tagName "tag"
10╭─
╰─ ╰─ openTagEnd
11╭─ tag a = testclass b
│ │ │ │ │ ╰─ attrName
│ │ │ │ ╰─ attrValue.value "testclass"
│ │ │ ╰─ attrValue "= testclass"
│ │ ╰─ attrName
│ ├─ closeTagEnd(tag)
╰─ ╰─ tagName "tag"
12╭─
╰─ ╰─ openTagEnd
13╭─ tag a = test_class b
│ │ │ │ │ ╰─ attrName
│ │ │ │ ╰─ attrValue.value "test_class"
│ │ │ ╰─ attrValue "= test_class"
│ │ ╰─ attrName
│ ├─ closeTagEnd(tag)
╰─ ╰─ tagName "tag"
14╭─
╰─ ╰─ openTagEnd
15╭─ tag a = test$class b
│ │ │ │ │ ╰─ attrName
│ │ │ │ ╰─ attrValue.value "test$class"
│ │ │ ╰─ attrValue "= test$class"
│ │ ╰─ attrName
│ ├─ closeTagEnd(tag)
╰─ ╰─ tagName "tag"
16╭─
╰─ ╰─ openTagEnd
17╭─ tag a = test+class b
│ │ │ │ ╰─ attrValue.value "test+class b"
│ │ │ ╰─ attrValue "= test+class b"
│ │ ╰─ attrName
│ ├─ closeTagEnd(tag)
╰─ ╰─ tagName "tag"
18╭─
│ ├─ openTagEnd
╰─ ╰─ closeTagEnd(tag)
17 changes: 17 additions & 0 deletions src/__tests__/fixtures/attr-complex-unary/input.marko
@@ -0,0 +1,17 @@
tag a = class b {}

tag a = class, b

<tag a = class></tag>

<tag a = class/>

tag a = classthing b

tag a = testclass b

tag a = test_class b

tag a = test$class b

tag a = test+class b
3 changes: 2 additions & 1 deletion src/states/EXPRESSION.ts
Expand Up @@ -296,7 +296,8 @@ function lookBehindForOperator(data: string, pos: number): number {
for (const keyword of unaryKeywords) {
const keywordPos = lookBehindFor(data, curPos, keyword);
if (keywordPos !== -1) {
return data.charCodeAt(keywordPos - 1) === CODE.PERIOD
const prevCode = data.charCodeAt(keywordPos - 1);
return prevCode === CODE.PERIOD || isWordCode(prevCode)
? -1
: keywordPos;
}
Expand Down

0 comments on commit 72b3379

Please sign in to comment.