Diff
Modified: trunk/LayoutTests/ChangeLog (209426 => 209427)
--- trunk/LayoutTests/ChangeLog 2016-12-06 23:01:56 UTC (rev 209426)
+++ trunk/LayoutTests/ChangeLog 2016-12-06 23:06:42 UTC (rev 209427)
@@ -1,3 +1,13 @@
+2016-12-06 Zalan Bujtas <za...@apple.com>
+
+ Can not select whole line when using flexbox
+ https://bugs.webkit.org/show_bug.cgi?id=165299
+
+ Reviewed by David Hyatt.
+
+ * fast/flexbox/flexbox-fail-to-select-same-line-expected.html: Added.
+ * fast/flexbox/flexbox-fail-to-select-same-line.html: Added.
+
2016-12-06 Jer Noble <jer.no...@apple.com>
YouTube sometimes pauses when switching tabs
Added: trunk/LayoutTests/fast/flexbox/flexbox-fail-to-select-same-line-expected.html (0 => 209427)
--- trunk/LayoutTests/fast/flexbox/flexbox-fail-to-select-same-line-expected.html (rev 0)
+++ trunk/LayoutTests/fast/flexbox/flexbox-fail-to-select-same-line-expected.html 2016-12-06 23:06:42 UTC (rev 209427)
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>This tests that we can select flex content when they share the same line.</title>
+<style>
+div {
+ color: transparent;
+ font-size: 10px;
+}
+
+div::selection {
+ background-color: green;
+}
+</style>
+</head>
+<body>
+<div>  </div>
+<script>
+ document.execCommand('selectAll', false, null);
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/fast/flexbox/flexbox-fail-to-select-same-line.html (0 => 209427)
--- trunk/LayoutTests/fast/flexbox/flexbox-fail-to-select-same-line.html (rev 0)
+++ trunk/LayoutTests/fast/flexbox/flexbox-fail-to-select-same-line.html 2016-12-06 23:06:42 UTC (rev 209427)
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>This tests that we can select flex content when they share the same line.</title>
+<style>
+.line {
+ display: flex;
+ color: transparent;
+ font-size: 10px;
+}
+
+div::selection {
+ background-color: green;
+}
+</style>
+</head>
+<body>
+<div class="line"><div> </div><div> </div></div>
+<script>
+ document.execCommand('selectAll', false, null);
+</script>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (209426 => 209427)
--- trunk/Source/WebCore/ChangeLog 2016-12-06 23:01:56 UTC (rev 209426)
+++ trunk/Source/WebCore/ChangeLog 2016-12-06 23:06:42 UTC (rev 209427)
@@ -1,3 +1,25 @@
+2016-12-06 Zalan Bujtas <za...@apple.com>
+
+ Can not select whole line when using flexbox
+ https://bugs.webkit.org/show_bug.cgi?id=165299
+
+ Reviewed by David Hyatt.
+
+ RootInlineBox::selectionTopAdjustedForPrecedingBlock assumes that the preceding block is
+ always above the current line. However in certain layout contexts (flex as an example) the block before
+ could just be on the same line as the current one.
+
+ This patch checks if we actually need to adjust the selection top to avoid vertical selection overlap.
+
+ Test: fast/flexbox/flexbox-fail-to-select-same-line.html
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::blockBeforeWithinSelectionRoot): Deleted.
+ * rendering/RenderBlock.h:
+ * rendering/RootInlineBox.cpp:
+ (WebCore::blockBeforeWithinSelectionRoot):
+ (WebCore::RootInlineBox::selectionTopAdjustedForPrecedingBlock):
+
2016-12-06 Ryosuke Niwa <rn...@webkit.org>
Add more assertions to ElementQueue diagnose a bug
Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (209426 => 209427)
--- trunk/Source/WebCore/rendering/RenderBlock.cpp 2016-12-06 23:01:56 UTC (rev 209426)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp 2016-12-06 23:06:42 UTC (rev 209427)
@@ -2201,38 +2201,6 @@
return logicalRight;
}
-RenderBlock* RenderBlock::blockBeforeWithinSelectionRoot(LayoutSize& offset) const
-{
- if (isSelectionRoot())
- return nullptr;
-
- const RenderElement* object = this;
- RenderObject* sibling;
- do {
- sibling = object->previousSibling();
- while (sibling && (!is<RenderBlock>(*sibling) || downcast<RenderBlock>(*sibling).isSelectionRoot()))
- sibling = sibling->previousSibling();
-
- offset -= LayoutSize(downcast<RenderBlock>(*object).logicalLeft(), downcast<RenderBlock>(*object).logicalTop());
- object = object->parent();
- } while (!sibling && is<RenderBlock>(object) && !downcast<RenderBlock>(*object).isSelectionRoot());
-
- if (!sibling)
- return nullptr;
-
- RenderBlock* beforeBlock = downcast<RenderBlock>(sibling);
-
- offset += LayoutSize(beforeBlock->logicalLeft(), beforeBlock->logicalTop());
-
- RenderObject* child = beforeBlock->lastChild();
- while (is<RenderBlock>(child)) {
- beforeBlock = downcast<RenderBlock>(child);
- offset += LayoutSize(beforeBlock->logicalLeft(), beforeBlock->logicalTop());
- child = beforeBlock->lastChild();
- }
- return beforeBlock;
-}
-
TrackedRendererListHashSet* RenderBlock::positionedObjects() const
{
return positionedDescendantsMap().positionedRenderers(*this);
Modified: trunk/Source/WebCore/rendering/RenderBlock.h (209426 => 209427)
--- trunk/Source/WebCore/rendering/RenderBlock.h 2016-12-06 23:01:56 UTC (rev 209426)
+++ trunk/Source/WebCore/rendering/RenderBlock.h 2016-12-06 23:06:42 UTC (rev 209427)
@@ -176,7 +176,7 @@
LayoutRect logicalRightSelectionGap(RenderBlock& rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
RenderBoxModelObject* selObj, LayoutUnit logicalRight, LayoutUnit logicalTop, LayoutUnit logicalHeight, const LogicalSelectionOffsetCaches&, const PaintInfo*);
void getSelectionGapInfo(SelectionState, bool& leftGap, bool& rightGap);
- RenderBlock* blockBeforeWithinSelectionRoot(LayoutSize& offset) const;
+ bool isSelectionRoot() const;
LayoutRect logicalRectToPhysicalRect(const LayoutPoint& physicalPosition, const LayoutRect& logicalRect);
@@ -457,7 +457,6 @@
return selectionGapRectsForRepaint(repaintContainer);
}
bool shouldPaintSelectionGaps() const final;
- bool isSelectionRoot() const;
GapRects selectionGaps(RenderBlock& rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches&, const PaintInfo* = 0);
// FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
Modified: trunk/Source/WebCore/rendering/RootInlineBox.cpp (209426 => 209427)
--- trunk/Source/WebCore/rendering/RootInlineBox.cpp 2016-12-06 23:01:56 UTC (rev 209426)
+++ trunk/Source/WebCore/rendering/RootInlineBox.cpp 2016-12-06 23:06:42 UTC (rev 209427)
@@ -641,29 +641,64 @@
return prevBottom;
}
+static RenderBlock* blockBeforeWithinSelectionRoot(const RenderBlockFlow& blockFlow, LayoutSize& offset)
+{
+ if (blockFlow.isSelectionRoot())
+ return nullptr;
+
+ const RenderElement* object = &blockFlow;
+ RenderObject* sibling;
+ do {
+ sibling = object->previousSibling();
+ while (sibling && (!is<RenderBlock>(*sibling) || downcast<RenderBlock>(*sibling).isSelectionRoot()))
+ sibling = sibling->previousSibling();
+
+ offset -= LayoutSize(downcast<RenderBlock>(*object).logicalLeft(), downcast<RenderBlock>(*object).logicalTop());
+ object = object->parent();
+ } while (!sibling && is<RenderBlock>(object) && !downcast<RenderBlock>(*object).isSelectionRoot());
+
+ if (!sibling)
+ return nullptr;
+
+ RenderBlock* beforeBlock = downcast<RenderBlock>(sibling);
+
+ offset += LayoutSize(beforeBlock->logicalLeft(), beforeBlock->logicalTop());
+
+ RenderObject* child = beforeBlock->lastChild();
+ while (is<RenderBlock>(child)) {
+ beforeBlock = downcast<RenderBlock>(child);
+ offset += LayoutSize(beforeBlock->logicalLeft(), beforeBlock->logicalTop());
+ child = beforeBlock->lastChild();
+ }
+ return beforeBlock;
+}
+
LayoutUnit RootInlineBox::selectionTopAdjustedForPrecedingBlock() const
{
const RootInlineBox& rootBox = root();
LayoutUnit top = selectionTop();
- RenderObject::SelectionState blockSelectionState = rootBox.blockFlow().selectionState();
+ auto blockSelectionState = rootBox.blockFlow().selectionState();
if (blockSelectionState != RenderObject::SelectionInside && blockSelectionState != RenderObject::SelectionEnd)
return top;
LayoutSize offsetToBlockBefore;
- if (RenderBlock* block = rootBox.blockFlow().blockBeforeWithinSelectionRoot(offsetToBlockBefore)) {
- if (is<RenderBlockFlow>(*block)) {
- if (RootInlineBox* lastLine = downcast<RenderBlockFlow>(*block).lastRootBox()) {
- RenderObject::SelectionState lastLineSelectionState = lastLine->selectionState();
- if (lastLineSelectionState != RenderObject::SelectionInside && lastLineSelectionState != RenderObject::SelectionStart)
- return top;
+ auto* blockBefore = blockBeforeWithinSelectionRoot(rootBox.blockFlow(), offsetToBlockBefore);
+ if (!is<RenderBlockFlow>(blockBefore))
+ return top;
- LayoutUnit lastLineSelectionBottom = lastLine->selectionBottom() + offsetToBlockBefore.height();
- top = std::max(top, lastLineSelectionBottom);
- }
- }
+ // Do not adjust blocks sharing the same line.
+ if (!offsetToBlockBefore.height())
+ return top;
+
+ if (auto* lastLine = downcast<RenderBlockFlow>(*blockBefore).lastRootBox()) {
+ RenderObject::SelectionState lastLineSelectionState = lastLine->selectionState();
+ if (lastLineSelectionState != RenderObject::SelectionInside && lastLineSelectionState != RenderObject::SelectionStart)
+ return top;
+
+ LayoutUnit lastLineSelectionBottom = lastLine->selectionBottom() + offsetToBlockBefore.height();
+ top = std::max(top, lastLineSelectionBottom);
}
-
return top;
}