Make distinct nodes for style/script, set up injection

This commit is contained in:
Max Brunsfeld 2018-12-14 17:43:41 -08:00
parent 57b42ed645
commit 30b7bf0f46
10 changed files with 1147 additions and 652 deletions

View File

@ -148,12 +148,12 @@ Raw text elements
---
(fragment
(raw_element
(script_element
(start_tag (tag_name))
(raw_text)
(end_tag (tag_name)))
(text)
(raw_element
(style_element
(start_tag (tag_name))
(raw_text)
(end_tag (tag_name)))

View File

@ -8,7 +8,8 @@ module.exports = grammar({
externals: $ => [
$._start_tag_name,
$._start_raw_tag_name,
$._script_start_tag_name,
$._style_start_tag_name,
$._end_tag_name,
$.erroneous_end_tag_name,
'/>',
@ -33,8 +34,9 @@ module.exports = grammar({
$.doctype,
$.text,
$.element,
$.erroneous_end_tag,
$.raw_element
$.script_element,
$.style_element,
$.erroneous_end_tag
),
element: $ => choice(
@ -46,8 +48,14 @@ module.exports = grammar({
$.self_closing_tag
),
raw_element: $ => seq(
alias($._raw_start_tag, $.start_tag),
script_element: $ => seq(
alias($.script_start_tag, $.start_tag),
optional($.raw_text),
$.end_tag
),
style_element: $ => seq(
alias($.style_start_tag, $.start_tag),
optional($.raw_text),
$.end_tag
),
@ -59,9 +67,16 @@ module.exports = grammar({
'>'
),
_raw_start_tag: $ => seq(
script_start_tag: $ => seq(
'<',
alias($._start_raw_tag_name, $.tag_name),
alias($._script_start_tag_name, $.tag_name),
repeat($.attribute),
'>'
),
style_start_tag: $ => seq(
'<',
alias($._style_start_tag_name, $.tag_name),
repeat($.attribute),
'>'
),

View File

@ -1,3 +1,5 @@
@import "./injections.css";
tag_name {
scope: 'tag';
}

View File

@ -0,0 +1,9 @@
script_element {
injection-language: 'javascript';
injection-content: child(this(), 1);
}
style_element {
injection-language: 'css';
injection-content: child(this(), 1);
}

View File

@ -55,11 +55,15 @@
},
{
"type": "SYMBOL",
"name": "erroneous_end_tag"
"name": "script_element"
},
{
"type": "SYMBOL",
"name": "raw_element"
"name": "style_element"
},
{
"type": "SYMBOL",
"name": "erroneous_end_tag"
}
]
},
@ -101,14 +105,44 @@
}
]
},
"raw_element": {
"script_element": {
"type": "SEQ",
"members": [
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_raw_start_tag"
"name": "script_start_tag"
},
"named": true,
"value": "start_tag"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "raw_text"
},
{
"type": "BLANK"
}
]
},
{
"type": "SYMBOL",
"name": "end_tag"
}
]
},
"style_element": {
"type": "SEQ",
"members": [
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "style_start_tag"
},
"named": true,
"value": "start_tag"
@ -160,7 +194,7 @@
}
]
},
"_raw_start_tag": {
"script_start_tag": {
"type": "SEQ",
"members": [
{
@ -171,7 +205,36 @@
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_start_raw_tag_name"
"name": "_script_start_tag_name"
},
"named": true,
"value": "tag_name"
},
{
"type": "REPEAT",
"content": {
"type": "SYMBOL",
"name": "attribute"
}
},
{
"type": "STRING",
"value": ">"
}
]
},
"style_start_tag": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "<"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_style_start_tag_name"
},
"named": true,
"value": "tag_name"
@ -392,7 +455,11 @@
},
{
"type": "SYMBOL",
"name": "_start_raw_tag_name"
"name": "_script_start_tag_name"
},
{
"type": "SYMBOL",
"name": "_style_start_tag_name"
},
{
"type": "SYMBOL",

View File

@ -7,7 +7,7 @@
{
"type": "attribute_name",
"named": true,
"state_id": 4
"state_id": 5
},
{
"type": "attribute_value",
@ -22,17 +22,27 @@
{
"type": "doctype",
"named": true,
"state_id": 5
"state_id": 3
},
{
"type": "erroneous_end_tag_name",
"named": true,
"state_id": 3
"state_id": 4
},
{
"type": "script_element",
"named": true,
"state_id": 7
},
{
"type": "style_element",
"named": true,
"state_id": 6
},
{
"type": "tag_name",
"named": true,
"state_id": 3
"state_id": 4
}
],
"default_next_state_id": 0
@ -44,7 +54,7 @@
{
"type": "attribute_name",
"named": true,
"state_id": 4
"state_id": 5
},
{
"type": "attribute_value",
@ -59,17 +69,27 @@
{
"type": "doctype",
"named": true,
"state_id": 5
"state_id": 3
},
{
"type": "erroneous_end_tag_name",
"named": true,
"state_id": 3
"state_id": 4
},
{
"type": "script_element",
"named": true,
"state_id": 7
},
{
"type": "style_element",
"named": true,
"state_id": 6
},
{
"type": "tag_name",
"named": true,
"state_id": 3
"state_id": 4
}
],
"default_next_state_id": 0
@ -81,7 +101,7 @@
{
"type": "attribute_name",
"named": true,
"state_id": 4
"state_id": 5
},
{
"type": "attribute_value",
@ -96,17 +116,27 @@
{
"type": "doctype",
"named": true,
"state_id": 5
"state_id": 3
},
{
"type": "erroneous_end_tag_name",
"named": true,
"state_id": 3
"state_id": 4
},
{
"type": "script_element",
"named": true,
"state_id": 7
},
{
"type": "style_element",
"named": true,
"state_id": 6
},
{
"type": "tag_name",
"named": true,
"state_id": 3
"state_id": 4
}
],
"default_next_state_id": 0
@ -118,7 +148,7 @@
{
"type": "attribute_name",
"named": true,
"state_id": 4
"state_id": 5
},
{
"type": "attribute_value",
@ -133,17 +163,27 @@
{
"type": "doctype",
"named": true,
"state_id": 5
"state_id": 3
},
{
"type": "erroneous_end_tag_name",
"named": true,
"state_id": 3
"state_id": 4
},
{
"type": "script_element",
"named": true,
"state_id": 7
},
{
"type": "style_element",
"named": true,
"state_id": 6
},
{
"type": "tag_name",
"named": true,
"state_id": 3
"state_id": 4
}
],
"default_next_state_id": 0
@ -155,7 +195,7 @@
{
"type": "attribute_name",
"named": true,
"state_id": 4
"state_id": 5
},
{
"type": "attribute_value",
@ -170,17 +210,27 @@
{
"type": "doctype",
"named": true,
"state_id": 5
"state_id": 3
},
{
"type": "erroneous_end_tag_name",
"named": true,
"state_id": 3
"state_id": 4
},
{
"type": "script_element",
"named": true,
"state_id": 7
},
{
"type": "style_element",
"named": true,
"state_id": 6
},
{
"type": "tag_name",
"named": true,
"state_id": 3
"state_id": 4
}
],
"default_next_state_id": 0
@ -192,7 +242,7 @@
{
"type": "attribute_name",
"named": true,
"state_id": 4
"state_id": 5
},
{
"type": "attribute_value",
@ -207,17 +257,121 @@
{
"type": "doctype",
"named": true,
"state_id": 5
"state_id": 3
},
{
"type": "erroneous_end_tag_name",
"named": true,
"state_id": 3
"state_id": 4
},
{
"type": "script_element",
"named": true,
"state_id": 7
},
{
"type": "style_element",
"named": true,
"state_id": 6
},
{
"type": "tag_name",
"named": true,
"state_id": 4
}
],
"default_next_state_id": 0
},
{
"id": 6,
"property_set_id": 6,
"transitions": [
{
"type": "attribute_name",
"named": true,
"state_id": 5
},
{
"type": "attribute_value",
"named": true,
"state_id": 2
},
{
"type": "comment",
"named": true,
"state_id": 1
},
{
"type": "doctype",
"named": true,
"state_id": 3
},
{
"type": "erroneous_end_tag_name",
"named": true,
"state_id": 4
},
{
"type": "script_element",
"named": true,
"state_id": 7
},
{
"type": "style_element",
"named": true,
"state_id": 6
},
{
"type": "tag_name",
"named": true,
"state_id": 4
}
],
"default_next_state_id": 0
},
{
"id": 7,
"property_set_id": 7,
"transitions": [
{
"type": "attribute_name",
"named": true,
"state_id": 5
},
{
"type": "attribute_value",
"named": true,
"state_id": 2
},
{
"type": "comment",
"named": true,
"state_id": 1
},
{
"type": "doctype",
"named": true,
"state_id": 3
},
{
"type": "erroneous_end_tag_name",
"named": true,
"state_id": 4
},
{
"type": "script_element",
"named": true,
"state_id": 7
},
{
"type": "style_element",
"named": true,
"state_id": 6
},
{
"type": "tag_name",
"named": true,
"state_id": 4
}
],
"default_next_state_id": 0
@ -231,6 +385,9 @@
{
"scope": "string"
},
{
"scope": "constant"
},
{
"scope": "tag"
},
@ -238,7 +395,30 @@
"scope": "attribute"
},
{
"scope": "constant"
"injection-content": {
"name": "child",
"args": [
{
"name": "this",
"args": []
},
1
]
},
"injection-language": "css"
},
{
"injection-content": {
"name": "child",
"args": [
{
"name": "this",
"args": []
},
1
]
},
"injection-language": "javascript"
}
]
}

84
src/injections.json Normal file
View File

@ -0,0 +1,84 @@
{
"states": [
{
"id": 0,
"property_set_id": 0,
"transitions": [
{
"type": "script_element",
"named": true,
"state_id": 2
},
{
"type": "style_element",
"named": true,
"state_id": 1
}
],
"default_next_state_id": 0
},
{
"id": 1,
"property_set_id": 1,
"transitions": [
{
"type": "script_element",
"named": true,
"state_id": 2
},
{
"type": "style_element",
"named": true,
"state_id": 1
}
],
"default_next_state_id": 0
},
{
"id": 2,
"property_set_id": 2,
"transitions": [
{
"type": "script_element",
"named": true,
"state_id": 2
},
{
"type": "style_element",
"named": true,
"state_id": 1
}
],
"default_next_state_id": 0
}
],
"property_sets": [
{},
{
"injection-content": {
"name": "child",
"args": [
{
"name": "this",
"args": []
},
1
]
},
"injection-language": "css"
},
{
"injection-content": {
"name": "child",
"args": [
{
"name": "this",
"args": []
},
1
]
},
"injection-language": "javascript"
}
]
}

1341
src/parser.c vendored

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,8 @@ using std::string;
enum TokenType {
START_TAG_NAME,
START_RAW_TAG_NAME,
SCRIPT_START_TAG_NAME,
STYLE_START_TAG_NAME,
END_TAG_NAME,
ERRONEOUS_END_TAG_NAME,
SELF_CLOSING_TAG_DELIMITER,
@ -187,10 +188,16 @@ struct Scanner {
if (tag_name.empty()) return false;
Tag tag = Tag::for_name(tag_name);
tags.push_back(tag);
if (tag.is_raw()) {
lexer->result_symbol = START_RAW_TAG_NAME;
} else {
switch (tag.type) {
case SCRIPT:
lexer->result_symbol = SCRIPT_START_TAG_NAME;
break;
case STYLE:
lexer->result_symbol = STYLE_START_TAG_NAME;
break;
default:
lexer->result_symbol = START_TAG_NAME;
break;
}
return true;
}

View File

@ -329,10 +329,6 @@ struct Tag {
return type < END_OF_VOID_TAGS;
}
inline bool is_raw() const {
return type == SCRIPT || type == STYLE;
}
inline bool can_contain(const Tag &tag) {
TagType child = tag.type;