LibWeb: Parse enough to handle a <style> inside a <head> :^)

This commit is contained in:
Andreas Kling 2020-05-24 20:36:43 +02:00
parent af8a9331b2
commit 5d332c1f11
Notes: sideshowbarker 2024-07-19 06:10:18 +09:00
3 changed files with 103 additions and 0 deletions

View file

@ -207,6 +207,11 @@ void HTMLDocumentParser::handle_in_head(HTMLToken& token)
return;
}
if (token.is_start_tag() && ((token.tag_name() == "noscript" && m_scripting_enabled) || token.tag_name() == "noframes" || token.tag_name() == "style")) {
parse_generic_raw_text_element(token);
return;
}
if (token.is_start_tag() && token.tag_name() == "meta") {
auto element = insert_html_element(token);
m_stack_of_open_elements.pop();
@ -228,6 +233,14 @@ void HTMLDocumentParser::handle_in_head_noscript(HTMLToken&)
ASSERT_NOT_REACHED();
}
void HTMLDocumentParser::parse_generic_raw_text_element(HTMLToken& token)
{
insert_html_element(token);
m_tokenizer.switch_to({}, HTMLTokenizer::State::RAWTEXT);
m_original_insertion_mode = m_insertion_mode;
m_insertion_mode = InsertionMode::Text;
}
void HTMLDocumentParser::insert_character(u32 data)
{
auto adjusted_insertion_location = find_appropriate_place_for_inserting_node();

View file

@ -99,6 +99,7 @@ private:
void insert_comment(HTMLToken&);
void reconstruct_the_active_formatting_elements();
void process_using_the_rules_for(InsertionMode, HTMLToken&);
void parse_generic_raw_text_element(HTMLToken&);
InsertionMode m_insertion_mode { InsertionMode::Initial };
InsertionMode m_original_insertion_mode { InsertionMode::Initial };
@ -112,6 +113,7 @@ private:
bool m_foster_parenting { false };
bool m_frameset_ok { true };
bool m_parsing_fragment { false };
bool m_scripting_enabled { true };
RefPtr<Document> m_document;
RefPtr<HTMLHeadElement> m_head_element;

View file

@ -827,6 +827,94 @@ Optional<HTMLToken> HTMLTokenizer::next_token()
}
END_STATE
BEGIN_STATE(RAWTEXT)
{
ON('<')
{
SWITCH_TO(RAWTEXTLessThanSign);
}
ON(0)
{
TODO();
}
ON_EOF
{
EMIT_EOF;
}
ANYTHING_ELSE
{
EMIT_CURRENT_CHARACTER;
}
}
END_STATE
BEGIN_STATE(RAWTEXTLessThanSign)
{
ON('/')
{
m_temporary_buffer.clear();
SWITCH_TO(RAWTEXTEndTagOpen);
}
ANYTHING_ELSE
{
EMIT_CHARACTER('<');
RECONSUME_IN(RAWTEXT);
}
}
END_STATE
BEGIN_STATE(RAWTEXTEndTagOpen)
{
ON_ASCII_ALPHA
{
create_new_token(HTMLToken::Type::EndTag);
RECONSUME_IN(RAWTEXTEndTagName);
}
ANYTHING_ELSE
{
// FIXME: Emit a U+003C LESS-THAN SIGN character token and a U+002F SOLIDUS character token. Reconsume in the RAWTEXT state.
TODO();
}
}
END_STATE
BEGIN_STATE(RAWTEXTEndTagName)
{
ON_WHITESPACE
{
TODO();
}
ON('/')
{
TODO();
}
ON('>')
{
if (!current_end_tag_token_is_appropriate()) {
// FIXME: Otherwise, treat it as per the "anything else" entry below.
TODO();
}
SWITCH_TO_AND_EMIT_CURRENT_TOKEN(Data);
}
ON_ASCII_UPPER_ALPHA
{
m_current_token.m_tag.tag_name.append(tolower(current_input_character.value()));
m_temporary_buffer.append(current_input_character.value());
continue;
}
ON_ASCII_LOWER_ALPHA
{
m_current_token.m_tag.tag_name.append(current_input_character.value());
m_temporary_buffer.append(current_input_character.value());
continue;
}
ANYTHING_ELSE
{
TODO();
}
}
END_STATE
default:
ASSERT_NOT_REACHED();
}