diff --git a/Userland/Libraries/LibWeb/DOM/Range.cpp b/Userland/Libraries/LibWeb/DOM/Range.cpp index dae53a5c32..9c4c25ca8d 100644 --- a/Userland/Libraries/LibWeb/DOM/Range.cpp +++ b/Userland/Libraries/LibWeb/DOM/Range.cpp @@ -227,6 +227,93 @@ ExceptionOr Range::set_end_after(Node& node) return set_start_or_end(*parent, node.index() + 1, StartOrEnd::End); } +// https://dom.spec.whatwg.org/#dom-range-compareboundarypoints +ExceptionOr Range::compare_boundary_points(u16 how, Range const& source_range) const +{ + // 1. If how is not one of + // - START_TO_START, + // - START_TO_END, + // - END_TO_END, and + // - END_TO_START, + // then throw a "NotSupportedError" DOMException. + if (how != HowToCompareBoundaryPoints::START_TO_START && how != HowToCompareBoundaryPoints::START_TO_END && how != HowToCompareBoundaryPoints::END_TO_END && how != HowToCompareBoundaryPoints::END_TO_START) + return NotSupportedError::create(String::formatted("Expected 'how' to be one of START_TO_START (0), START_TO_END (1), END_TO_END (2) or END_TO_START (3), got {}", how)); + + // 2. If this’s root is not the same as sourceRange’s root, then throw a "WrongDocumentError" DOMException. + if (&root() != &source_range.root()) + return WrongDocumentError::create("This range is not in the same tree as the source range."); + + RefPtr this_point_node; + u32 this_point_offset = 0; + + RefPtr other_point_node; + u32 other_point_offset = 0; + + // 3. If how is: + switch (how) { + case HowToCompareBoundaryPoints::START_TO_START: + // -> START_TO_START: + // Let this point be this’s start. Let other point be sourceRange’s start. + this_point_node = m_start_container; + this_point_offset = m_start_offset; + + other_point_node = source_range.m_start_container; + other_point_offset = source_range.m_start_offset; + break; + case HowToCompareBoundaryPoints::START_TO_END: + // -> START_TO_END: + // Let this point be this’s end. Let other point be sourceRange’s start. + this_point_node = m_end_container; + this_point_offset = m_end_offset; + + other_point_node = source_range.m_start_container; + other_point_offset = source_range.m_start_offset; + break; + case HowToCompareBoundaryPoints::END_TO_END: + // -> END_TO_END: + // Let this point be this’s end. Let other point be sourceRange’s end. + this_point_node = m_end_container; + this_point_offset = m_end_offset; + + other_point_node = source_range.m_end_container; + other_point_offset = source_range.m_end_offset; + break; + case HowToCompareBoundaryPoints::END_TO_START: + // -> END_TO_START: + // Let this point be this’s start. Let other point be sourceRange’s end. + this_point_node = m_start_container; + this_point_offset = m_start_offset; + + other_point_node = source_range.m_end_container; + other_point_offset = source_range.m_end_offset; + break; + default: + VERIFY_NOT_REACHED(); + } + + VERIFY(this_point_node); + VERIFY(other_point_node); + + // 4. If the position of this point relative to other point is + auto relative_position = position_of_boundary_point_relative_to_other_boundary_point(*this_point_node, this_point_offset, *other_point_node, other_point_offset); + switch (relative_position) { + case RelativeBoundaryPointPosition::Before: + // -> before + // Return −1. + return -1; + case RelativeBoundaryPointPosition::Equal: + // -> equal + // Return 0. + return 0; + case RelativeBoundaryPointPosition::After: + // -> after + // Return 1. + return 1; + default: + VERIFY_NOT_REACHED(); + } +} + NonnullRefPtr Range::clone_range() const { return adopt_ref(*new Range(const_cast(*m_start_container), m_start_offset, const_cast(*m_end_container), m_end_offset)); diff --git a/Userland/Libraries/LibWeb/DOM/Range.h b/Userland/Libraries/LibWeb/DOM/Range.h index b145a30f98..e23814e428 100644 --- a/Userland/Libraries/LibWeb/DOM/Range.h +++ b/Userland/Libraries/LibWeb/DOM/Range.h @@ -31,6 +31,16 @@ public: ExceptionOr set_end_before(Node& node); ExceptionOr set_end_after(Node& node); + // https://dom.spec.whatwg.org/#dom-range-start_to_start + enum HowToCompareBoundaryPoints : u16 { + START_TO_START = 0, + START_TO_END = 1, + END_TO_END = 2, + END_TO_START = 3, + }; + + ExceptionOr compare_boundary_points(u16 how, Range const& source_range) const; + NonnullRefPtr inverted() const; NonnullRefPtr normalized() const; NonnullRefPtr clone_range() const; diff --git a/Userland/Libraries/LibWeb/DOM/Range.idl b/Userland/Libraries/LibWeb/DOM/Range.idl index 792abf3f6a..0faaddfcc9 100644 --- a/Userland/Libraries/LibWeb/DOM/Range.idl +++ b/Userland/Libraries/LibWeb/DOM/Range.idl @@ -15,6 +15,12 @@ interface Range : AbstractRange { undefined setEndBefore(Node node); undefined setEndAfter(Node node); + const unsigned short START_TO_START = 0; + const unsigned short START_TO_END = 1; + const unsigned short END_TO_END = 2; + const unsigned short END_TO_START = 3; + short compareBoundaryPoints(unsigned short how, Range sourceRange); + Range cloneRange(); };