/src/serenity/Userland/Libraries/LibWeb/DOM/Range.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2020, the SerenityOS developers. |
3 | | * Copyright (c) 2022, Luke Wilde <lukew@serenityos.org> |
4 | | * Copyright (c) 2022-2023, Andreas Kling <kling@serenityos.org> |
5 | | * |
6 | | * SPDX-License-Identifier: BSD-2-Clause |
7 | | */ |
8 | | |
9 | | #pragma once |
10 | | |
11 | | #include <LibWeb/DOM/AbstractRange.h> |
12 | | #include <LibWeb/Selection/Selection.h> |
13 | | #include <LibWeb/WebIDL/Types.h> |
14 | | |
15 | | namespace Web::DOM { |
16 | | |
17 | | enum class RelativeBoundaryPointPosition { |
18 | | Equal, |
19 | | Before, |
20 | | After, |
21 | | }; |
22 | | |
23 | | // https://dom.spec.whatwg.org/#concept-range-bp-position |
24 | | RelativeBoundaryPointPosition position_of_boundary_point_relative_to_other_boundary_point(Node const& node_a, u32 offset_a, Node const& node_b, u32 offset_b); |
25 | | |
26 | | class Range final : public AbstractRange { |
27 | | WEB_PLATFORM_OBJECT(Range, AbstractRange); |
28 | | JS_DECLARE_ALLOCATOR(Range); |
29 | | |
30 | | public: |
31 | | [[nodiscard]] static JS::NonnullGCPtr<Range> create(Document&); |
32 | | [[nodiscard]] static JS::NonnullGCPtr<Range> create(HTML::Window&); |
33 | | [[nodiscard]] static JS::NonnullGCPtr<Range> create(Node& start_container, WebIDL::UnsignedLong start_offset, Node& end_container, WebIDL::UnsignedLong end_offset); |
34 | | static WebIDL::ExceptionOr<JS::NonnullGCPtr<Range>> construct_impl(JS::Realm&); |
35 | | |
36 | | virtual ~Range() override; |
37 | | |
38 | | WebIDL::ExceptionOr<void> set_start(Node& node, WebIDL::UnsignedLong offset); |
39 | | WebIDL::ExceptionOr<void> set_end(Node& node, WebIDL::UnsignedLong offset); |
40 | | WebIDL::ExceptionOr<void> set_start_before(Node& node); |
41 | | WebIDL::ExceptionOr<void> set_start_after(Node& node); |
42 | | WebIDL::ExceptionOr<void> set_end_before(Node& node); |
43 | | WebIDL::ExceptionOr<void> set_end_after(Node& node); |
44 | | WebIDL::ExceptionOr<void> select_node(Node& node); |
45 | | void collapse(bool to_start); |
46 | | WebIDL::ExceptionOr<void> select_node_contents(Node&); |
47 | | |
48 | | void increase_start_offset(Badge<Node>, WebIDL::UnsignedLong); |
49 | | void increase_end_offset(Badge<Node>, WebIDL::UnsignedLong); |
50 | | void decrease_start_offset(Badge<Node>, WebIDL::UnsignedLong); |
51 | | void decrease_end_offset(Badge<Node>, WebIDL::UnsignedLong); |
52 | | |
53 | | // https://dom.spec.whatwg.org/#dom-range-start_to_start |
54 | | enum HowToCompareBoundaryPoints : WebIDL::UnsignedShort { |
55 | | START_TO_START = 0, |
56 | | START_TO_END = 1, |
57 | | END_TO_END = 2, |
58 | | END_TO_START = 3, |
59 | | }; |
60 | | |
61 | | WebIDL::ExceptionOr<WebIDL::Short> compare_boundary_points(WebIDL::UnsignedShort how, Range const& source_range) const; |
62 | | |
63 | | JS::NonnullGCPtr<Range> inverted() const; |
64 | | JS::NonnullGCPtr<Range> normalized() const; |
65 | | JS::NonnullGCPtr<Range> clone_range() const; |
66 | | |
67 | | JS::NonnullGCPtr<Node> common_ancestor_container() const; |
68 | | |
69 | | // https://dom.spec.whatwg.org/#dom-range-detach |
70 | | void detach() const |
71 | 0 | { |
72 | | // The detach() method steps are to do nothing. |
73 | | // Note: Its functionality (disabling a Range object) was removed, but the method itself is preserved for compatibility. |
74 | 0 | } |
75 | | |
76 | | bool intersects_node(Node const&) const; |
77 | | WebIDL::ExceptionOr<bool> is_point_in_range(Node const&, WebIDL::UnsignedLong offset) const; |
78 | | WebIDL::ExceptionOr<WebIDL::Short> compare_point(Node const&, WebIDL::UnsignedLong offset) const; |
79 | | |
80 | | WebIDL::ExceptionOr<void> delete_contents(); |
81 | | WebIDL::ExceptionOr<JS::NonnullGCPtr<DocumentFragment>> extract_contents(); |
82 | | WebIDL::ExceptionOr<JS::NonnullGCPtr<DocumentFragment>> clone_contents(); |
83 | | |
84 | | WebIDL::ExceptionOr<void> insert_node(JS::NonnullGCPtr<Node>); |
85 | | WebIDL::ExceptionOr<void> surround_contents(JS::NonnullGCPtr<Node> new_parent); |
86 | | |
87 | | String to_string() const; |
88 | | |
89 | | static HashTable<Range*>& live_ranges(); |
90 | | |
91 | | JS::NonnullGCPtr<Geometry::DOMRectList> get_client_rects(); |
92 | | JS::NonnullGCPtr<Geometry::DOMRect> get_bounding_client_rect(); |
93 | | |
94 | | bool contains_node(Node const&) const; |
95 | | |
96 | | void set_associated_selection(Badge<Selection::Selection>, JS::GCPtr<Selection::Selection>); |
97 | | |
98 | | WebIDL::ExceptionOr<JS::NonnullGCPtr<DocumentFragment>> create_contextual_fragment(String const& fragment); |
99 | | |
100 | | private: |
101 | | explicit Range(Document&); |
102 | | Range(Node& start_container, WebIDL::UnsignedLong start_offset, Node& end_container, WebIDL::UnsignedLong end_offset); |
103 | | |
104 | | virtual void initialize(JS::Realm&) override; |
105 | | virtual void visit_edges(Cell::Visitor&) override; |
106 | | |
107 | | Node& root(); |
108 | | Node const& root() const; |
109 | | |
110 | | void update_associated_selection(); |
111 | | |
112 | | enum class StartOrEnd { |
113 | | Start, |
114 | | End, |
115 | | }; |
116 | | |
117 | | WebIDL::ExceptionOr<void> set_start_or_end(Node& node, u32 offset, StartOrEnd start_or_end); |
118 | | WebIDL::ExceptionOr<void> select(Node& node); |
119 | | |
120 | | WebIDL::ExceptionOr<JS::NonnullGCPtr<DocumentFragment>> extract(); |
121 | | WebIDL::ExceptionOr<JS::NonnullGCPtr<DocumentFragment>> clone_the_contents(); |
122 | | WebIDL::ExceptionOr<void> insert(JS::NonnullGCPtr<Node>); |
123 | | |
124 | | bool partially_contains_node(Node const&) const; |
125 | | |
126 | | JS::GCPtr<Selection::Selection> m_associated_selection; |
127 | | }; |
128 | | |
129 | | } |