Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(117)

Unified Diff: third_party/WebKit/Source/core/layout/LayoutBlock.cpp

Issue 1957633003: Move line-specific code into LayoutBlockFlow::positionForPoint(). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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);
}
}
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutBlock.h ('k') | third_party/WebKit/Source/core/layout/LayoutBlockFlow.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698