/* * Copyright (c) 2024-2025, Jelle Raaijmakers * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include namespace Web::Editing { // https://w3c.github.io/editing/docs/execCommand/#record-the-values struct RecordedNodeValue { GC::Ref node; FlyString command; Optional specified_command_value; }; // https://w3c.github.io/editing/docs/execCommand/#record-current-states-and-values struct RecordedOverride { FlyString command; Variant value; }; // https://w3c.github.io/editing/docs/execCommand/#selection's-list-state enum class SelectionsListState : u8 { Ol, Ul, Mixed, MixedOl, MixedUl, None, }; // https://w3c.github.io/editing/docs/execCommand/#justify-the-selection enum class JustifyAlignment : u8 { Center, Justify, Left, Right, }; using Selection::Selection; // Below algorithms are specified here: // https://w3c.github.io/editing/docs/execCommand/#assorted-common-algorithms GC::Ptr active_range(DOM::Document const&); JustifyAlignment alignment_value_of_node(GC::Ptr); void autolink(DOM::BoundaryPoint); GC::Ref block_extend_a_range(GC::Ref); GC::Ptr block_node_of_node(GC::Ref); String canonical_space_sequence(u32 length, bool non_breaking_start, bool non_breaking_end); void canonicalize_whitespace(DOM::BoundaryPoint, bool fix_collapsed_space = true); Vector> clear_the_value(FlyString const&, GC::Ref); void delete_the_selection(Selection&, bool block_merging = true, bool strip_wrappers = true, Selection::Direction direction = Selection::Direction::Forwards); GC::Ptr editing_host_of_node(GC::Ref); Optional effective_command_value(GC::Ptr, FlyString const& command); DOM::BoundaryPoint first_equivalent_point(DOM::BoundaryPoint); void fix_disallowed_ancestors_of_node(GC::Ref); bool follows_a_line_break(GC::Ref); void force_the_value(GC::Ref, FlyString const&, Optional); void indent(Vector>); bool is_allowed_child_of_node(Variant, FlyString> child, Variant, FlyString> parent); bool is_block_boundary_point(DOM::BoundaryPoint); bool is_block_end_point(DOM::BoundaryPoint); bool is_block_node(GC::Ref); bool is_block_start_point(DOM::BoundaryPoint); bool is_collapsed_block_prop(GC::Ref); bool is_collapsed_line_break(GC::Ref); bool is_collapsed_whitespace_node(GC::Ref); bool is_effectively_contained_in_range(GC::Ref, GC::Ref); bool is_element_with_inline_contents(GC::Ref); bool is_extraneous_line_break(GC::Ref); bool is_formattable_block_name(FlyString const&); bool is_formattable_node(GC::Ref); bool is_in_same_editing_host(GC::Ref, GC::Ref); bool is_indentation_element(GC::Ref); bool is_inline_node(GC::Ref); bool is_invisible_node(GC::Ref); bool is_modifiable_element(GC::Ref); bool is_name_of_an_element_with_inline_contents(FlyString const&); bool is_non_list_single_line_container(GC::Ref); bool is_prohibited_paragraph_child(GC::Ref); bool is_prohibited_paragraph_child_name(FlyString const&); bool is_remove_format_candidate(GC::Ref); bool is_simple_indentation_element(GC::Ref); bool is_simple_modifiable_element(GC::Ref); bool is_single_line_container(GC::Ref); bool is_visible_node(GC::Ref); bool is_whitespace_node(GC::Ref); void justify_the_selection(DOM::Document&, JustifyAlignment); DOM::BoundaryPoint last_equivalent_point(DOM::BoundaryPoint); String legacy_font_size(int); void move_node_preserving_ranges(GC::Ref, GC::Ref new_parent, u32 new_index); Optional next_equivalent_point(DOM::BoundaryPoint); void normalize_sublists_in_node(GC::Ref); void outdent(GC::Ref); bool precedes_a_line_break(GC::Ref); Optional previous_equivalent_point(DOM::BoundaryPoint); void push_down_values(FlyString const&, GC::Ref, Optional); Vector record_current_overrides(DOM::Document const&); Vector record_current_states_and_values(DOM::Document const&); Vector record_the_values_of_nodes(Vector> const&); void remove_extraneous_line_breaks_at_the_end_of_node(GC::Ref); void remove_extraneous_line_breaks_before_node(GC::Ref); void remove_extraneous_line_breaks_from_a_node(GC::Ref); void remove_node_preserving_its_descendants(GC::Ref); void reorder_modifiable_descendants(GC::Ref, FlyString const&, Optional); void restore_states_and_values(DOM::Document&, Vector const&); void restore_the_values_of_nodes(Vector const&); SelectionsListState selections_list_state(DOM::Document const&); void set_the_selections_value(DOM::Document&, FlyString const&, Optional); GC::Ref set_the_tag_name(GC::Ref, FlyString const&); Optional specified_command_value(GC::Ref, FlyString const& command); void split_the_parent_of_nodes(Vector> const&); void toggle_lists(DOM::Document&, FlyString const&); bool values_are_equivalent(FlyString const&, Optional, Optional); bool values_are_loosely_equivalent(FlyString const&, Optional, Optional); GC::Ptr wrap(Vector>, Function)> sibling_criteria, Function()> new_parent_instructions); // Utility methods: GC::Ptr first_formattable_node_effectively_contained(GC::Ptr); CSSPixels font_size_to_pixel_size(StringView); void for_each_node_effectively_contained_in_range(GC::Ptr, Function)>); bool has_visible_children(GC::Ref); bool is_heading(FlyString const&); String justify_alignment_to_string(JustifyAlignment); Array named_font_sizes(); Optional> property_in_style_attribute(GC::Ref, CSS::PropertyID); Optional resolved_display(GC::Ref); Optional resolved_keyword(GC::Ref, CSS::PropertyID); Optional> resolved_value(GC::Ref, CSS::PropertyID); void take_the_action_for_command(DOM::Document&, FlyString const&, String const&); bool value_list_contains_keyword(CSS::StyleValueList const&, CSS::Keyword); }