Diff
Modified: trunk/LayoutTests/ChangeLog (266122 => 266123)
--- trunk/LayoutTests/ChangeLog 2020-08-25 16:30:51 UTC (rev 266122)
+++ trunk/LayoutTests/ChangeLog 2020-08-25 16:32:24 UTC (rev 266123)
@@ -1,3 +1,25 @@
+2020-08-25 Darin Adler <[email protected]>
+
+ REGRESSION (r266028): platform/ios/ios/fast/coordinates/range-client-rects.html
+ https://bugs.webkit.org/show_bug.cgi?id=215772
+
+ Reviewed by Anders Carlsson.
+
+ * platform/ios-wk2/TestExpectations: Removed failure expectation.
+
+ * platform/ios/ios/fast/coordinates/element-client-rects-expected.txt:
+ * platform/ios/ios/fast/coordinates/element-client-rects.html:
+ * platform/ios/ios/fast/coordinates/range-client-rects-expected.txt:
+ * platform/ios/ios/fast/coordinates/range-client-rects.html:
+ Changed tests so it's easier to read their results by putting rectangles and
+ rectangle lists into strings instead of comparing one value per line.
+
+ * platform/ios/ios/fast/coordinates/resources/helpers.js:
+ (rectString): Added.
+ (rectStrings): Added.
+ (setExpectedClientRectValues): Deleted.
+ (verifyClientRect): Deleted.
+
2020-08-25 Hector Lopez <[email protected]>
[ macOS wk2 Debug ] http/tests/websocket/construct-in-detached-frame.html is a flaky crash
Modified: trunk/LayoutTests/platform/ios/ios/fast/coordinates/element-client-rects-expected.txt (266122 => 266123)
--- trunk/LayoutTests/platform/ios/ios/fast/coordinates/element-client-rects-expected.txt 2020-08-25 16:30:51 UTC (rev 266122)
+++ trunk/LayoutTests/platform/ios/ios/fast/coordinates/element-client-rects-expected.txt 2020-08-25 16:32:24 UTC (rev 266123)
@@ -1,32 +1,14 @@
This tests Element.getBoundingClientRects and getClientRects positions when unscaled, scaled, and panned.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
unscaled
-PASS clientRect.left is 100
-PASS clientRect.right is 200
-PASS clientRect.top is 100
-PASS clientRect.bottom is 200
-PASS clientRect.width is 100
-PASS clientRect.height is 100
-PASS clientRect.left is 100
-PASS clientRect.right is 200
-PASS clientRect.top is 100
-PASS clientRect.bottom is 200
-PASS clientRect.width is 100
-PASS clientRect.height is 100
+PASS rectString(document.getElementById('box').getBoundingClientRect()) is "(100,100 100x100)"
+PASS rectStrings(document.getElementById('box').getClientRects()) is "(100,100 100x100)"
scaled and panned
-PASS clientRect.left is 90
-PASS clientRect.right is 190
-PASS clientRect.top is 90
-PASS clientRect.bottom is 190
-PASS clientRect.width is 100
-PASS clientRect.height is 100
-PASS clientRect.left is 90
-PASS clientRect.right is 190
-PASS clientRect.top is 90
-PASS clientRect.bottom is 190
-PASS clientRect.width is 100
-PASS clientRect.height is 100
+PASS rectString(document.getElementById('box').getBoundingClientRect()) is "(90,90 100x100)"
+PASS rectStrings(document.getElementById('box').getClientRects()) is "(90,90 100x100)"
+
PASS successfullyParsed is true
TEST COMPLETE
Modified: trunk/LayoutTests/platform/ios/ios/fast/coordinates/element-client-rects.html (266122 => 266123)
--- trunk/LayoutTests/platform/ios/ios/fast/coordinates/element-client-rects.html 2020-08-25 16:30:51 UTC (rev 266122)
+++ trunk/LayoutTests/platform/ios/ios/fast/coordinates/element-client-rects.html 2020-08-25 16:32:24 UTC (rev 266123)
@@ -20,18 +20,20 @@
var box = document.getElementById('box');
+debug('');
debug('unscaled');
-setExpectedClientRectValues(100, 200, 100, 200, 100, 100);
-verifyClientRect(box.getBoundingClientRect());
-verifyClientRect(box.getClientRects()[0]);
+shouldBeEqualToString("rectString(document.getElementById('box').getBoundingClientRect())", "(100,100 100x100)");
+shouldBeEqualToString("rectStrings(document.getElementById('box').getClientRects())", "(100,100 100x100)");
debug('');
debug('scaled and panned');
setInitialScaleAndPanBy(scale, panX, panY);
-setExpectedClientRectValues(100-panX, 200-panX, 100-panY, 200-panY, 100, 100);
-verifyClientRect(box.getBoundingClientRect());
-verifyClientRect(box.getClientRects()[0]);
+var rect = "(" + (100-panX) + "," + (100-panY) + " 100x100)";
+shouldBeEqualToString("rectString(document.getElementById('box').getBoundingClientRect())", rect);
+shouldBeEqualToString("rectStrings(document.getElementById('box').getClientRects())", rect);
+debug('');
+
var successfullyParsed = true;
endTest();
</script>
Modified: trunk/LayoutTests/platform/ios/ios/fast/coordinates/range-client-rects-expected.txt (266122 => 266123)
--- trunk/LayoutTests/platform/ios/ios/fast/coordinates/range-client-rects-expected.txt 2020-08-25 16:30:51 UTC (rev 266122)
+++ trunk/LayoutTests/platform/ios/ios/fast/coordinates/range-client-rects-expected.txt 2020-08-25 16:32:24 UTC (rev 266123)
@@ -1,45 +1,14 @@
This tests Range.getBoundingClientRects and getClientRects positions when unscaled, scaled, and panned.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-PASS range.getClientRects().length is 2
+
unscaled
-PASS clientRect.left is 0
-PASS clientRect.right is 1500
-PASS clientRect.top is 0
-PASS clientRect.bottom is 1500
-PASS clientRect.width is 1500
-PASS clientRect.height is 1500
-PASS clientRect.left is 0
-PASS clientRect.right is 1500
-PASS clientRect.top is 0
-PASS clientRect.bottom is 1500
-PASS clientRect.width is 1500
-PASS clientRect.height is 1500
-PASS clientRect.left is 100
-PASS clientRect.right is 200
-PASS clientRect.top is 100
-PASS clientRect.bottom is 200
-PASS clientRect.width is 100
-PASS clientRect.height is 100
+PASS rectString(getSelection().getRangeAt(0).getBoundingClientRect()) is "(0,0 1500x1500)"
+PASS rectStrings(getSelection().getRangeAt(0).getClientRects()) is "(100,100 100x100) (0,0 1500x1500)"
scaled and panned
-PASS clientRect.left is -10
-PASS clientRect.right is 1490
-PASS clientRect.top is -10
-PASS clientRect.bottom is 1490
-PASS clientRect.width is 1500
-PASS clientRect.height is 1500
-PASS clientRect.left is -10
-PASS clientRect.right is 1490
-PASS clientRect.top is -10
-PASS clientRect.bottom is 1490
-PASS clientRect.width is 1500
-PASS clientRect.height is 1500
-PASS clientRect.left is 90
-PASS clientRect.right is 190
-PASS clientRect.top is 90
-PASS clientRect.bottom is 190
-PASS clientRect.width is 100
-PASS clientRect.height is 100
+PASS rectString(getSelection().getRangeAt(0).getBoundingClientRect()) is "(-10,-10 1500x1500)"
+PASS rectStrings(getSelection().getRangeAt(0).getClientRects()) is "(90,90 100x100) (-10,-10 1500x1500)"
+
PASS successfullyParsed is true
TEST COMPLETE
Modified: trunk/LayoutTests/platform/ios/ios/fast/coordinates/range-client-rects.html (266122 => 266123)
--- trunk/LayoutTests/platform/ios/ios/fast/coordinates/range-client-rects.html 2020-08-25 16:30:51 UTC (rev 266122)
+++ trunk/LayoutTests/platform/ios/ios/fast/coordinates/range-client-rects.html 2020-08-25 16:32:24 UTC (rev 266123)
@@ -31,25 +31,22 @@
// positioned absolutely inside it. The first client rect of the
// Range is the box.
document.execCommand("SelectAll");
-var range = window.getSelection().getRangeAt(0);
-shouldBe('range.getClientRects().length', '2');
+debug('');
debug('unscaled');
-setExpectedClientRectValues(0, 1500, 0, 1500, 1500, 1500);
-verifyClientRect(range.getBoundingClientRect());
-verifyClientRect(range.getClientRects()[1]);
-setExpectedClientRectValues(100, 200, 100, 200, 100, 100);
-verifyClientRect(range.getClientRects()[0]);
+shouldBeEqualToString("rectString(getSelection().getRangeAt(0).getBoundingClientRect())", "(0,0 1500x1500)");
+shouldBeEqualToString("rectStrings(getSelection().getRangeAt(0).getClientRects())", "(100,100 100x100) (0,0 1500x1500)");
debug('');
debug('scaled and panned');
setInitialScaleAndPanBy(scale, panX, panY);
-setExpectedClientRectValues(0-panX, 1500-panX, 0-panY, 1500-panY, 1500, 1500);
-verifyClientRect(range.getBoundingClientRect());
-verifyClientRect(range.getClientRects()[1]);
-setExpectedClientRectValues(100-panX, 200-panX, 100-panY, 200-panY, 100, 100);
-verifyClientRect(range.getClientRects()[0]);
+var firstRect = "(" + (0-panX) + "," + (0-panX) + " 1500x1500)";
+var secondRect = "(" + (100-panX) + "," + (100-panX) + " 100x100)";
+shouldBeEqualToString("rectString(getSelection().getRangeAt(0).getBoundingClientRect())", firstRect);
+shouldBeEqualToString("rectStrings(getSelection().getRangeAt(0).getClientRects())", secondRect + " " + firstRect);
+debug('');
+
setDisplayOnDescriptionAndConsole('block');
var successfullyParsed = true;
Modified: trunk/LayoutTests/platform/ios/ios/fast/coordinates/resources/helpers.js (266122 => 266123)
--- trunk/LayoutTests/platform/ios/ios/fast/coordinates/resources/helpers.js 2020-08-25 16:30:51 UTC (rev 266122)
+++ trunk/LayoutTests/platform/ios/ios/fast/coordinates/resources/helpers.js 2020-08-25 16:32:24 UTC (rev 266123)
@@ -19,25 +19,21 @@
// To verify client rect positions.
-var expectedLeft, expectedRight, expectedTop, expectedBottom, expectedWidth, expectedHeight;
-function setExpectedClientRectValues(left, right, top, bottom, width, height) {
- expectedLeft = left;
- expectedRight = right;
- expectedTop = top;
- expectedBottom = bottom;
- expectedWidth = width;
- expectedHeight = width;
+function rectString(rect)
+{
+ return "(" + rect.x + "," + rect.y + " " + rect.width + "x" + rect.height + ")";
}
-var clientRect;
-function verifyClientRect(o) {
- clientRect = o;
- shouldBe('clientRect.left', expectedLeft.toString());
- shouldBe('clientRect.right', expectedRight.toString());
- shouldBe('clientRect.top', expectedTop.toString());
- shouldBe('clientRect.bottom', expectedBottom.toString());
- shouldBe('clientRect.width', expectedWidth.toString());
- shouldBe('clientRect.height', expectedHeight.toString());
+function rectStrings(rectList)
+{
+ var text = "";
+ var i;
+ for (i = 0; i < rectList.length; i++) {
+ if (i != 0)
+ text += " ";
+ text += rectString(rectList[i]);
+ }
+ return text;
}
// To verify page scroll offsets.
Modified: trunk/LayoutTests/platform/ios-wk2/TestExpectations (266122 => 266123)
--- trunk/LayoutTests/platform/ios-wk2/TestExpectations 2020-08-25 16:30:51 UTC (rev 266122)
+++ trunk/LayoutTests/platform/ios-wk2/TestExpectations 2020-08-25 16:32:24 UTC (rev 266123)
@@ -1863,8 +1863,6 @@
webkit.org/b/215773 http/tests/websocket/tests/hybi/client-close-2.html [ Pass Failure ]
-webkit.org/b/215772 platform/ios/ios/fast/coordinates/range-client-rects.html [ Failure ]
-
webkit.org/b/215783 [ Debug ] imported/w3c/web-platform-tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-fetch-error-external-module.html [ Pass Failure ]
webkit.org/b/209461 imported/w3c/web-platform-tests/css/css-grid/grid-items/grid-item-dynamic-min-contribution-001.html [ Failure ]
Modified: trunk/Source/WebCore/ChangeLog (266122 => 266123)
--- trunk/Source/WebCore/ChangeLog 2020-08-25 16:30:51 UTC (rev 266122)
+++ trunk/Source/WebCore/ChangeLog 2020-08-25 16:32:24 UTC (rev 266123)
@@ -1,3 +1,35 @@
+2020-08-25 Darin Adler <[email protected]>
+
+ REGRESSION (r266028): platform/ios/ios/fast/coordinates/range-client-rects.html
+ https://bugs.webkit.org/show_bug.cgi?id=215772
+
+ Reviewed by Anders Carlsson.
+
+ * dom/Range.cpp:
+ (WebCore::Range::getClientRects const): Call updateLayout since it's not safe
+ to start working with the render tree without updating it first. Not required
+ to fix this bug, but an obvious omission. Ideally should make a test to show
+ this is needed.
+ (WebCore::Range::getBoundingClientRect const): Ditto.
+
+ * dom/SimpleRange.cpp:
+ (WebCore::order): Added.
+ (WebCore::documentOrder): Removed bogus special case. Test case proving this is
+ wrong is coming in the next documentOrder-related patch. Not needed to fix this
+ bug, but seems dangerous to leave this in the tree the way it was.
+ (WebCore::firstIntersectingNodeWithDeprecatedZeroOffsetStartQuirk): Added.
+ (WebCore::IntersectingNodeIterator::IntersectingNodeIterator): Added.
+
+ * dom/SimpleRange.h: Added intersectingNodesWithDeprecatedZeroOffsetStartQuirk.
+
+ * rendering/RenderObject.cpp:
+ (WebCore::borderAndTextRects): Use intersectingNodesWithDeprecatedZeroOffsetStartQuirk
+ because this needs to get the set of nodes in a way that works for our incorrectly
+ formed selection ranges and includes the first element even when the range technically
+ starts inside that element. We need to fix those, but that's a big project that affects
+ a lot of editing code. For now, restoring the old quirk is expedient.
+ (WebCore::RenderObject::collectSelectionRectsInternal): Ditto.
+
2020-08-25 Eric Carlson <[email protected]>
[macOS] Update audio arbitration manager when audio transport changes
Modified: trunk/Source/WebCore/dom/Range.cpp (266122 => 266123)
--- trunk/Source/WebCore/dom/Range.cpp 2020-08-25 16:30:51 UTC (rev 266122)
+++ trunk/Source/WebCore/dom/Range.cpp 2020-08-25 16:32:24 UTC (rev 266123)
@@ -1358,11 +1358,13 @@
Ref<DOMRectList> Range::getClientRects() const
{
+ startContainer().document().updateLayout();
return DOMRectList::create(RenderObject::clientBorderAndTextRects(makeSimpleRange(*this)));
}
Ref<DOMRect> Range::getBoundingClientRect() const
{
+ startContainer().document().updateLayout();
return DOMRect::create(unionRectIgnoringZeroRects(RenderObject::clientBorderAndTextRects(makeSimpleRange(*this))));
}
Modified: trunk/Source/WebCore/dom/SimpleRange.cpp (266122 => 266123)
--- trunk/Source/WebCore/dom/SimpleRange.cpp 2020-08-25 16:30:51 UTC (rev 266122)
+++ trunk/Source/WebCore/dom/SimpleRange.cpp 2020-08-25 16:32:24 UTC (rev 266123)
@@ -81,13 +81,22 @@
}
// FIXME: Create BoundaryPoint.cpp and move this there.
+// FIXME: Once we move to C++20, replace with the C++20 <=> operator.
+// FIXME: This could return std::strong_ordering if we had that, or the equivalent.
+static PartialOrdering order(unsigned a, unsigned b)
+{
+ if (a < b)
+ return PartialOrdering::less;
+ if (a > b)
+ return PartialOrdering::greater;
+ return PartialOrdering::equivalent;
+}
+
+// FIXME: Create BoundaryPoint.cpp and move this there.
PartialOrdering documentOrder(const BoundaryPoint& a, const BoundaryPoint& b)
{
- if (a.offset == b.offset)
- return documentOrder(a.container, b.container);
-
if (a.container.ptr() == b.container.ptr())
- return a.offset < b.offset ? PartialOrdering::less : PartialOrdering::greater;
+ return order(a.offset, b.offset);
for (auto ancestor = b.container.ptr(); ancestor; ) {
auto nextAncestor = ancestor->parentOrShadowHostNode();
@@ -144,6 +153,17 @@
return NodeTraversal::nextSkippingChildren(range.end.container);
}
+static RefPtr<Node> firstIntersectingNodeWithDeprecatedZeroOffsetStartQuirk(const SimpleRange& range)
+{
+ if (range.start.container->isCharacterDataNode())
+ return range.start.container.ptr();
+ if (auto child = range.start.container->traverseToChildAt(range.start.offset))
+ return child;
+ if (!range.start.offset)
+ return range.start.container.ptr();
+ return NodeTraversal::nextSkippingChildren(range.start.container);
+}
+
IntersectingNodeIterator::IntersectingNodeIterator(const SimpleRange& range)
: m_node(firstIntersectingNode(range))
, m_pastLastNode(nodePastLastIntersectingNode(range))
@@ -151,6 +171,13 @@
enforceEndInvariant();
}
+IntersectingNodeIterator::IntersectingNodeIterator(const SimpleRange& range, QuirkFlag)
+ : m_node(firstIntersectingNodeWithDeprecatedZeroOffsetStartQuirk(range))
+ , m_pastLastNode(nodePastLastIntersectingNode(range))
+{
+ enforceEndInvariant();
+}
+
void IntersectingNodeIterator::advance()
{
ASSERT(m_node);
Modified: trunk/Source/WebCore/dom/SimpleRange.h (266122 => 266123)
--- trunk/Source/WebCore/dom/SimpleRange.h 2020-08-25 16:30:51 UTC (rev 266122)
+++ trunk/Source/WebCore/dom/SimpleRange.h 2020-08-25 16:32:24 UTC (rev 266123)
@@ -68,6 +68,9 @@
class IntersectingNodeRange;
IntersectingNodeRange intersectingNodes(const SimpleRange&);
+class IntersectingNodeRangeWithQuirk;
+IntersectingNodeRangeWithQuirk intersectingNodesWithDeprecatedZeroOffsetStartQuirk(const SimpleRange&);
+
struct OffsetRange {
unsigned start { 0 };
unsigned end { 0 };
@@ -78,6 +81,9 @@
public:
IntersectingNodeIterator(const SimpleRange&);
+ enum QuirkFlag { DeprecatedZeroOffsetStartQuirk };
+ IntersectingNodeIterator(const SimpleRange&, QuirkFlag);
+
Node& operator*() const { return *m_node; }
Node* operator->() const { ASSERT(m_node); return m_node.get(); }
@@ -107,16 +113,37 @@
SimpleRange m_range;
};
+class IntersectingNodeRangeWithQuirk {
+public:
+ IntersectingNodeRangeWithQuirk(const SimpleRange&);
+
+ IntersectingNodeIterator begin() const { return { m_range, IntersectingNodeIterator::DeprecatedZeroOffsetStartQuirk }; }
+ static constexpr std::nullptr_t end() { return nullptr; }
+
+private:
+ SimpleRange m_range;
+};
+
inline IntersectingNodeRange::IntersectingNodeRange(const SimpleRange& range)
: m_range(range)
{
}
+inline IntersectingNodeRangeWithQuirk::IntersectingNodeRangeWithQuirk(const SimpleRange& range)
+ : m_range(range)
+{
+}
+
inline IntersectingNodeRange intersectingNodes(const SimpleRange& range)
{
return { range };
}
+inline IntersectingNodeRangeWithQuirk intersectingNodesWithDeprecatedZeroOffsetStartQuirk(const SimpleRange& range)
+{
+ return { range };
+}
+
inline SimpleRange makeSimpleRangeHelper(BoundaryPoint&& start, BoundaryPoint&& end)
{
return { WTFMove(start), WTFMove(end) };
Modified: trunk/Source/WebCore/rendering/RenderObject.cpp (266122 => 266123)
--- trunk/Source/WebCore/rendering/RenderObject.cpp 2020-08-25 16:30:51 UTC (rev 266122)
+++ trunk/Source/WebCore/rendering/RenderObject.cpp 2020-08-25 16:32:24 UTC (rev 266123)
@@ -1980,7 +1980,7 @@
bool useVisibleBounds = behavior.contains(RenderObject::BoundingRectBehavior::UseVisibleBounds);
HashSet<Element*> selectedElementsSet;
- for (auto& node : intersectingNodes(range)) {
+ for (auto& node : intersectingNodesWithDeprecatedZeroOffsetStartQuirk(range)) {
if (is<Element>(node))
selectedElementsSet.add(&downcast<Element>(node));
}
@@ -1998,7 +1998,7 @@
RenderObject::VisibleRectContextOption::ApplyCompositedContainerScrolls
};
- for (auto& node : intersectingNodes(range)) {
+ for (auto& node : intersectingNodesWithDeprecatedZeroOffsetStartQuirk(range)) {
if (is<Element>(node) && selectedElementsSet.contains(&downcast<Element>(node)) && (useVisibleBounds || !node.parentElement() || !selectedElementsSet.contains(node.parentElement()))) {
if (auto renderer = downcast<Element>(node).renderBoxModelObject()) {
if (useVisibleBounds) {
@@ -2104,7 +2104,7 @@
Vector<SelectionRect> newRects;
bool hasFlippedWritingMode = range.start.container->renderer() && range.start.container->renderer()->style().isFlippedBlocksWritingMode();
bool containsDifferentWritingModes = false;
- for (auto& node : intersectingNodes(range)) {
+ for (auto& node : intersectingNodesWithDeprecatedZeroOffsetStartQuirk(range)) {
auto renderer = node.renderer();
// Only ask leaf render objects for their line box rects.
if (renderer && !renderer->firstChildSlow() && renderer->style().userSelect() != UserSelect::None) {