| Index: third_party/WebKit/Source/core/dom/RangeBoundaryPoint.h
|
| diff --git a/third_party/WebKit/Source/core/dom/RangeBoundaryPoint.h b/third_party/WebKit/Source/core/dom/RangeBoundaryPoint.h
|
| index c8aab2a78a0c2ca7e419a96564dbcfba42361c87..401a563078cd906d230b6eb010c7f4819295cefc 100644
|
| --- a/third_party/WebKit/Source/core/dom/RangeBoundaryPoint.h
|
| +++ b/third_party/WebKit/Source/core/dom/RangeBoundaryPoint.h
|
| @@ -56,8 +56,8 @@ public:
|
| void setToEndOfNode(Node&);
|
|
|
| void childBeforeWillBeRemoved();
|
| - void invalidateOffset() const;
|
| - void ensureOffsetIsValid() const;
|
| + void invalidateOffset();
|
| + void markValid() const;
|
|
|
| DEFINE_INLINE_TRACE()
|
| {
|
| @@ -66,25 +66,31 @@ public:
|
| }
|
|
|
| private:
|
| + uint64_t domTreeVersion() const;
|
| + void ensureOffsetIsValid() const;
|
| + bool isOffsetValid() const;
|
| +
|
| static const int invalidOffset = -1;
|
|
|
| Member<Node> m_containerNode;
|
| - mutable int m_offsetInContainer;
|
| Member<Node> m_childBeforeBoundary;
|
| + mutable uint64_t m_domTreeVersion;
|
| + mutable int m_offsetInContainer;
|
| };
|
|
|
| inline RangeBoundaryPoint::RangeBoundaryPoint(Node* container)
|
| : m_containerNode(container)
|
| - , m_offsetInContainer(0)
|
| , m_childBeforeBoundary(nullptr)
|
| + , m_domTreeVersion(domTreeVersion())
|
| + , m_offsetInContainer(0)
|
| {
|
| - DCHECK(m_containerNode);
|
| }
|
|
|
| inline RangeBoundaryPoint::RangeBoundaryPoint(const RangeBoundaryPoint& other)
|
| : m_containerNode(other.container())
|
| - , m_offsetInContainer(other.offset())
|
| , m_childBeforeBoundary(other.childBefore())
|
| + , m_domTreeVersion(other.m_domTreeVersion)
|
| + , m_offsetInContainer(other.offset())
|
| {
|
| }
|
|
|
| @@ -98,12 +104,21 @@ inline Node* RangeBoundaryPoint::childBefore() const
|
| return m_childBeforeBoundary.get();
|
| }
|
|
|
| +inline uint64_t RangeBoundaryPoint::domTreeVersion() const
|
| +{
|
| + return m_containerNode->document().domTreeVersion();
|
| +}
|
| +
|
| inline void RangeBoundaryPoint::ensureOffsetIsValid() const
|
| {
|
| - if (m_offsetInContainer >= 0)
|
| + if (isOffsetValid())
|
| return;
|
| -
|
| - DCHECK(m_childBeforeBoundary);
|
| + DCHECK(!m_containerNode->isCharacterDataNode());
|
| + markValid();
|
| + if (!m_childBeforeBoundary) {
|
| + m_offsetInContainer = 0;
|
| + return;
|
| + }
|
| m_offsetInContainer = m_childBeforeBoundary->nodeIndex() + 1;
|
| }
|
|
|
| @@ -112,9 +127,20 @@ inline bool RangeBoundaryPoint::inShadowIncludingDocument() const
|
| return m_containerNode && m_containerNode->inShadowIncludingDocument();
|
| }
|
|
|
| +inline bool RangeBoundaryPoint::isOffsetValid() const
|
| +{
|
| + if (m_offsetInContainer == invalidOffset) {
|
| + DCHECK(!m_containerNode->isTextNode());
|
| + return false;
|
| + }
|
| + return domTreeVersion() == m_domTreeVersion || m_containerNode->isCharacterDataNode();
|
| +}
|
| +
|
| inline const Position RangeBoundaryPoint::toPosition() const
|
| {
|
| ensureOffsetIsValid();
|
| + // TODO(yosin): We should return |Position::beforeAnchor| when
|
| + // |m_containerNode| isn't |Text| node.
|
| return Position::editingPositionOf(m_containerNode.get(), m_offsetInContainer);
|
| }
|
|
|
| @@ -129,6 +155,7 @@ inline void RangeBoundaryPoint::clear()
|
| m_containerNode.clear();
|
| m_offsetInContainer = 0;
|
| m_childBeforeBoundary = nullptr;
|
| + m_domTreeVersion = 0;
|
| }
|
|
|
| inline void RangeBoundaryPoint::set(Node* container, int offset, Node* childBefore)
|
| @@ -139,6 +166,7 @@ inline void RangeBoundaryPoint::set(Node* container, int offset, Node* childBefo
|
| m_containerNode = container;
|
| m_offsetInContainer = offset;
|
| m_childBeforeBoundary = childBefore;
|
| + markValid();
|
| }
|
|
|
| inline void RangeBoundaryPoint::setOffset(int offset)
|
| @@ -148,6 +176,7 @@ inline void RangeBoundaryPoint::setOffset(int offset)
|
| DCHECK_GE(m_offsetInContainer, 0);
|
| DCHECK(!m_childBeforeBoundary);
|
| m_offsetInContainer = offset;
|
| + markValid();
|
| }
|
|
|
| inline void RangeBoundaryPoint::setToBeforeChild(Node& child)
|
| @@ -156,6 +185,7 @@ inline void RangeBoundaryPoint::setToBeforeChild(Node& child)
|
| m_childBeforeBoundary = child.previousSibling();
|
| m_containerNode = child.parentNode();
|
| m_offsetInContainer = m_childBeforeBoundary ? invalidOffset : 0;
|
| + markValid();
|
| }
|
|
|
| inline void RangeBoundaryPoint::setToStartOfNode(Node& container)
|
| @@ -163,6 +193,7 @@ inline void RangeBoundaryPoint::setToStartOfNode(Node& container)
|
| m_containerNode = &container;
|
| m_offsetInContainer = 0;
|
| m_childBeforeBoundary = nullptr;
|
| + markValid();
|
| }
|
|
|
| inline void RangeBoundaryPoint::setToEndOfNode(Node& container)
|
| @@ -175,6 +206,7 @@ inline void RangeBoundaryPoint::setToEndOfNode(Node& container)
|
| m_childBeforeBoundary = m_containerNode->lastChild();
|
| m_offsetInContainer = m_childBeforeBoundary ? invalidOffset : 0;
|
| }
|
| + markValid();
|
| }
|
|
|
| inline void RangeBoundaryPoint::childBeforeWillBeRemoved()
|
| @@ -185,13 +217,19 @@ inline void RangeBoundaryPoint::childBeforeWillBeRemoved()
|
| m_offsetInContainer = 0;
|
| else if (m_offsetInContainer > 0)
|
| --m_offsetInContainer;
|
| + markValid();
|
| }
|
|
|
| -inline void RangeBoundaryPoint::invalidateOffset() const
|
| +inline void RangeBoundaryPoint::invalidateOffset()
|
| {
|
| m_offsetInContainer = invalidOffset;
|
| }
|
|
|
| +inline void RangeBoundaryPoint::markValid() const
|
| +{
|
| + m_domTreeVersion = domTreeVersion();
|
| +}
|
| +
|
| inline bool operator==(const RangeBoundaryPoint& a, const RangeBoundaryPoint& b)
|
| {
|
| if (a.container() != b.container())
|
|
|