diff --git a/Userland/Libraries/LibWeb/DOM/Range.cpp b/Userland/Libraries/LibWeb/DOM/Range.cpp index 28b7097efe..6c95a982e5 100644 --- a/Userland/Libraries/LibWeb/DOM/Range.cpp +++ b/Userland/Libraries/LibWeb/DOM/Range.cpp @@ -473,4 +473,33 @@ ExceptionOr Range::is_point_in_range(Node const& node, u32 offset) const return true; } +// https://dom.spec.whatwg.org/#dom-range-comparepoint +ExceptionOr Range::compare_point(Node const& node, u32 offset) const +{ + // 1. If node’s root is different from this’s root, then throw a "WrongDocumentError" DOMException. + if (&node.root() != &root()) + return WrongDocumentError::create("Given node is not in the same document as the range."); + + // 2. If node is a doctype, then throw an "InvalidNodeTypeError" DOMException. + if (is(node)) + return InvalidNodeTypeError::create("Node cannot be a DocumentType."); + + // 3. If offset is greater than node’s length, then throw an "IndexSizeError" DOMException. + if (offset > node.length()) + return IndexSizeError::create(String::formatted("Node does not contain a child at offset {}", offset)); + + // 4. If (node, offset) is before start, return −1. + auto relative_position_to_start = position_of_boundary_point_relative_to_other_boundary_point(node, offset, m_start_container, m_start_offset); + if (relative_position_to_start == RelativeBoundaryPointPosition::Before) + return -1; + + // 5. If (node, offset) is after end, return 1. + auto relative_position_to_end = position_of_boundary_point_relative_to_other_boundary_point(node, offset, m_end_container, m_end_offset); + if (relative_position_to_end == RelativeBoundaryPointPosition::After) + return 1; + + // 6. Return 0. + return 0; +} + } diff --git a/Userland/Libraries/LibWeb/DOM/Range.h b/Userland/Libraries/LibWeb/DOM/Range.h index 0b28978e8c..f7d73b1a85 100644 --- a/Userland/Libraries/LibWeb/DOM/Range.h +++ b/Userland/Libraries/LibWeb/DOM/Range.h @@ -59,6 +59,7 @@ public: bool intersects_node(Node const&) const; ExceptionOr is_point_in_range(Node const&, u32 offset) const; + ExceptionOr compare_point(Node const&, u32 offset) const; private: explicit Range(Document&); diff --git a/Userland/Libraries/LibWeb/DOM/Range.idl b/Userland/Libraries/LibWeb/DOM/Range.idl index 750ed462e1..900c9ceec0 100644 --- a/Userland/Libraries/LibWeb/DOM/Range.idl +++ b/Userland/Libraries/LibWeb/DOM/Range.idl @@ -28,6 +28,7 @@ interface Range : AbstractRange { undefined detach(); boolean isPointInRange(Node node, unsigned long offset); + short comparePoint(Node node, unsigned long offset); boolean intersectsNode(Node node);