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 (fragment
(raw_element (script_element
(start_tag (tag_name)) (start_tag (tag_name))
(raw_text) (raw_text)
(end_tag (tag_name))) (end_tag (tag_name)))
(text) (text)
(raw_element (style_element
(start_tag (tag_name)) (start_tag (tag_name))
(raw_text) (raw_text)
(end_tag (tag_name))) (end_tag (tag_name)))

View File

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

View File

@ -1,3 +1,5 @@
@import "./injections.css";
tag_name { tag_name {
scope: 'tag'; 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", "type": "SYMBOL",
"name": "erroneous_end_tag" "name": "script_element"
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "raw_element" "name": "style_element"
},
{
"type": "SYMBOL",
"name": "erroneous_end_tag"
} }
] ]
}, },
@ -101,14 +105,44 @@
} }
] ]
}, },
"raw_element": { "script_element": {
"type": "SEQ", "type": "SEQ",
"members": [ "members": [
{ {
"type": "ALIAS", "type": "ALIAS",
"content": { "content": {
"type": "SYMBOL", "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, "named": true,
"value": "start_tag" "value": "start_tag"
@ -160,7 +194,7 @@
} }
] ]
}, },
"_raw_start_tag": { "script_start_tag": {
"type": "SEQ", "type": "SEQ",
"members": [ "members": [
{ {
@ -171,7 +205,36 @@
"type": "ALIAS", "type": "ALIAS",
"content": { "content": {
"type": "SYMBOL", "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, "named": true,
"value": "tag_name" "value": "tag_name"
@ -392,7 +455,11 @@
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "_start_raw_tag_name" "name": "_script_start_tag_name"
},
{
"type": "SYMBOL",
"name": "_style_start_tag_name"
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",

View File

@ -7,7 +7,7 @@
{ {
"type": "attribute_name", "type": "attribute_name",
"named": true, "named": true,
"state_id": 4 "state_id": 5
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
@ -22,17 +22,27 @@
{ {
"type": "doctype", "type": "doctype",
"named": true, "named": true,
"state_id": 5 "state_id": 3
}, },
{ {
"type": "erroneous_end_tag_name", "type": "erroneous_end_tag_name",
"named": true, "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", "type": "tag_name",
"named": true, "named": true,
"state_id": 3 "state_id": 4
} }
], ],
"default_next_state_id": 0 "default_next_state_id": 0
@ -44,7 +54,7 @@
{ {
"type": "attribute_name", "type": "attribute_name",
"named": true, "named": true,
"state_id": 4 "state_id": 5
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
@ -59,17 +69,27 @@
{ {
"type": "doctype", "type": "doctype",
"named": true, "named": true,
"state_id": 5 "state_id": 3
}, },
{ {
"type": "erroneous_end_tag_name", "type": "erroneous_end_tag_name",
"named": true, "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", "type": "tag_name",
"named": true, "named": true,
"state_id": 3 "state_id": 4
} }
], ],
"default_next_state_id": 0 "default_next_state_id": 0
@ -81,7 +101,7 @@
{ {
"type": "attribute_name", "type": "attribute_name",
"named": true, "named": true,
"state_id": 4 "state_id": 5
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
@ -96,17 +116,27 @@
{ {
"type": "doctype", "type": "doctype",
"named": true, "named": true,
"state_id": 5 "state_id": 3
}, },
{ {
"type": "erroneous_end_tag_name", "type": "erroneous_end_tag_name",
"named": true, "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", "type": "tag_name",
"named": true, "named": true,
"state_id": 3 "state_id": 4
} }
], ],
"default_next_state_id": 0 "default_next_state_id": 0
@ -118,7 +148,7 @@
{ {
"type": "attribute_name", "type": "attribute_name",
"named": true, "named": true,
"state_id": 4 "state_id": 5
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
@ -133,17 +163,27 @@
{ {
"type": "doctype", "type": "doctype",
"named": true, "named": true,
"state_id": 5 "state_id": 3
}, },
{ {
"type": "erroneous_end_tag_name", "type": "erroneous_end_tag_name",
"named": true, "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", "type": "tag_name",
"named": true, "named": true,
"state_id": 3 "state_id": 4
} }
], ],
"default_next_state_id": 0 "default_next_state_id": 0
@ -155,7 +195,7 @@
{ {
"type": "attribute_name", "type": "attribute_name",
"named": true, "named": true,
"state_id": 4 "state_id": 5
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
@ -170,17 +210,27 @@
{ {
"type": "doctype", "type": "doctype",
"named": true, "named": true,
"state_id": 5 "state_id": 3
}, },
{ {
"type": "erroneous_end_tag_name", "type": "erroneous_end_tag_name",
"named": true, "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", "type": "tag_name",
"named": true, "named": true,
"state_id": 3 "state_id": 4
} }
], ],
"default_next_state_id": 0 "default_next_state_id": 0
@ -192,7 +242,7 @@
{ {
"type": "attribute_name", "type": "attribute_name",
"named": true, "named": true,
"state_id": 4 "state_id": 5
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
@ -207,17 +257,121 @@
{ {
"type": "doctype", "type": "doctype",
"named": true, "named": true,
"state_id": 5 "state_id": 3
}, },
{ {
"type": "erroneous_end_tag_name", "type": "erroneous_end_tag_name",
"named": true, "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", "type": "tag_name",
"named": true, "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 "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 "default_next_state_id": 0
@ -231,6 +385,9 @@
{ {
"scope": "string" "scope": "string"
}, },
{
"scope": "constant"
},
{ {
"scope": "tag" "scope": "tag"
}, },
@ -238,7 +395,30 @@
"scope": "attribute" "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 { enum TokenType {
START_TAG_NAME, START_TAG_NAME,
START_RAW_TAG_NAME, SCRIPT_START_TAG_NAME,
STYLE_START_TAG_NAME,
END_TAG_NAME, END_TAG_NAME,
ERRONEOUS_END_TAG_NAME, ERRONEOUS_END_TAG_NAME,
SELF_CLOSING_TAG_DELIMITER, SELF_CLOSING_TAG_DELIMITER,
@ -187,10 +188,16 @@ struct Scanner {
if (tag_name.empty()) return false; if (tag_name.empty()) return false;
Tag tag = Tag::for_name(tag_name); Tag tag = Tag::for_name(tag_name);
tags.push_back(tag); tags.push_back(tag);
if (tag.is_raw()) { switch (tag.type) {
lexer->result_symbol = START_RAW_TAG_NAME; case SCRIPT:
} else { 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; lexer->result_symbol = START_TAG_NAME;
break;
} }
return true; return true;
} }

View File

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