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

Unified Diff: third_party/WebKit/Source/core/layout/LayoutBlockFlow.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
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutBlockFlow.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
index 97baaabca2d756ceb2d1776496e7c67f0d518d3c..58932b0e1db3c1992a61a5eb95b5df9d767b9e3f 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
@@ -31,6 +31,7 @@
#include "core/layout/LayoutBlockFlow.h"
#include "core/dom/AXObjectCache.h"
+#include "core/editing/Editor.h"
#include "core/frame/FrameView.h"
#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
@@ -3180,6 +3181,106 @@ bool LayoutBlockFlow::recalcInlineChildrenOverflowAfterStyleChange()
return childrenOverflowChanged;
}
+PositionWithAffinity LayoutBlockFlow::positionForPoint(const LayoutPoint& point)
+{
+ if (isAtomicInlineLevel()) {
+ PositionWithAffinity position = positionForPointIfOutsideAtomicInlineLevel(point);
+ if (!position.isNull())
+ return position;
+ }
+ if (!childrenInline())
+ return LayoutBlock::positionForPoint(point);
+
+ LayoutPoint pointInContents = point;
+ offsetForContents(pointInContents);
+ LayoutPoint pointInLogicalContents(pointInContents);
+ if (!isHorizontalWritingMode())
+ pointInLogicalContents = pointInLogicalContents.transposedPoint();
+
+ 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(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);
+}
+
#ifndef NDEBUG
void LayoutBlockFlow::showLineTreeAndMark(const InlineBox* markedBox1, const char* markedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const LayoutObject* obj) const
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutBlockFlow.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698