| Index: third_party/WebKit/Source/core/editing/Position.cpp
|
| diff --git a/third_party/WebKit/Source/core/editing/Position.cpp b/third_party/WebKit/Source/core/editing/Position.cpp
|
| index 2f2f9d59e058dc163ffaefaf3246b235b5b8bdfc..e47c06318b87f43299d00964198a40b036dcd859 100644
|
| --- a/third_party/WebKit/Source/core/editing/Position.cpp
|
| +++ b/third_party/WebKit/Source/core/editing/Position.cpp
|
| @@ -25,11 +25,11 @@
|
|
|
| #include "core/editing/Position.h"
|
|
|
| +#include "core/dom/Text.h"
|
| #include "core/dom/shadow/ElementShadow.h"
|
| #include "core/editing/EditingUtilities.h"
|
| #include "core/editing/TextAffinity.h"
|
| #include "wtf/text/CString.h"
|
| -#include <stdio.h>
|
| #include <ostream> // NOLINT
|
|
|
| namespace blink {
|
| @@ -74,12 +74,10 @@ PositionTemplate<Strategy>::PositionTemplate(Node* anchorNode, PositionAnchorTyp
|
| , m_offset(0)
|
| , m_anchorType(anchorType)
|
| {
|
| - if (!m_anchorNode) {
|
| - m_anchorType = PositionAnchorType::OffsetInAnchor;
|
| - return;
|
| - }
|
| + DCHECK(m_anchorNode);
|
| + DCHECK_NE(m_anchorType, PositionAnchorType::OffsetInAnchor);
|
| if (m_anchorNode->isTextNode()) {
|
| - DCHECK(m_anchorType == PositionAnchorType::BeforeAnchor || m_anchorType == PositionAnchorType::AfterAnchor);
|
| + DCHECK(isBeforeAnchor() || isAfterAnchor()) << m_anchorType;
|
| return;
|
| }
|
| if (m_anchorNode->isDocumentNode()) {
|
| @@ -88,6 +86,7 @@ PositionTemplate<Strategy>::PositionTemplate(Node* anchorNode, PositionAnchorTyp
|
| DCHECK(isBeforeChildren() || isAfterChildren()) << m_anchorType;
|
| return;
|
| }
|
| +
|
| #if DCHECK_IS_ON()
|
| DCHECK(canBeAnchorNode(m_anchorNode.get()));
|
| #endif
|
| @@ -393,27 +392,7 @@ bool PositionTemplate<Strategy>::atEndOfTree() const
|
| template <typename Strategy>
|
| void PositionTemplate<Strategy>::debugPosition(const char* msg) const
|
| {
|
| - static const char* const anchorTypes[] = {
|
| - "OffsetInAnchor",
|
| - "BeforeAnchor",
|
| - "AfterAnchor",
|
| - "BeforeChildren",
|
| - "AfterChildren",
|
| - "Invalid",
|
| - };
|
| -
|
| - if (isNull()) {
|
| - fprintf(stderr, "Position [%s]: null\n", msg);
|
| - return;
|
| - }
|
| -
|
| - const char* anchorType = anchorTypes[std::min(static_cast<size_t>(m_anchorType), WTF_ARRAY_LENGTH(anchorTypes) - 1)];
|
| - if (m_anchorNode->isTextNode()) {
|
| - fprintf(stderr, "Position [%s]: %s [%p] %s, (%s) at %d\n", msg, anchorNode()->nodeName().utf8().data(), anchorNode(), anchorType, m_anchorNode->nodeValue().utf8().data(), m_offset);
|
| - return;
|
| - }
|
| -
|
| - fprintf(stderr, "Position [%s]: %s [%p] %s at %d\n", msg, anchorNode()->nodeName().utf8().data(), anchorNode(), anchorType, m_offset);
|
| + VLOG(0) << msg << ' ' << *this;
|
| }
|
|
|
| PositionInFlatTree toPositionInFlatTree(const Position& pos)
|
| @@ -494,6 +473,57 @@ Position toPositionInDOMTree(const PositionInFlatTree& position)
|
| }
|
| }
|
|
|
| +// |normalize()| returns an equivalent position with |BeforeNode| position, or
|
| +// |OffsetInAnchor| for |Text| node if possible, otherwise |normalize()| returns
|
| +// - |AfterAnchor| if anchor node has no next siblings.
|
| +// - |BeforeChildren| if anchor node has no children.
|
| +// |normalized()| never return |AfterChildren| position.
|
| +template <typename Strategy>
|
| +PositionTemplate<Strategy> PositionTemplate<Strategy>::normalize(const PositionTemplate<Strategy>& position)
|
| +{
|
| + if (position.isNull())
|
| + return PositionTemplate<Strategy>();
|
| + Node* const anchorNode = position.anchorNode();
|
| + switch (position.anchorType()) {
|
| + case PositionAnchorType::AfterAnchor:
|
| + if (Node* nextSibling = Strategy::nextSibling(*anchorNode))
|
| + return normalize(beforeNode(nextSibling));
|
| + if (anchorNode->isTextNode())
|
| + return PositionTemplate<Strategy>(anchorNode, toText(anchorNode)->length());
|
| + return position;
|
| + case PositionAnchorType::AfterChildren:
|
| + ASSERT(!anchorNode->isTextNode());
|
| + if (Node* lastChild = Strategy::lastChild(*anchorNode))
|
| + return normalize(afterNode(lastChild));
|
| + return firstPositionInNode(anchorNode);
|
| + case PositionAnchorType::BeforeAnchor:
|
| + if (anchorNode->isTextNode())
|
| + return PositionTemplate<Strategy>(anchorNode, 0);
|
| + return position;
|
| + case PositionAnchorType::BeforeChildren:
|
| + ASSERT(!anchorNode->isTextNode());
|
| + if (Node* firstChild = Strategy::firstChild(*anchorNode))
|
| + return normalize(beforeNode(firstChild));
|
| + return position;
|
| + case PositionAnchorType::OffsetInAnchor: {
|
| + const int offsetInContainer = position.offsetInContainerNode();
|
| + if (anchorNode->isTextNode()) {
|
| + const Text& textNode = *toText(anchorNode);
|
| + if (offsetInContainer < static_cast<int>(textNode.length()))
|
| + return position;
|
| + return normalize(afterNode(anchorNode));
|
| + }
|
| + if (Node* child = Strategy::childAt(*anchorNode, offsetInContainer))
|
| + return normalize(beforeNode(child));
|
| + if (Node* lastChild = Strategy::lastChild(*anchorNode))
|
| + return normalize(afterNode(lastChild));
|
| + return firstPositionInNode(anchorNode);
|
| + }
|
| + }
|
| + ASSERT_NOT_REACHED();
|
| + return PositionTemplate<Strategy>();
|
| +}
|
| +
|
| #ifndef NDEBUG
|
|
|
| template <typename Strategy>
|
| @@ -516,35 +546,12 @@ void PositionTemplate<Strategy>::formatForDebugger(char* buffer, unsigned length
|
| }
|
|
|
| template <typename Strategy>
|
| -void PositionTemplate<Strategy>::showAnchorTypeAndOffset() const
|
| -{
|
| - switch (anchorType()) {
|
| - case PositionAnchorType::OffsetInAnchor:
|
| - fputs("offset", stderr);
|
| - break;
|
| - case PositionAnchorType::BeforeChildren:
|
| - fputs("beforeChildren", stderr);
|
| - break;
|
| - case PositionAnchorType::AfterChildren:
|
| - fputs("afterChildren", stderr);
|
| - break;
|
| - case PositionAnchorType::BeforeAnchor:
|
| - fputs("before", stderr);
|
| - break;
|
| - case PositionAnchorType::AfterAnchor:
|
| - fputs("after", stderr);
|
| - break;
|
| - }
|
| - fprintf(stderr, ", offset:%d\n", m_offset);
|
| -}
|
| -
|
| -template <typename Strategy>
|
| void PositionTemplate<Strategy>::showTreeForThis() const
|
| {
|
| if (!anchorNode())
|
| return;
|
| anchorNode()->showTreeForThis();
|
| - showAnchorTypeAndOffset();
|
| + VLOG(0) << *this;
|
| }
|
|
|
| template <typename Strategy>
|
| @@ -553,7 +560,7 @@ void PositionTemplate<Strategy>::showTreeForThisInFlatTree() const
|
| if (!anchorNode())
|
| return;
|
| anchorNode()->showTreeForThisInFlatTree();
|
| - showAnchorTypeAndOffset();
|
| + VLOG(0) << *this;
|
| }
|
|
|
| #endif
|
|
|