2020-05-23 19:14:23 -03:00
/*
2024-10-04 08:19:50 -03:00
* Copyright ( c ) 2020 - 2022 , Andreas Kling < andreas @ ladybird . org >
2020-05-23 19:14:23 -03:00
*
2021-04-22 05:24:48 -03:00
* SPDX - License - Identifier : BSD - 2 - Clause
2020-05-23 19:14:23 -03:00
*/
# pragma once
2023-05-28 00:04:40 -03:00
# include <LibGfx/Color.h>
2022-10-17 05:46:11 -03:00
# include <LibJS/Heap/Cell.h>
2020-05-23 19:14:23 -03:00
# include <LibWeb/DOM/Node.h>
2020-07-28 14:18:23 -03:00
# include <LibWeb/HTML/Parser/HTMLTokenizer.h>
# include <LibWeb/HTML/Parser/ListOfActiveFormattingElements.h>
# include <LibWeb/HTML/Parser/StackOfOpenElements.h>
2024-10-20 05:39:50 -03:00
# include <LibWeb/MimeSniff/MimeType.h>
2020-05-23 19:14:23 -03:00
2025-04-04 12:20:27 -03:00
# ifdef LIBWEB_USE_SWIFT
# include <LibGC / ForeignCell.h>
namespace Web {
2025-05-13 08:06:33 -03:00
2025-04-04 12:20:27 -03:00
class SpeculativeHTMLParser ;
2025-05-13 08:06:33 -03:00
2025-04-04 12:20:27 -03:00
}
# endif
2020-07-28 13:20:36 -03:00
namespace Web : : HTML {
2020-05-23 19:14:23 -03:00
# define ENUMERATE_INSERTION_MODES \
__ENUMERATE_INSERTION_MODE ( Initial ) \
__ENUMERATE_INSERTION_MODE ( BeforeHTML ) \
__ENUMERATE_INSERTION_MODE ( BeforeHead ) \
__ENUMERATE_INSERTION_MODE ( InHead ) \
__ENUMERATE_INSERTION_MODE ( InHeadNoscript ) \
__ENUMERATE_INSERTION_MODE ( AfterHead ) \
__ENUMERATE_INSERTION_MODE ( InBody ) \
__ENUMERATE_INSERTION_MODE ( Text ) \
__ENUMERATE_INSERTION_MODE ( InTable ) \
__ENUMERATE_INSERTION_MODE ( InTableText ) \
__ENUMERATE_INSERTION_MODE ( InCaption ) \
__ENUMERATE_INSERTION_MODE ( InColumnGroup ) \
__ENUMERATE_INSERTION_MODE ( InTableBody ) \
__ENUMERATE_INSERTION_MODE ( InRow ) \
__ENUMERATE_INSERTION_MODE ( InCell ) \
__ENUMERATE_INSERTION_MODE ( InSelect ) \
__ENUMERATE_INSERTION_MODE ( InSelectInTable ) \
__ENUMERATE_INSERTION_MODE ( InTemplate ) \
__ENUMERATE_INSERTION_MODE ( AfterBody ) \
__ENUMERATE_INSERTION_MODE ( InFrameset ) \
__ENUMERATE_INSERTION_MODE ( AfterFrameset ) \
__ENUMERATE_INSERTION_MODE ( AfterAfterBody ) \
__ENUMERATE_INSERTION_MODE ( AfterAfterFrameset )
2022-10-17 05:46:11 -03:00
class HTMLParser final : public JS : : Cell {
2024-11-14 12:01:23 -03:00
GC_CELL ( HTMLParser , JS : : Cell ) ;
GC_DECLARE_ALLOCATOR ( HTMLParser ) ;
2022-10-17 05:46:11 -03:00
2022-02-15 15:52:45 -03:00
friend class HTMLTokenizer ;
2020-05-23 19:14:23 -03:00
public :
2021-09-25 18:15:48 -03:00
~ HTMLParser ( ) ;
2020-05-23 19:14:23 -03:00
2024-11-14 12:01:23 -03:00
static GC : : Ref < HTMLParser > create_for_scripting ( DOM : : Document & ) ;
static GC : : Ref < HTMLParser > create_with_uncertain_encoding ( DOM : : Document & , ByteBuffer const & input , Optional < MimeSniff : : MimeType > maybe_mime_type = { } ) ;
static GC : : Ref < HTMLParser > create ( DOM : : Document & , StringView input , StringView encoding ) ;
2021-05-12 05:47:12 -03:00
2024-02-18 14:45:53 -03:00
void run ( HTMLTokenizer : : StopAtInsertionPoint = HTMLTokenizer : : StopAtInsertionPoint : : No ) ;
2024-03-18 00:22:27 -03:00
void run ( const URL : : URL & , HTMLTokenizer : : StopAtInsertionPoint = HTMLTokenizer : : StopAtInsertionPoint : : No ) ;
2020-05-23 19:14:23 -03:00
2024-11-14 12:01:23 -03:00
static void the_end ( GC : : Ref < DOM : : Document > , GC : : Ptr < HTMLParser > = nullptr ) ;
2023-12-19 09:51:34 -03:00
2020-07-26 14:37:56 -03:00
DOM : : Document & document ( ) ;
2024-06-25 16:55:58 -03:00
enum class AllowDeclarativeShadowRoots {
No ,
Yes ,
} ;
2024-11-14 12:01:23 -03:00
static Vector < GC : : Root < DOM : : Node > > parse_html_fragment ( DOM : : Element & context_element , StringView , AllowDeclarativeShadowRoots = AllowDeclarativeShadowRoots : : No ) ;
2024-06-25 05:49:54 -03:00
enum class SerializableShadowRoots {
No ,
Yes ,
} ;
2024-11-14 12:01:23 -03:00
static String serialize_html_fragment ( DOM : : Node const & , SerializableShadowRoots , Vector < GC : : Root < DOM : : ShadowRoot > > const & , DOM : : FragmentSerializationMode = DOM : : FragmentSerializationMode : : Inner ) ;
2020-06-25 18:42:08 -03:00
2020-05-23 19:14:23 -03:00
enum class InsertionMode {
# define __ENUMERATE_INSERTION_MODE(mode) mode,
ENUMERATE_INSERTION_MODES
# undef __ENUMERATE_INSERTION_MODE
} ;
InsertionMode insertion_mode ( ) const { return m_insertion_mode ; }
2023-11-04 06:19:21 -03:00
static bool is_special_tag ( FlyString const & tag_name , Optional < FlyString > const & namespace_ ) ;
2020-05-29 17:06:05 -03:00
2022-02-19 11:58:21 -03:00
HTMLTokenizer & tokenizer ( ) { return m_tokenizer ; }
2022-09-20 16:08:14 -03:00
// https://html.spec.whatwg.org/multipage/parsing.html#abort-a-parser
void abort ( ) ;
2022-02-19 11:58:21 -03:00
bool aborted ( ) const { return m_aborted ; }
2022-09-20 16:08:14 -03:00
bool stopped ( ) const { return m_stop_parsing ; }
2022-02-19 11:58:21 -03:00
size_t script_nesting_level ( ) const { return m_script_nesting_level ; }
2020-05-23 19:14:23 -03:00
private :
2024-04-03 22:56:58 -03:00
HTMLParser ( DOM : : Document & , StringView input , StringView encoding ) ;
2022-02-21 17:54:21 -03:00
HTMLParser ( DOM : : Document & ) ;
2022-10-17 05:46:11 -03:00
virtual void visit_edges ( Cell : : Visitor & ) override ;
2025-04-04 12:20:27 -03:00
virtual void initialize ( JS : : Realm & ) override ;
2022-10-17 05:46:11 -03:00
2022-04-01 14:58:27 -03:00
char const * insertion_mode_name ( ) const ;
2020-05-23 19:14:23 -03:00
2022-04-01 14:58:27 -03:00
DOM : : QuirksMode which_quirks_mode ( HTMLToken const & ) const ;
2020-07-18 17:17:17 -03:00
2020-05-23 19:14:23 -03:00
void handle_initial ( HTMLToken & ) ;
void handle_before_html ( HTMLToken & ) ;
void handle_before_head ( HTMLToken & ) ;
void handle_in_head ( HTMLToken & ) ;
void handle_in_head_noscript ( HTMLToken & ) ;
void handle_after_head ( HTMLToken & ) ;
void handle_in_body ( HTMLToken & ) ;
2020-05-23 19:49:22 -03:00
void handle_after_body ( HTMLToken & ) ;
void handle_after_after_body ( HTMLToken & ) ;
2020-05-23 19:14:23 -03:00
void handle_text ( HTMLToken & ) ;
2020-05-25 15:30:34 -03:00
void handle_in_table ( HTMLToken & ) ;
2020-05-27 19:27:46 -03:00
void handle_in_table_body ( HTMLToken & ) ;
void handle_in_row ( HTMLToken & ) ;
void handle_in_cell ( HTMLToken & ) ;
2020-05-30 12:57:41 -03:00
void handle_in_table_text ( HTMLToken & ) ;
2020-05-30 14:58:52 -03:00
void handle_in_select_in_table ( HTMLToken & ) ;
void handle_in_select ( HTMLToken & ) ;
2020-06-13 01:09:54 -03:00
void handle_in_caption ( HTMLToken & ) ;
2020-06-13 02:22:18 -03:00
void handle_in_column_group ( HTMLToken & ) ;
2020-06-21 01:58:03 -03:00
void handle_in_template ( HTMLToken & ) ;
void handle_in_frameset ( HTMLToken & ) ;
void handle_after_frameset ( HTMLToken & ) ;
void handle_after_after_frameset ( HTMLToken & ) ;
2020-05-23 19:14:23 -03:00
2020-05-28 13:55:18 -03:00
void stop_parsing ( ) { m_stop_parsing = true ; }
2023-10-01 04:07:44 -03:00
void generate_implied_end_tags ( FlyString const & exception = { } ) ;
2020-08-19 18:30:33 -03:00
void generate_all_implied_end_tags_thoroughly ( ) ;
2024-11-14 12:01:23 -03:00
GC : : Ref < DOM : : Element > create_element_for ( HTMLToken const & , Optional < FlyString > const & namespace_ , DOM : : Node & intended_parent ) ;
2020-06-21 12:00:55 -03:00
struct AdjustedInsertionLocation {
2024-11-14 12:01:23 -03:00
GC : : Ptr < DOM : : Node > parent ;
GC : : Ptr < DOM : : Node > insert_before_sibling ;
2020-06-21 12:00:55 -03:00
} ;
2024-11-14 12:01:23 -03:00
AdjustedInsertionLocation find_appropriate_place_for_inserting_node ( GC : : Ptr < DOM : : Element > override_target = nullptr ) ;
2020-06-21 12:00:55 -03:00
2024-11-14 12:01:23 -03:00
void insert_an_element_at_the_adjusted_insertion_location ( GC : : Ref < DOM : : Element > ) ;
2024-06-25 04:43:50 -03:00
2020-07-26 14:37:56 -03:00
DOM : : Text * find_character_insertion_node ( ) ;
2020-06-03 16:53:08 -03:00
void flush_character_insertions ( ) ;
2024-06-25 04:43:50 -03:00
enum class OnlyAddToElementStack {
No ,
Yes ,
} ;
2024-11-14 12:01:23 -03:00
GC : : Ref < DOM : : Element > insert_foreign_element ( HTMLToken const & , Optional < FlyString > const & namespace_ , OnlyAddToElementStack ) ;
GC : : Ref < DOM : : Element > insert_html_element ( HTMLToken const & ) ;
[ [ nodiscard ] ] GC : : Ptr < DOM : : Element > current_node ( ) ;
[ [ nodiscard ] ] GC : : Ptr < DOM : : Element > adjusted_current_node ( ) ;
[ [ nodiscard ] ] GC : : Ptr < DOM : : Element > node_before_current_node ( ) ;
2020-05-24 14:51:50 -03:00
void insert_character ( u32 data ) ;
2020-05-24 15:29:01 -03:00
void insert_comment ( HTMLToken & ) ;
2020-05-24 14:51:50 -03:00
void reconstruct_the_active_formatting_elements ( ) ;
2020-05-24 17:21:25 -03:00
void close_a_p_element ( ) ;
2020-05-24 14:51:50 -03:00
void process_using_the_rules_for ( InsertionMode , HTMLToken & ) ;
2020-10-11 21:51:28 -03:00
void process_using_the_rules_for_foreign_content ( HTMLToken & ) ;
2020-05-24 15:36:43 -03:00
void parse_generic_raw_text_element ( HTMLToken & ) ;
2020-05-24 17:00:46 -03:00
void increment_script_nesting_level ( ) ;
void decrement_script_nesting_level ( ) ;
2020-07-21 15:03:05 -03:00
void reset_the_insertion_mode_appropriately ( ) ;
2020-05-30 11:22:25 -03:00
2020-06-21 01:58:03 -03:00
void adjust_mathml_attributes ( HTMLToken & ) ;
2020-10-11 21:51:28 -03:00
void adjust_svg_tag_names ( HTMLToken & ) ;
2020-06-21 01:58:03 -03:00
void adjust_svg_attributes ( HTMLToken & ) ;
2023-11-03 19:26:44 -03:00
static void adjust_foreign_attributes ( HTMLToken & ) ;
2020-06-21 01:58:03 -03:00
2020-05-30 11:22:25 -03:00
enum AdoptionAgencyAlgorithmOutcome {
DoNothing ,
RunAnyOtherEndTagSteps ,
} ;
AdoptionAgencyAlgorithmOutcome run_the_adoption_agency_algorithm ( HTMLToken & ) ;
2020-05-27 19:27:46 -03:00
void clear_the_stack_back_to_a_table_context ( ) ;
void clear_the_stack_back_to_a_table_body_context ( ) ;
void clear_the_stack_back_to_a_table_row_context ( ) ;
2020-05-28 06:45:40 -03:00
void close_the_cell ( ) ;
2020-05-23 19:14:23 -03:00
InsertionMode m_insertion_mode { InsertionMode : : Initial } ;
2020-05-24 15:24:43 -03:00
InsertionMode m_original_insertion_mode { InsertionMode : : Initial } ;
2020-05-24 14:51:50 -03:00
2020-05-24 14:24:36 -03:00
StackOfOpenElements m_stack_of_open_elements ;
2020-06-21 01:58:03 -03:00
Vector < InsertionMode > m_stack_of_template_insertion_modes ;
2020-05-27 18:22:42 -03:00
ListOfActiveFormattingElements m_list_of_active_formatting_elements ;
2020-05-24 14:51:50 -03:00
2020-05-23 19:14:23 -03:00
HTMLTokenizer m_tokenizer ;
2025-02-19 12:54:28 -03:00
bool m_next_line_feed_can_be_ignored { false } ;
2020-05-23 19:14:23 -03:00
bool m_foster_parenting { false } ;
2020-05-23 19:49:22 -03:00
bool m_frameset_ok { true } ;
bool m_parsing_fragment { false } ;
2022-09-23 16:43:17 -03:00
// https://html.spec.whatwg.org/multipage/parsing.html#scripting-flag
// The scripting flag is set to "enabled" if scripting was enabled for the Document with which the parser is associated when the parser was created, and "disabled" otherwise.
2020-05-24 15:36:43 -03:00
bool m_scripting_enabled { true } ;
2022-09-23 16:43:17 -03:00
2020-05-24 17:00:46 -03:00
bool m_invoked_via_document_write { false } ;
2020-05-27 18:01:04 -03:00
bool m_aborted { false } ;
2020-05-24 17:00:46 -03:00
bool m_parser_pause_flag { false } ;
2020-05-28 13:55:18 -03:00
bool m_stop_parsing { false } ;
2020-05-24 17:00:46 -03:00
size_t m_script_nesting_level { 0 } ;
2020-05-23 19:14:23 -03:00
2022-08-28 08:42:07 -03:00
JS : : Realm & realm ( ) ;
2024-11-14 12:01:23 -03:00
GC : : Ptr < DOM : : Document > m_document ;
GC : : Ptr < HTMLHeadElement > m_head_element ;
GC : : Ptr < HTMLFormElement > m_form_element ;
GC : : Ptr < DOM : : Element > m_context_element ;
2020-05-30 12:57:41 -03:00
2025-04-04 12:20:27 -03:00
# ifdef LIBWEB_USE_SWIFT
GC : : ForeignPtr < Web : : SpeculativeHTMLParser > m_speculative_parser ;
# endif
2020-05-30 12:57:41 -03:00
Vector < HTMLToken > m_pending_table_character_tokens ;
2020-06-03 16:53:08 -03:00
2024-11-14 12:01:23 -03:00
GC : : Ptr < DOM : : Text > m_character_insertion_node ;
2020-06-03 16:53:08 -03:00
StringBuilder m_character_insertion_builder ;
2025-03-22 22:12:30 -03:00
} SWIFT_UNSAFE_REFERENCE ;
2020-05-23 19:14:23 -03:00
2025-04-15 18:18:27 -03:00
RefPtr < CSS : : CSSStyleValue const > parse_dimension_value ( StringView ) ;
RefPtr < CSS : : CSSStyleValue const > parse_nonzero_dimension_value ( StringView ) ;
2024-01-16 15:04:45 -03:00
Optional < Color > parse_legacy_color_value ( StringView ) ;
2022-03-26 10:29:52 -03:00
2025-03-22 22:12:30 -03:00
// Swift interop
using HTMLParserGCPtr = GC : : Ptr < HTMLParser > ;
using HTMLParserGCRef = GC : : Ref < HTMLParser > ;
2020-05-23 19:14:23 -03:00
}