Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add new parser events and rename 'onTagName' to 'onOpenTagName'. #114

Merged
merged 1 commit into from
Jun 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/two-points-guess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"htmljs-parser": major
---

Rename `onTagName` to `onOpenTagName`.
Add a new `onOpenTagStart` event (before `onOpenTagName`).
Split the `onCloseTag` event into three new events: `onClosetTagStart`, `onCloseTagName` & `onCloseTagEnd`).
54 changes: 40 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,20 +155,29 @@ const parser = createParser({
range.value; // Another range that includes only the value itself without the leading $ or surrounding braces (if applicable).
},

/**
* Called when we're about to begin an HTML open tag (before the tag name).
* Note: This is only called for HTML mode tags and can be used to track if you are in concise mode.
*
* @example
* 1╭─ <div>Hi</div>
* ╰─ ╰─ openTagStart
*/
onOpenTagStart(range) {}

/**
* Called when a tag name, which can include placeholders, has been parsed.
*
* @example
* 1╭─ <div/>
* ╰─ ╰─ tagName "div"
* ╰─ ╰─ openTagName "div"
* 2╭─ <hello-${test}-again/>
* │ │ │ ╰─ tagName.quasis[1] "-again"
* │ │ ╰─ tagName.expressions[0] "${test}"
* │ ├─ tagName.quasis[0] "hello-"
* ╰─ ╰─ tagName "hello-${test}-again"
* │ │ │ ╰─ openTagName.quasis[1] "-again"
* │ │ ╰─ openTagName.expressions[0] "${test}"
* │ ├─ openTagName.quasis[0] "hello-"
* ╰─ ╰─ openTagName "hello-${test}-again"
*/
onTagName(range) {
range.concise; // true if this tag is a concise mode tag.
onOpenTagName(range) {
range.quasis; // An array of ranges that indicate the string literal parts of the tag name.
range.expressions; // A list of placeholder ranges (similar to whats emitted via onPlaceholder).

Expand Down Expand Up @@ -353,21 +362,38 @@ const parser = createParser({
* ╰─ ╰─ openTagEnd ">"
*/
onOpenTagEnd(range) {
range.selfClosed; // true if this tag was self closed (onCloseTag would not be called if so).
range.selfClosed; // true if this tag was self closed (the onCloseTag* handlers will not be called if so).
},

/**
* Called once the closing tag (or in concise mode an outdent or eof) is parsed.
* Called when we start parsing and html closing tag.
* Note this is not emitted for concise, selfClosed, void or statement tags.
*
* @example
* 1╭─ <div><span/></div>
* ╰─ ╰─ closeTagStart "</"
*/
onCloseTagStart(range) {},

/**
* Called after the content within the brackets of an html closing tag has been parsed.
* Note this is not emitted for concise, selfClosed, void or statement tags.
*
* @example
* 1╭─ <div><span/></div>
* ╰─ ╰─ closeTagName "div"
*/
onCloseTagName(range) {},

/**
* Called once the closing tag has finished parsing, or in concise mode we hit an outdent or eof.
* Note this is not called for selfClosed, void or statement tags.
*
* @example
* 1╭─ <div><span/></div>
* │ │ ╰─ closeTag(div).value "div"
* ╰─ ╰─ closeTag(div) "</div>"
* ╰─ ╰─ closeTagEnd ">"
*/
onCloseTag(range) {
range.value; // The raw content of the closing tag (undefined in concise mode).
},
onCloseTagEnd(range) {},
});
```

Expand Down
Original file line number Diff line number Diff line change
@@ -1,44 +1,50 @@
1╭─ <${x}(y)/>
│ │ ││ ╰─ openTagEnd:selfClosed "/>"
│ │ │╰─ tagArgs.value
│ │ ├─ tagArgs "(y)"
│ │ ╰─ tagName.quasis[1]
│ ├─ tagName.expressions[0] "${x}"
│ ├─ tagName.quasis[0]
╰─ ╰─ tagName "${x}"
│ ││ ││ ╰─ openTagEnd:selfClosed "/>"
│ ││ │╰─ tagArgs.value
│ ││ ├─ tagArgs "(y)"
│ ││ ╰─ tagName.quasis[1]
│ │├─ tagName.expressions[0] "${x}"
│ │├─ tagName.quasis[0]
│ │╰─ tagName "${x}"
╰─ ╰─ openTagStart
2╭─ <${x}|y|/>
│ │ ││ ╰─ openTagEnd:selfClosed "/>"
│ │ │╰─ tagParams.value
│ │ ├─ tagParams "|y|"
│ │ ╰─ tagName.quasis[1]
│ ├─ tagName.expressions[0] "${x}"
│ ├─ tagName.quasis[0]
╰─ ╰─ tagName "${x}"
│ ││ ││ ╰─ openTagEnd:selfClosed "/>"
│ ││ │╰─ tagParams.value
│ ││ ├─ tagParams "|y|"
│ ││ ╰─ tagName.quasis[1]
│ │├─ tagName.expressions[0] "${x}"
│ │├─ tagName.quasis[0]
│ │╰─ tagName "${x}"
╰─ ╰─ openTagStart
3╭─ <tag.x(y)/>
│ │ ││││ ╰─ openTagEnd:selfClosed "/>"
│ │ │││╰─ tagArgs.value
│ │ ││╰─ tagArgs "(y)"
│ │ │╰─ tagShorthandClass.quasis[0]
│ │ ╰─ tagShorthandClass ".x"
╰─ ╰─ tagName "tag"
│ ││ ││││ ╰─ openTagEnd:selfClosed "/>"
│ ││ │││╰─ tagArgs.value
│ ││ ││╰─ tagArgs "(y)"
│ ││ │╰─ tagShorthandClass.quasis[0]
│ ││ ╰─ tagShorthandClass ".x"
│ │╰─ tagName "tag"
╰─ ╰─ openTagStart
4╭─ <tag.x|y|/>
│ │ ││││ ╰─ openTagEnd:selfClosed "/>"
│ │ │││╰─ tagParams.value
│ │ ││╰─ tagParams "|y|"
│ │ │╰─ tagShorthandClass.quasis[0]
│ │ ╰─ tagShorthandClass ".x"
╰─ ╰─ tagName "tag"
│ ││ ││││ ╰─ openTagEnd:selfClosed "/>"
│ ││ │││╰─ tagParams.value
│ ││ ││╰─ tagParams "|y|"
│ ││ │╰─ tagShorthandClass.quasis[0]
│ ││ ╰─ tagShorthandClass ".x"
│ │╰─ tagName "tag"
╰─ ╰─ openTagStart
5╭─ <tag#x(y)/>
│ │ ││││ ╰─ openTagEnd:selfClosed "/>"
│ │ │││╰─ tagArgs.value
│ │ ││╰─ tagArgs "(y)"
│ │ │╰─ tagShorthandId.quasis[0]
│ │ ╰─ tagShorthandId "#x"
╰─ ╰─ tagName "tag"
│ ││ ││││ ╰─ openTagEnd:selfClosed "/>"
│ ││ │││╰─ tagArgs.value
│ ││ ││╰─ tagArgs "(y)"
│ ││ │╰─ tagShorthandId.quasis[0]
│ ││ ╰─ tagShorthandId "#x"
│ │╰─ tagName "tag"
╰─ ╰─ openTagStart
6╭─ <tag#x|y|/>
│ │ ││││ ╰─ openTagEnd:selfClosed "/>"
│ │ │││╰─ tagParams.value
│ │ ││╰─ tagParams "|y|"
│ │ │╰─ tagShorthandId.quasis[0]
│ │ ╰─ tagShorthandId "#x"
╰─ ╰─ tagName "tag"
│ ││ ││││ ╰─ openTagEnd:selfClosed "/>"
│ ││ │││╰─ tagParams.value
│ ││ ││╰─ tagParams "|y|"
│ ││ │╰─ tagShorthandId.quasis[0]
│ ││ ╰─ tagShorthandId "#x"
│ │╰─ tagName "tag"
╰─ ╰─ openTagStart
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
1╭─ <div if (x > y)>
│ │ │ ││ ╰─ openTagEnd
│ │ │ │╰─ attrArgs.value "x > y"
│ │ │ ╰─ attrArgs "(x > y)"
│ │ ╰─ attrName "if"
╰─ ╰─ tagName "div"
│ ││ │ ││ ╰─ openTagEnd
│ ││ │ │╰─ attrArgs.value "x > y"
│ ││ │ ╰─ attrArgs "(x > y)"
│ ││ ╰─ attrName "if"
│ │╰─ tagName "div"
╰─ ╰─ openTagStart
2╭─ </div>
│ │ ╰─ closeTag(div).value "div"
│ │ │ ╰─ closeTagEnd(div)
│ │ ╰─ closeTagName "div"
│ ├─ text "\n"
╰─ ╰─ closeTag(div) "</div>"
╰─ ╰─ closeTagStart "</"
3╰─
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
1╭─ <div for(var i = 0; i < 10; i++) (nonsense!)></div>
│ │ │ ││ ╰─ error(INVALID_ATTRIBUTE_ARGUMENT:An attribute can only have one set of arguments) "nonsense!"
│ │ │ │╰─ attrArgs.value "var i = 0; i < 10; i++"
│ │ │ ╰─ attrArgs "(var i = 0; i < 10; i++)"
│ │ ╰─ attrName "for"
╰─ ╰─ tagName "div"
│ ││ │ ││ ╰─ error(INVALID_ATTRIBUTE_ARGUMENT:An attribute can only have one set of arguments) "nonsense!"
│ ││ │ │╰─ attrArgs.value "var i = 0; i < 10; i++"
│ ││ │ ╰─ attrArgs "(var i = 0; i < 10; i++)"
│ ││ ╰─ attrName "for"
│ │╰─ tagName "div"
╰─ ╰─ openTagStart
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
1╭─ <div if(x > y)></div>
│ │ │ ││ ││ ╰─ closeTag(div).value "div"
│ │ │ ││ │╰─ closeTag(div) "</div>"
│ │ │ ││ ╰─ openTagEnd
│ │ │ │╰─ attrArgs.value "x > y"
│ │ │ ╰─ attrArgs "(x > y)"
│ │ ╰─ attrName "if"
╰─ ╰─ tagName "div"
│ ││ │ ││ ││ │ ╰─ closeTagEnd(div)
│ ││ │ ││ ││ ╰─ closeTagName "div"
│ ││ │ ││ │╰─ closeTagStart "</"
│ ││ │ ││ ╰─ openTagEnd
│ ││ │ │╰─ attrArgs.value "x > y"
│ ││ │ ╰─ attrArgs "(x > y)"
│ ││ ╰─ attrName "if"
│ │╰─ tagName "div"
╰─ ╰─ openTagStart
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
1╭─ <for(var i = 0; i < 10; i++) if(x > y)></for>
│ │ ││ │ ││ ││ ╰─ closeTag(for).value "for"
│ │ ││ │ ││ │╰─ closeTag(for) "</for>"
│ │ ││ │ ││ ╰─ openTagEnd
│ │ ││ │ │╰─ attrArgs.value "x > y"
│ │ ││ │ ╰─ attrArgs "(x > y)"
│ │ ││ ╰─ attrName "if"
│ │ │╰─ tagArgs.value "var i = 0; i < 10; i++"
│ │ ╰─ tagArgs "(var i = 0; i < 10; i++)"
╰─ ╰─ tagName "for"
│ ││ ││ │ ││ ││ │ ╰─ closeTagEnd(for)
│ ││ ││ │ ││ ││ ╰─ closeTagName "for"
│ ││ ││ │ ││ │╰─ closeTagStart "</"
│ ││ ││ │ ││ ╰─ openTagEnd
│ ││ ││ │ │╰─ attrArgs.value "x > y"
│ ││ ││ │ ╰─ attrArgs "(x > y)"
│ ││ ││ ╰─ attrName "if"
│ ││ │╰─ tagArgs.value "var i = 0; i < 10; i++"
│ ││ ╰─ tagArgs "(var i = 0; i < 10; i++)"
│ │╰─ tagName "for"
╰─ ╰─ openTagStart
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
1╭─ <for (x in ["Hello ${name}!", "(World)"])></for>
│ │ ││ ││ ╰─ closeTag(for).value "for"
│ │ ││ │╰─ closeTag(for) "</for>"
│ │ ││ ╰─ openTagEnd
│ │ │╰─ tagArgs.value "x in [\"Hello ${name}!\", \"(World)\"]"
│ │ ╰─ tagArgs "(x in [\"Hello ${name}!\", \"(World)\"])"
╰─ ╰─ tagName "for"
│ ││ ││ ││ │ ╰─ closeTagEnd(for)
│ ││ ││ ││ ╰─ closeTagName "for"
│ ││ ││ │╰─ closeTagStart "</"
│ ││ ││ ╰─ openTagEnd
│ ││ │╰─ tagArgs.value "x in [\"Hello ${name}!\", \"(World)\"]"
│ ││ ╰─ tagArgs "(x in [\"Hello ${name}!\", \"(World)\"])"
│ │╰─ tagName "for"
╰─ ╰─ openTagStart
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
1╭─ <for (x in y)></for>
│ │ ││ ││ ╰─ closeTag(for).value "for"
│ │ ││ │╰─ closeTag(for) "</for>"
│ │ ││ ╰─ openTagEnd
│ │ │╰─ tagArgs.value "x in y"
│ │ ╰─ tagArgs "(x in y)"
╰─ ╰─ tagName "for"
│ ││ ││ ││ │ ╰─ closeTagEnd(for)
│ ││ ││ ││ ╰─ closeTagName "for"
│ ││ ││ │╰─ closeTagStart "</"
│ ││ ││ ╰─ openTagEnd
│ ││ │╰─ tagArgs.value "x in y"
│ ││ ╰─ tagArgs "(x in y)"
│ │╰─ tagName "for"
╰─ ╰─ openTagStart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
1╭─ <for(var i = 0; i < 10; i++) (nonsense!)></for>
│ │ ││ ╰─ error(INVALID_TAG_ARGUMENT:A tag can only have one argument)
│ │ │╰─ tagArgs.value "var i = 0; i < 10; i++"
│ │ ╰─ tagArgs "(var i = 0; i < 10; i++)"
╰─ ╰─ tagName "for"
│ ││ ││ ╰─ error(INVALID_TAG_ARGUMENT:A tag can only have one argument)
│ ││ │╰─ tagArgs.value "var i = 0; i < 10; i++"
│ ││ ╰─ tagArgs "(var i = 0; i < 10; i++)"
│ │╰─ tagName "for"
╰─ ╰─ openTagStart
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
│ ││ │╰─ tagArgs.value "notEmpty(data.colors)"
│ ││ ╰─ tagArgs "(notEmpty(data.colors))"
│ │╰─ tagName "if"
╰─ ╰─ text "\n"
│ ├─ text "\n"
╰─ ╰─ openTagStart
3╭─ </if>
│ │ ╰─ closeTag(if).value "if"
│ │ │ ╰─ closeTagEnd(if)
│ │ ╰─ closeTagName "if"
│ ├─ text "\n"
╰─ ╰─ closeTag(if) "</if>"
╰─ ╰─ closeTagStart "</"
4╭─ ---
╰─ ╰─ text "\n"
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
1╭─ <for(x in y)></for>
│ │ ││ ││ ╰─ closeTag(for).value "for"
│ │ ││ │╰─ closeTag(for) "</for>"
│ │ ││ ╰─ openTagEnd
│ │ │╰─ tagArgs.value "x in y"
│ │ ╰─ tagArgs "(x in y)"
╰─ ╰─ tagName "for"
│ ││ ││ ││ │ ╰─ closeTagEnd(for)
│ ││ ││ ││ ╰─ closeTagName "for"
│ ││ ││ │╰─ closeTagStart "</"
│ ││ ││ ╰─ openTagEnd
│ ││ │╰─ tagArgs.value "x in y"
│ ││ ╰─ tagArgs "(x in y)"
│ │╰─ tagName "for"
╰─ ╰─ openTagStart
2╭─ <ab('c')/>
│ │ ││ ╰─ openTagEnd:selfClosed "/>"
│ │ │╰─ tagArgs.value "'c'"
│ │ ╰─ tagArgs "('c')"
╰─ ╰─ tagName "ab"
│ ││ ││ ╰─ openTagEnd:selfClosed "/>"
│ ││ │╰─ tagArgs.value "'c'"
│ ││ ╰─ tagArgs "('c')"
│ │╰─ tagName "ab"
╰─ ╰─ openTagStart
3╭─ <a('b')/>
│ │││ ╰─ openTagEnd:selfClosed "/>"
│ ││╰─ tagArgs.value "'b'"
│ │╰─ tagArgs "('b')"
╰─ ╰─ tagName
│ ││││ ╰─ openTagEnd:selfClosed "/>"
│ │││╰─ tagArgs.value "'b'"
│ ││╰─ tagArgs "('b')"
│ │╰─ tagName
╰─ ╰─ openTagStart
4╰─
Loading