Kaynağa Gözat

LibWeb: Flesh out the "in frameset" parsing state and add spec comments

This also implements two FIXMEs, which were covered by WPT tests.
Andreas Kling 9 ay önce
ebeveyn
işleme
b82e34ed00

+ 38 - 2
Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp

@@ -3862,63 +3862,99 @@ void HTMLParser::handle_in_template(HTMLToken& token)
     }
 }
 
+// https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inframeset
 void HTMLParser::handle_in_frameset(HTMLToken& token)
 {
+    // -> A character token that is one of U+0009 CHARACTER TABULATION, U+000A LINE FEED (LF),
+    //    U+000C FORM FEED (FF), U+000D CARRIAGE RETURN (CR), or U+0020 SPACE
     if (token.is_character() && token.is_parser_whitespace()) {
+        // Insert the character.
         insert_character(token.code_point());
         return;
     }
 
+    // -> A comment token
     if (token.is_comment()) {
+        // Insert a comment.
         insert_comment(token);
         return;
     }
 
+    // -> A DOCTYPE token
     if (token.is_doctype()) {
+        // Parse error. Ignore the token.
         log_parse_error();
         return;
     }
 
+    // -> A start tag whose tag name is "html"
     if (token.is_start_tag() && token.tag_name() == HTML::TagNames::html) {
+        // Process the token using the rules for the "in body" insertion mode.
         process_using_the_rules_for(InsertionMode::InBody, token);
         return;
     }
 
+    // -> A start tag whose tag name is "frameset"
     if (token.is_start_tag() && token.tag_name() == HTML::TagNames::frameset) {
+        // Insert an HTML element for the token.
         (void)insert_html_element(token);
         return;
     }
 
+    // -> An end tag whose tag name is "frameset"
     if (token.is_end_tag() && token.tag_name() == HTML::TagNames::frameset) {
-        // FIXME: If the current node is the root html element, then this is a parse error; ignore the token. (fragment case)
+        // If the current node is the root html element, then this is a parse error; ignore the token. (fragment case)
+        if (current_node().is_document_element()) {
+            log_parse_error();
+            return;
+        }
 
+        // Otherwise, pop the current node from the stack of open elements.
         (void)m_stack_of_open_elements.pop();
 
+        // If the parser was not created as part of the HTML fragment parsing algorithm (fragment case),
+        // and the current node is no longer a frameset element, then switch the insertion mode to "after frameset".
         if (!m_parsing_fragment && current_node().local_name() != HTML::TagNames::frameset) {
             m_insertion_mode = InsertionMode::AfterFrameset;
         }
         return;
     }
 
+    // -> A start tag whose tag name is "frame"
     if (token.is_start_tag() && token.tag_name() == HTML::TagNames::frame) {
+        // Insert an HTML element for the token.
         (void)insert_html_element(token);
+
+        // Immediately pop the current node off the stack of open elements.
         (void)m_stack_of_open_elements.pop();
+
+        // Acknowledge the token's self-closing flag, if it is set.
         token.acknowledge_self_closing_flag_if_set();
         return;
     }
 
+    // -> A start tag whose tag name is "noframes"
     if (token.is_start_tag() && token.tag_name() == HTML::TagNames::noframes) {
+        // Process the token using the rules for the "in head" insertion mode.
         process_using_the_rules_for(InsertionMode::InHead, token);
         return;
     }
 
+    // -> An end-of-file token
     if (token.is_end_of_file()) {
-        // FIXME: If the current node is not the root html element, then this is a parse error.
+        // If the current node is not the root html element, then this is a parse error.
+        if (!current_node().is_document_element()) {
+            log_parse_error();
+        }
 
+        // Stop parsing.
         stop_parsing();
         return;
     }
 
+    // -> Anything else
+
+    // Parse error. Ignore the token.
     log_parse_error();
 }