| Index: third_party/WebKit/Source/core/layout/LayoutBlock.cpp
|
| diff --git a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
|
| index d6f52fd0b0c271ec706d1afb9f2cfae2aa32b1f1..0c6fc97c2d052026bc494056de2166da5c134a40 100644
|
| --- a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
|
| +++ b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
|
| @@ -31,7 +31,6 @@
|
| #include "core/dom/shadow/ShadowRoot.h"
|
| #include "core/editing/DragCaretController.h"
|
| #include "core/editing/EditingUtilities.h"
|
| -#include "core/editing/Editor.h"
|
| #include "core/editing/FrameSelection.h"
|
| #include "core/frame/FrameView.h"
|
| #include "core/frame/LocalFrame.h"
|
| @@ -1617,10 +1616,10 @@ static inline bool isEditingBoundary(LayoutObject* ancestor, LineLayoutBox child
|
| || ancestor->nonPseudoNode()->hasEditableStyle() == child.nonPseudoNode()->hasEditableStyle();
|
| }
|
|
|
| -// FIXME: This function should go on LayoutObject as an instance method. Then
|
| -// all cases in which positionForPoint recurs could call this instead to
|
| +// FIXME: This function should go on LayoutObject.
|
| +// Then all cases in which positionForPoint recurs could call this instead to
|
| // prevent crossing editable boundaries. This would require many tests.
|
| -static PositionWithAffinity positionForPointRespectingEditingBoundaries(LayoutBlock* parent, LineLayoutBox child, const LayoutPoint& pointInParentCoordinates)
|
| +PositionWithAffinity LayoutBlock::positionForPointRespectingEditingBoundaries(LineLayoutBox child, const LayoutPoint& pointInParentCoordinates)
|
| {
|
| LayoutPoint childLocation = child.location();
|
| if (child.isInFlowPositioned())
|
| @@ -1636,7 +1635,7 @@ static PositionWithAffinity positionForPointRespectingEditingBoundaries(LayoutBl
|
|
|
| // Otherwise, first make sure that the editability of the parent and child agree.
|
| // If they don't agree, then we return a visible position just before or after the child
|
| - LayoutObject* ancestor = parent;
|
| + LayoutObject* ancestor = this;
|
| while (ancestor && !ancestor->nonPseudoNode())
|
| ancestor = ancestor->parent();
|
|
|
| @@ -1645,99 +1644,29 @@ static PositionWithAffinity positionForPointRespectingEditingBoundaries(LayoutBl
|
| return child.positionForPoint(pointInChildCoordinates);
|
|
|
| // Otherwise return before or after the child, depending on if the click was to the logical left or logical right of the child
|
| - LayoutUnit childMiddle = parent->logicalWidthForChildSize(child.size()) / 2;
|
| - LayoutUnit logicalLeft = parent->isHorizontalWritingMode() ? pointInChildCoordinates.x() : pointInChildCoordinates.y();
|
| + LayoutUnit childMiddle = logicalWidthForChildSize(child.size()) / 2;
|
| + LayoutUnit logicalLeft = isHorizontalWritingMode() ? pointInChildCoordinates.x() : pointInChildCoordinates.y();
|
| if (logicalLeft < childMiddle)
|
| return ancestor->createPositionWithAffinity(childNode->nodeIndex());
|
| return ancestor->createPositionWithAffinity(childNode->nodeIndex() + 1, TextAffinity::Upstream);
|
| }
|
|
|
| -PositionWithAffinity LayoutBlock::positionForPointWithInlineChildren(const LayoutPoint& pointInLogicalContents)
|
| +PositionWithAffinity LayoutBlock::positionForPointIfOutsideAtomicInlineLevel(const LayoutPoint& point)
|
| {
|
| - ASSERT(childrenInline());
|
| + ASSERT(isAtomicInlineLevel());
|
| + // FIXME: This seems wrong when the object's writing-mode doesn't match the line's writing-mode.
|
| + LayoutUnit pointLogicalLeft = isHorizontalWritingMode() ? point.x() : point.y();
|
| + LayoutUnit pointLogicalTop = isHorizontalWritingMode() ? point.y() : point.x();
|
|
|
| - if (!firstRootBox())
|
| - return createPositionWithAffinity(0);
|
| -
|
| - bool linesAreFlipped = style()->isFlippedLinesWritingMode();
|
| - bool blocksAreFlipped = style()->isFlippedBlocksWritingMode();
|
| -
|
| - // look for the closest line box in the root box which is at the passed-in y coordinate
|
| - InlineBox* closestBox = nullptr;
|
| - RootInlineBox* firstRootBoxWithChildren = nullptr;
|
| - RootInlineBox* lastRootBoxWithChildren = nullptr;
|
| - for (RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox()) {
|
| - if (!root->firstLeafChild())
|
| - continue;
|
| - if (!firstRootBoxWithChildren)
|
| - firstRootBoxWithChildren = root;
|
| -
|
| - if (!linesAreFlipped && root->isFirstAfterPageBreak() && (pointInLogicalContents.y() < root->lineTopWithLeading()
|
| - || (blocksAreFlipped && pointInLogicalContents.y() == root->lineTopWithLeading())))
|
| - break;
|
| -
|
| - lastRootBoxWithChildren = root;
|
| -
|
| - // check if this root line box is located at this y coordinate
|
| - if (pointInLogicalContents.y() < root->selectionBottom() || (blocksAreFlipped && pointInLogicalContents.y() == root->selectionBottom())) {
|
| - if (linesAreFlipped) {
|
| - RootInlineBox* nextRootBoxWithChildren = root->nextRootBox();
|
| - while (nextRootBoxWithChildren && !nextRootBoxWithChildren->firstLeafChild())
|
| - nextRootBoxWithChildren = nextRootBoxWithChildren->nextRootBox();
|
| -
|
| - if (nextRootBoxWithChildren && nextRootBoxWithChildren->isFirstAfterPageBreak() && (pointInLogicalContents.y() > nextRootBoxWithChildren->lineTopWithLeading()
|
| - || (!blocksAreFlipped && pointInLogicalContents.y() == nextRootBoxWithChildren->lineTopWithLeading())))
|
| - continue;
|
| - }
|
| - closestBox = root->closestLeafChildForLogicalLeftPosition(pointInLogicalContents.x());
|
| - if (closestBox)
|
| - break;
|
| - }
|
| - }
|
| -
|
| - bool moveCaretToBoundary = document().frame()->editor().behavior().shouldMoveCaretToHorizontalBoundaryWhenPastTopOrBottom();
|
| -
|
| - if (!moveCaretToBoundary && !closestBox && lastRootBoxWithChildren) {
|
| - // y coordinate is below last root line box, pretend we hit it
|
| - closestBox = lastRootBoxWithChildren->closestLeafChildForLogicalLeftPosition(pointInLogicalContents.x());
|
| - }
|
| -
|
| - if (closestBox) {
|
| - if (moveCaretToBoundary) {
|
| - LayoutUnit firstRootBoxWithChildrenTop = std::min<LayoutUnit>(firstRootBoxWithChildren->selectionTop(), firstRootBoxWithChildren->logicalTop());
|
| - if (pointInLogicalContents.y() < firstRootBoxWithChildrenTop
|
| - || (blocksAreFlipped && pointInLogicalContents.y() == firstRootBoxWithChildrenTop)) {
|
| - InlineBox* box = firstRootBoxWithChildren->firstLeafChild();
|
| - if (box->isLineBreak()) {
|
| - if (InlineBox* newBox = box->nextLeafChildIgnoringLineBreak())
|
| - box = newBox;
|
| - }
|
| - // y coordinate is above first root line box, so return the start of the first
|
| - return PositionWithAffinity(positionForBox(box, true));
|
| - }
|
| - }
|
| -
|
| - // pass the box a top position that is inside it
|
| - LayoutPoint point(pointInLogicalContents.x(), closestBox->root().blockDirectionPointInLine());
|
| - if (!isHorizontalWritingMode())
|
| - point = point.transposedPoint();
|
| - if (closestBox->getLineLayoutItem().isAtomicInlineLevel())
|
| - return positionForPointRespectingEditingBoundaries(this, LineLayoutBox(closestBox->getLineLayoutItem()), point);
|
| - return closestBox->getLineLayoutItem().positionForPoint(point);
|
| - }
|
| -
|
| - if (lastRootBoxWithChildren) {
|
| - // We hit this case for Mac behavior when the Y coordinate is below the last box.
|
| - ASSERT(moveCaretToBoundary);
|
| - InlineBox* logicallyLastBox;
|
| - if (lastRootBoxWithChildren->getLogicalEndBoxWithNode(logicallyLastBox))
|
| - return PositionWithAffinity(positionForBox(logicallyLastBox, false));
|
| - }
|
| -
|
| - // Can't reach this. We have a root line box, but it has no kids.
|
| - // FIXME: This should ASSERT_NOT_REACHED(), but clicking on placeholder text
|
| - // seems to hit this code path.
|
| - return createPositionWithAffinity(0);
|
| + if (pointLogicalLeft < 0)
|
| + return createPositionWithAffinity(caretMinOffset());
|
| + if (pointLogicalLeft >= logicalWidth())
|
| + return createPositionWithAffinity(caretMaxOffset());
|
| + if (pointLogicalTop < 0)
|
| + return createPositionWithAffinity(caretMinOffset());
|
| + if (pointLogicalTop >= logicalHeight())
|
| + return createPositionWithAffinity(caretMaxOffset());
|
| + return PositionWithAffinity();
|
| }
|
|
|
| static inline bool isChildHitTestCandidate(LayoutBox* box)
|
| @@ -1751,18 +1680,9 @@ PositionWithAffinity LayoutBlock::positionForPoint(const LayoutPoint& point)
|
| return LayoutBox::positionForPoint(point);
|
|
|
| if (isAtomicInlineLevel()) {
|
| - // FIXME: This seems wrong when the object's writing-mode doesn't match the line's writing-mode.
|
| - LayoutUnit pointLogicalLeft = isHorizontalWritingMode() ? point.x() : point.y();
|
| - LayoutUnit pointLogicalTop = isHorizontalWritingMode() ? point.y() : point.x();
|
| -
|
| - if (pointLogicalLeft < 0)
|
| - return createPositionWithAffinity(caretMinOffset());
|
| - if (pointLogicalLeft >= logicalWidth())
|
| - return createPositionWithAffinity(caretMaxOffset());
|
| - if (pointLogicalTop < 0)
|
| - return createPositionWithAffinity(caretMinOffset());
|
| - if (pointLogicalTop >= logicalHeight())
|
| - return createPositionWithAffinity(caretMaxOffset());
|
| + PositionWithAffinity position = positionForPointIfOutsideAtomicInlineLevel(point);
|
| + if (!position.isNull())
|
| + return position;
|
| }
|
|
|
| LayoutPoint pointInContents = point;
|
| @@ -1771,8 +1691,7 @@ PositionWithAffinity LayoutBlock::positionForPoint(const LayoutPoint& point)
|
| if (!isHorizontalWritingMode())
|
| pointInLogicalContents = pointInLogicalContents.transposedPoint();
|
|
|
| - if (childrenInline())
|
| - return positionForPointWithInlineChildren(pointInLogicalContents);
|
| + ASSERT(!childrenInline());
|
|
|
| LayoutBox* lastCandidateBox = lastChildBox();
|
| while (lastCandidateBox && !isChildHitTestCandidate(lastCandidateBox))
|
| @@ -1782,7 +1701,7 @@ PositionWithAffinity LayoutBlock::positionForPoint(const LayoutPoint& point)
|
| if (lastCandidateBox) {
|
| if (pointInLogicalContents.y() > logicalTopForChild(*lastCandidateBox)
|
| || (!blocksAreFlipped && pointInLogicalContents.y() == logicalTopForChild(*lastCandidateBox)))
|
| - return positionForPointRespectingEditingBoundaries(this, LineLayoutBox(lastCandidateBox), pointInContents);
|
| + return positionForPointRespectingEditingBoundaries(LineLayoutBox(lastCandidateBox), pointInContents);
|
|
|
| for (LayoutBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
|
| if (!isChildHitTestCandidate(childBox))
|
| @@ -1791,7 +1710,7 @@ PositionWithAffinity LayoutBlock::positionForPoint(const LayoutPoint& point)
|
| // We hit child if our click is above the bottom of its padding box (like IE6/7 and FF3).
|
| if (isChildHitTestCandidate(childBox) && (pointInLogicalContents.y() < childLogicalBottom
|
| || (blocksAreFlipped && pointInLogicalContents.y() == childLogicalBottom)))
|
| - return positionForPointRespectingEditingBoundaries(this, LineLayoutBox(childBox), pointInContents);
|
| + return positionForPointRespectingEditingBoundaries(LineLayoutBox(childBox), pointInContents);
|
| }
|
| }
|
|
|
|
|