Index: Source/core/editing/Position.cpp |
diff --git a/Source/core/editing/Position.cpp b/Source/core/editing/Position.cpp |
index 635cc65accb70b160bb612c63ddae4d901c7af88..32c2d43042f8f7504a9e235899614cb57610137f 100644 |
--- a/Source/core/editing/Position.cpp |
+++ b/Source/core/editing/Position.cpp |
@@ -600,256 +600,6 @@ bool inRenderedText(const PositionInComposedTree& position) |
} |
template <typename Strategy> |
-static InlineBoxPosition computeInlineBoxPositionAlgorithm(const PositionAlgorithm<Strategy>& position, TextAffinity affinity) |
-{ |
- return computeInlineBoxPositionAlgorithm<Strategy>(position, affinity, primaryDirectionOf(*position.anchorNode())); |
-} |
- |
-InlineBoxPosition computeInlineBoxPosition(const Position& position, TextAffinity affinity) |
-{ |
- return computeInlineBoxPositionAlgorithm<EditingStrategy>(position, affinity); |
-} |
- |
-InlineBoxPosition computeInlineBoxPosition(const PositionInComposedTree& position, TextAffinity affinity) |
-{ |
- return computeInlineBoxPositionAlgorithm<EditingInComposedTreeStrategy>(position, affinity); |
-} |
- |
-static bool isNonTextLeafChild(LayoutObject* object) |
-{ |
- if (object->slowFirstChild()) |
- return false; |
- if (object->isText()) |
- return false; |
- return true; |
-} |
- |
-static InlineTextBox* searchAheadForBetterMatch(LayoutObject* layoutObject) |
-{ |
- LayoutBlock* container = layoutObject->containingBlock(); |
- for (LayoutObject* next = layoutObject->nextInPreOrder(container); next; next = next->nextInPreOrder(container)) { |
- if (next->isLayoutBlock()) |
- return 0; |
- if (next->isBR()) |
- return 0; |
- if (isNonTextLeafChild(next)) |
- return 0; |
- if (next->isText()) { |
- InlineTextBox* match = 0; |
- int minOffset = INT_MAX; |
- for (InlineTextBox* box = toLayoutText(next)->firstTextBox(); box; box = box->nextTextBox()) { |
- int caretMinOffset = box->caretMinOffset(); |
- if (caretMinOffset < minOffset) { |
- match = box; |
- minOffset = caretMinOffset; |
- } |
- } |
- if (match) |
- return match; |
- } |
- } |
- return 0; |
-} |
- |
-template <typename Strategy> |
-PositionAlgorithm<Strategy> downstreamIgnoringEditingBoundaries(PositionAlgorithm<Strategy> position) |
-{ |
- PositionAlgorithm<Strategy> lastPosition; |
- while (position != lastPosition) { |
- lastPosition = position; |
- position = position.downstream(CanCrossEditingBoundary); |
- } |
- return position; |
-} |
- |
-template <typename Strategy> |
-PositionAlgorithm<Strategy> upstreamIgnoringEditingBoundaries(PositionAlgorithm<Strategy> position) |
-{ |
- PositionAlgorithm<Strategy> lastPosition; |
- while (position != lastPosition) { |
- lastPosition = position; |
- position = position.upstream(CanCrossEditingBoundary); |
- } |
- return position; |
-} |
- |
-template <typename Strategy> |
-static InlineBoxPosition computeInlineBoxPositionAlgorithm(const PositionAlgorithm<Strategy>& position, TextAffinity affinity, TextDirection primaryDirection) |
-{ |
- InlineBox* inlineBox = nullptr; |
- int caretOffset = position.computeEditingOffset(); |
- Node* const anchorNode = position.anchorNode(); |
- LayoutObject* layoutObject = anchorNode->isShadowRoot() ? toShadowRoot(anchorNode)->host()->layoutObject() : anchorNode->layoutObject(); |
- |
- if (!layoutObject->isText()) { |
- inlineBox = 0; |
- if (canHaveChildrenForEditing(anchorNode) && layoutObject->isLayoutBlockFlow() && hasRenderedNonAnonymousDescendantsWithHeight(layoutObject)) { |
- // Try a visually equivalent position with possibly opposite |
- // editability. This helps in case |this| is in an editable block |
- // but surrounded by non-editable positions. It acts to negate the |
- // logic at the beginning of LayoutObject::createVisiblePosition(). |
- PositionAlgorithm<Strategy> equivalent = downstreamIgnoringEditingBoundaries(position); |
- if (equivalent == position) { |
- equivalent = upstreamIgnoringEditingBoundaries(position); |
- if (equivalent == position || downstreamIgnoringEditingBoundaries(equivalent) == position) |
- return InlineBoxPosition(inlineBox, caretOffset); |
- } |
- |
- return computeInlineBoxPosition(equivalent, TextAffinity::Upstream, primaryDirection); |
- } |
- if (layoutObject->isBox()) { |
- inlineBox = toLayoutBox(layoutObject)->inlineBoxWrapper(); |
- if (!inlineBox || (caretOffset > inlineBox->caretMinOffset() && caretOffset < inlineBox->caretMaxOffset())) |
- return InlineBoxPosition(inlineBox, caretOffset); |
- } |
- } else { |
- LayoutText* textLayoutObject = toLayoutText(layoutObject); |
- |
- InlineTextBox* box; |
- InlineTextBox* candidate = 0; |
- |
- for (box = textLayoutObject->firstTextBox(); box; box = box->nextTextBox()) { |
- int caretMinOffset = box->caretMinOffset(); |
- int caretMaxOffset = box->caretMaxOffset(); |
- |
- if (caretOffset < caretMinOffset || caretOffset > caretMaxOffset || (caretOffset == caretMaxOffset && box->isLineBreak())) |
- continue; |
- |
- if (caretOffset > caretMinOffset && caretOffset < caretMaxOffset) |
- return InlineBoxPosition(box, caretOffset); |
- |
- if (((caretOffset == caretMaxOffset) ^ (affinity == TextAffinity::Downstream)) |
- || ((caretOffset == caretMinOffset) ^ (affinity == TextAffinity::Upstream)) |
- || (caretOffset == caretMaxOffset && box->nextLeafChild() && box->nextLeafChild()->isLineBreak())) |
- break; |
- |
- candidate = box; |
- } |
- if (candidate && candidate == textLayoutObject->lastTextBox() && affinity == TextAffinity::Downstream) { |
- box = searchAheadForBetterMatch(textLayoutObject); |
- if (box) |
- caretOffset = box->caretMinOffset(); |
- } |
- inlineBox = box ? box : candidate; |
- } |
- |
- if (!inlineBox) |
- return InlineBoxPosition(inlineBox, caretOffset); |
- |
- unsigned char level = inlineBox->bidiLevel(); |
- |
- if (inlineBox->direction() == primaryDirection) { |
- if (caretOffset == inlineBox->caretRightmostOffset()) { |
- InlineBox* nextBox = inlineBox->nextLeafChild(); |
- if (!nextBox || nextBox->bidiLevel() >= level) |
- return InlineBoxPosition(inlineBox, caretOffset); |
- |
- level = nextBox->bidiLevel(); |
- InlineBox* prevBox = inlineBox; |
- do { |
- prevBox = prevBox->prevLeafChild(); |
- } while (prevBox && prevBox->bidiLevel() > level); |
- |
- // For example, abc FED 123 ^ CBA |
- if (prevBox && prevBox->bidiLevel() == level) |
- return InlineBoxPosition(inlineBox, caretOffset); |
- |
- // For example, abc 123 ^ CBA |
- while (InlineBox* nextBox = inlineBox->nextLeafChild()) { |
- if (nextBox->bidiLevel() < level) |
- break; |
- inlineBox = nextBox; |
- } |
- return InlineBoxPosition(inlineBox, inlineBox->caretRightmostOffset()); |
- } |
- |
- InlineBox* prevBox = inlineBox->prevLeafChild(); |
- if (!prevBox || prevBox->bidiLevel() >= level) |
- return InlineBoxPosition(inlineBox, caretOffset); |
- |
- level = prevBox->bidiLevel(); |
- InlineBox* nextBox = inlineBox; |
- do { |
- nextBox = nextBox->nextLeafChild(); |
- } while (nextBox && nextBox->bidiLevel() > level); |
- |
- if (nextBox && nextBox->bidiLevel() == level) |
- return InlineBoxPosition(inlineBox, caretOffset); |
- |
- while (InlineBox* prevBox = inlineBox->prevLeafChild()) { |
- if (prevBox->bidiLevel() < level) |
- break; |
- inlineBox = prevBox; |
- } |
- return InlineBoxPosition(inlineBox, inlineBox->caretLeftmostOffset()); |
- } |
- |
- if (caretOffset == inlineBox->caretLeftmostOffset()) { |
- InlineBox* prevBox = inlineBox->prevLeafChildIgnoringLineBreak(); |
- if (!prevBox || prevBox->bidiLevel() < level) { |
- // Left edge of a secondary run. Set to the right edge of the entire |
- // run. |
- while (InlineBox* nextBox = inlineBox->nextLeafChildIgnoringLineBreak()) { |
- if (nextBox->bidiLevel() < level) |
- break; |
- inlineBox = nextBox; |
- } |
- return InlineBoxPosition(inlineBox, inlineBox->caretRightmostOffset()); |
- } |
- |
- if (prevBox->bidiLevel() > level) { |
- // Right edge of a "tertiary" run. Set to the left edge of that run. |
- while (InlineBox* tertiaryBox = inlineBox->prevLeafChildIgnoringLineBreak()) { |
- if (tertiaryBox->bidiLevel() <= level) |
- break; |
- inlineBox = tertiaryBox; |
- } |
- return InlineBoxPosition(inlineBox, inlineBox->caretLeftmostOffset()); |
- } |
- return InlineBoxPosition(inlineBox, caretOffset); |
- } |
- |
- if (layoutObject && layoutObject->style()->unicodeBidi() == Plaintext) { |
- if (inlineBox->bidiLevel() < level) |
- return InlineBoxPosition(inlineBox, inlineBox->caretLeftmostOffset()); |
- return InlineBoxPosition(inlineBox, inlineBox->caretRightmostOffset()); |
- } |
- |
- InlineBox* nextBox = inlineBox->nextLeafChildIgnoringLineBreak(); |
- if (!nextBox || nextBox->bidiLevel() < level) { |
- // Right edge of a secondary run. Set to the left edge of the entire |
- // run. |
- while (InlineBox* prevBox = inlineBox->prevLeafChildIgnoringLineBreak()) { |
- if (prevBox->bidiLevel() < level) |
- break; |
- inlineBox = prevBox; |
- } |
- return InlineBoxPosition(inlineBox, inlineBox->caretLeftmostOffset()); |
- } |
- |
- if (nextBox->bidiLevel() <= level) |
- return InlineBoxPosition(inlineBox, caretOffset); |
- |
- // Left edge of a "tertiary" run. Set to the right edge of that run. |
- while (InlineBox* tertiaryBox = inlineBox->nextLeafChildIgnoringLineBreak()) { |
- if (tertiaryBox->bidiLevel() <= level) |
- break; |
- inlineBox = tertiaryBox; |
- } |
- return InlineBoxPosition(inlineBox, inlineBox->caretRightmostOffset()); |
-} |
- |
-InlineBoxPosition computeInlineBoxPosition(const Position& position, TextAffinity affinity, TextDirection primaryDirection) |
-{ |
- return computeInlineBoxPositionAlgorithm<EditingStrategy>(position, affinity, primaryDirection); |
-} |
- |
-InlineBoxPosition computeInlineBoxPosition(const PositionInComposedTree& position, TextAffinity affinity, TextDirection primaryDirection) |
-{ |
- return computeInlineBoxPositionAlgorithm<EditingInComposedTreeStrategy>(position, affinity, primaryDirection); |
-} |
- |
-template <typename Strategy> |
void PositionAlgorithm<Strategy>::debugPosition(const char* msg) const |
{ |
static const char* const anchorTypes[] = { |