#pragma once
#include "BoundaryPoint.h"
namespace WebCore {
struct SimpleRange {
BoundaryPoint start;
BoundaryPoint end;
Node& startContainer() const { return start.container.get(); }
unsigned startOffset() const { return start.offset; }
Node& endContainer() const { return end.container.get(); }
unsigned endOffset() const { return end.offset; }
bool collapsed() const { return start == end; }
WEBCORE_EXPORT SimpleRange(const BoundaryPoint&, const BoundaryPoint&);
WEBCORE_EXPORT SimpleRange(BoundaryPoint&&, BoundaryPoint&&);
};
SimpleRange makeSimpleRangeHelper(BoundaryPoint&&, BoundaryPoint&&);
Optional<SimpleRange> makeSimpleRangeHelper(Optional<BoundaryPoint>&&, Optional<BoundaryPoint>&&);
SimpleRange makeSimpleRangeHelper(BoundaryPoint&&);
Optional<SimpleRange> makeSimpleRangeHelper(Optional<BoundaryPoint>&&);
inline BoundaryPoint makeBoundaryPointHelper(const BoundaryPoint& point) { return point; }
inline BoundaryPoint makeBoundaryPointHelper(BoundaryPoint&& point) { return WTFMove(point); }
inline Optional<BoundaryPoint> makeBoundaryPointHelper(const Optional<BoundaryPoint>& point) { return point; }
inline Optional<BoundaryPoint> makeBoundaryPointHelper(Optional<BoundaryPoint>&& point) { return WTFMove(point); }
template<typename T> auto makeBoundaryPointHelper(T&& argument) -> decltype(makeBoundaryPoint(std::forward<T>(argument))) { return makeBoundaryPoint(std::forward<T>(argument)); }
template<typename ...T> auto makeSimpleRange(T&& ...arguments) -> decltype(makeSimpleRangeHelper(makeBoundaryPointHelper(std::forward<T>(arguments))...)) { return makeSimpleRangeHelper(makeBoundaryPointHelper(std::forward<T>(arguments))...); }
WEBCORE_EXPORT Optional<SimpleRange> makeRangeSelectingNode(Node&);
WEBCORE_EXPORT SimpleRange makeRangeSelectingNodeContents(Node&);
WEBCORE_EXPORT RefPtr<Node> commonInclusiveAncestor(const SimpleRange&);
bool operator==(const SimpleRange&, const SimpleRange&);
class IntersectingNodeRange;
IntersectingNodeRange intersectingNodes(const SimpleRange&);
struct OffsetRange {
unsigned start { 0 };
unsigned end { 0 };
};
OffsetRange characterDataOffsetRange(const SimpleRange&, const Node&);
class IntersectingNodeIterator : public std::iterator<std::forward_iterator_tag, Node> {
public:
IntersectingNodeIterator(const SimpleRange&);
Node& operator*() const { return *m_node; }
Node* operator->() const { ASSERT(m_node); return m_node.get(); }
operator bool() const { return m_node; }
bool operator!() const { return !m_node; }
bool operator!=(const std::nullptr_t) const { return m_node; }
IntersectingNodeIterator& operator++() { advance(); return *this; }
void advance();
void advanceSkippingChildren();
private:
void enforceEndInvariant();
RefPtr<Node> m_node;
RefPtr<Node> m_pastLastNode;
};
class IntersectingNodeRange {
public:
IntersectingNodeRange(const SimpleRange&);
IntersectingNodeIterator begin() const { return m_range; }
static constexpr std::nullptr_t end() { return nullptr; }
private:
SimpleRange m_range;
};
inline IntersectingNodeRange::IntersectingNodeRange(const SimpleRange& range)
: m_range(range)
{
}
inline IntersectingNodeRange intersectingNodes(const SimpleRange& range)
{
return { range };
}
inline SimpleRange makeSimpleRangeHelper(BoundaryPoint&& start, BoundaryPoint&& end)
{
return { WTFMove(start), WTFMove(end) };
}
inline Optional<SimpleRange> makeSimpleRangeHelper(Optional<BoundaryPoint>&& start, Optional<BoundaryPoint>&& end)
{
if (!start || !end)
return WTF::nullopt;
return makeSimpleRangeHelper(WTFMove(*start), WTFMove(*end));
}
inline SimpleRange makeSimpleRangeHelper(BoundaryPoint&& point)
{
auto end = point;
return makeSimpleRangeHelper(WTFMove(point), WTFMove(end));
}
inline Optional<SimpleRange> makeSimpleRangeHelper(Optional<BoundaryPoint>&& point)
{
if (!point)
return WTF::nullopt;
return makeSimpleRangeHelper(WTFMove(*point));
}
}