150 lines
4.2 KiB
C++
150 lines
4.2 KiB
C++
/*
|
|
* Copyright (C) 2008-2020 Apple Inc. All Rights Reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
|
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
|
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "BoundaryPoint.h"
|
|
#include "CharacterData.h"
|
|
|
|
namespace WebCore {
|
|
|
|
class RangeBoundaryPoint {
|
|
public:
|
|
explicit RangeBoundaryPoint(Node& container);
|
|
|
|
Node& container() const;
|
|
unsigned offset() const;
|
|
Node* childBefore() const;
|
|
|
|
void set(Ref<Node>&& container, unsigned offset, Node* childBefore);
|
|
void setOffset(unsigned);
|
|
|
|
void setToBeforeNode(Node&);
|
|
void setToAfterNode(Node&);
|
|
void setToBeforeContents(Ref<Node>&&);
|
|
void setToAfterContents(Ref<Node>&&);
|
|
|
|
void childBeforeWillBeRemoved();
|
|
void invalidateOffset();
|
|
|
|
private:
|
|
Ref<Node> m_container;
|
|
unsigned m_offset { 0 };
|
|
RefPtr<Node> m_childBefore;
|
|
};
|
|
|
|
BoundaryPoint makeBoundaryPoint(const RangeBoundaryPoint&);
|
|
|
|
inline RangeBoundaryPoint::RangeBoundaryPoint(Node& container)
|
|
: m_container(container)
|
|
{
|
|
}
|
|
|
|
inline Node& RangeBoundaryPoint::container() const
|
|
{
|
|
return m_container;
|
|
}
|
|
|
|
inline Node* RangeBoundaryPoint::childBefore() const
|
|
{
|
|
return m_childBefore.get();
|
|
}
|
|
|
|
inline unsigned RangeBoundaryPoint::offset() const
|
|
{
|
|
return m_offset;
|
|
}
|
|
|
|
inline void RangeBoundaryPoint::set(Ref<Node>&& container, unsigned offset, Node* childBefore)
|
|
{
|
|
ASSERT(childBefore == (offset ? container->traverseToChildAt(offset - 1) : nullptr));
|
|
m_container = WTFMove(container);
|
|
m_offset = offset;
|
|
m_childBefore = childBefore;
|
|
}
|
|
|
|
inline void RangeBoundaryPoint::setOffset(unsigned offset)
|
|
{
|
|
ASSERT(m_container->isCharacterDataNode());
|
|
ASSERT(m_offset);
|
|
ASSERT(!m_childBefore);
|
|
m_offset = offset;
|
|
}
|
|
|
|
inline void RangeBoundaryPoint::setToBeforeNode(Node& child)
|
|
{
|
|
ASSERT(child.parentNode());
|
|
m_container = *child.parentNode();
|
|
m_offset = child.computeNodeIndex();
|
|
m_childBefore = child.previousSibling();
|
|
}
|
|
|
|
inline void RangeBoundaryPoint::setToAfterNode(Node& child)
|
|
{
|
|
ASSERT(child.parentNode());
|
|
m_container = *child.parentNode();
|
|
m_offset = child.computeNodeIndex() + 1;
|
|
m_childBefore = &child;
|
|
}
|
|
|
|
inline void RangeBoundaryPoint::setToBeforeContents(Ref<Node>&& container)
|
|
{
|
|
m_container = WTFMove(container);
|
|
m_offset = 0;
|
|
m_childBefore = nullptr;
|
|
}
|
|
|
|
inline void RangeBoundaryPoint::setToAfterContents(Ref<Node>&& container)
|
|
{
|
|
m_container = WTFMove(container);
|
|
m_offset = m_container->length();
|
|
m_childBefore = m_container->lastChild();
|
|
}
|
|
|
|
inline void RangeBoundaryPoint::childBeforeWillBeRemoved()
|
|
{
|
|
ASSERT(m_offset);
|
|
ASSERT(m_childBefore);
|
|
--m_offset;
|
|
m_childBefore = m_childBefore->previousSibling();
|
|
}
|
|
|
|
inline void RangeBoundaryPoint::invalidateOffset()
|
|
{
|
|
m_offset = m_childBefore ? m_childBefore->computeNodeIndex() + 1 : 0;
|
|
}
|
|
|
|
inline bool operator==(const RangeBoundaryPoint& a, const RangeBoundaryPoint& b)
|
|
{
|
|
return &a.container() == &b.container() && a.offset() == b.offset();
|
|
}
|
|
|
|
inline BoundaryPoint makeBoundaryPoint(const RangeBoundaryPoint& point)
|
|
{
|
|
return { point.container(), point.offset() };
|
|
}
|
|
|
|
} // namespace WebCore
|