/* * 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; }; using Selection::Selection; // Below algorithms are specified here: // https://w3c.github.io/editing/docs/execCommand/#assorted-common-algorithms 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); 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); 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_node(GC::Ref); bool is_in_same_editing_host(GC::Ref, GC::Ref); bool is_inline_node(GC::Ref); bool is_invisible_node(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_single_line_container(GC::Ref); bool is_visible_node(GC::Ref); bool is_whitespace_node(GC::Ref); DOM::BoundaryPoint last_equivalent_point(DOM::BoundaryPoint); 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); bool precedes_a_line_break(GC::Ref); Optional previous_equivalent_point(DOM::BoundaryPoint); Vector record_current_states_and_values(GC::Ref); 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 restore_states_and_values(GC::Ref, Vector const&); void restore_the_values_of_nodes(Vector const&); 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&); GC::Ptr wrap(Vector>, Function)> sibling_criteria, Function()> new_parent_instructions); // Utility methods: bool has_visible_children(GC::Ref); bool is_heading(FlyString const&); Optional resolved_display(GC::Ref); Optional resolved_keyword(GC::Ref, CSS::PropertyID); Optional> resolved_value(GC::Ref, CSS::PropertyID); }