Skip to content

Commit

Permalink
Fix render tree construction when inlines are inserted in reverse aft…
Browse files Browse the repository at this point in the history
…er a block in a continuation

https://bugs.webkit.org/show_bug.cgi?id=274762
rdar://problem/128826228

Reviewed by Darin Adler.

This patch aligns WebKit with Blink / Chromium and
Gecko / Firefox.

Merge: https://chromium.googlesource.com/chromium/blink/+/6ac676e5e68e3271321b9c8236192b6a530d055e

When inserting inlines after a block inside of an inline continuation,
if we insert inline content in reverse DOM order, we can (depending on
when we attach) end up appending the renderers in the wrong location,
leading to visual aberrations.

The fix is in RenderTreeBuilder, where we should always attach behind our
beforeChild if we're inserting an inline and beforeChild is an inline,
regardless of other continuation state.

* Source/WebCore/rendering/updating/RenderTreeBuilderInline.cpp:
(WebCore::RenderTreeBuilder::Inline::insertChildToContinuation):
* LayoutTests/fast/inline/continuation-inlines-inserted-in-reverse-after-block.html: Add Test Case
* LayoutTests/fast/inline/continuation-inlines-inserted-in-reverse-after-block-expected.txt: Add Test Case Expectation
* LayoutTests/platform/mac/tables/mozilla/bugs/bug113235-3-expected.txt: Rebaselined
* LayoutTests/platform/mac/tables/mozilla/bugs/bug113235-3-expected.png: Ditto
* LayoutTests/platform/glib/tables/mozilla/bugs/bug113235-3-expected.txt: Ditto
* LayoutTests/platform/ios/tables/mozilla/bugs/bug113235-3-expected.txt: Ditto

Canonical link: https://commits.webkit.org/279422@main
  • Loading branch information
Ahmad Saleem committed May 29, 2024
1 parent 8e02837 commit 4af8f05
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
You should see two lines, both with 1,2,3.

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


PASS document.getElementById('3').offsetLeft is >= document.getElementById('2').offsetLeft
PASS document.getElementById('2').offsetLeft is >= document.getElementById('1').offsetLeft
PASS successfullyParsed is true

TEST COMPLETE
1,2,3,
1,2,3,

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<script src="../../resources/js-test.js"></script>
<div id="console"></div>

<span id="container"></span>
<span id="reference"><div></div><span>1,</span><span>2,</span><span>3,</span><div></div></span>

<script>
description('You should see two lines, both with 1,2,3.');
var last;

function insert(tagName, id)
{
last = container.insertBefore(document.createElement(tagName), last);
if (id)
last.id = id;
getComputedStyle(last).color; // attach.
return last;
}

var container = document.getElementById('container');
var div = container.appendChild(document.createElement('div'));
getComputedStyle(div).color; // attach.

// This inserts the elements in the reverse order they appear in the DOM
// calling layout()
insert('div');
insert('span', 3).textContent = '3,';
insert('span', 2).textContent = '2,';
insert('span', 1).textContent = '1,';
shouldBeGreaterThanOrEqual("document.getElementById('3').offsetLeft", "document.getElementById('2').offsetLeft");
shouldBeGreaterThanOrEqual("document.getElementById('2').offsetLeft", "document.getElementById('1').offsetLeft");
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -317,14 +317,33 @@ layer at (0,0) size 785x982
RenderInline {A} at (0,0) size 12x17
RenderText {#text} at (0,0) size 12x17
text run at (0,0) width 12: "X"
RenderBlock (anonymous) at (0,674) size 769x46
RenderBlock (anonymous) at (0,674) size 769x28
RenderTable {TABLE} at (0,0) size 53x28 [border: (1px outset #808080)]
RenderTableSection {TBODY} at (1,1) size 51x26
RenderTableRow {TR} at (0,2) size 51x22
RenderTableCell {TD} at (2,2) size 47x22 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=1]
RenderText {#text} at (2,2) size 43x17
text run at (2,2) width 43: "table-9"
RenderBlock {DIV} at (0,28) size 769x18
RenderBlock (anonymous) at (0,702) size 769x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderBlock (anonymous) at (0,702) size 769x18
RenderBlock {DIV} at (0,0) size 769x18
RenderText {#text} at (0,0) size 86x17
text run at (0,0) width 86: "div after table"
RenderBlock (anonymous) at (0,720) size 769x18
Expand Down Expand Up @@ -429,14 +448,37 @@ layer at (0,0) size 785x982
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderBlock (anonymous) at (0,838) size 769x46
RenderBlock (anonymous) at (0,838) size 769x28
RenderTable {TABLE} at (0,0) size 61x28 [border: (1px outset #808080)]
RenderTableSection {TBODY} at (1,1) size 59x26
RenderTableRow {TR} at (0,2) size 59x22
RenderTableCell {TD} at (2,2) size 55x22 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=1]
RenderText {#text} at (2,2) size 51x17
text run at (2,2) width 51: "table-11"
RenderBlock {DIV} at (0,28) size 769x18
RenderBlock (anonymous) at (0,866) size 769x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderBlock (anonymous) at (0,866) size 769x18
RenderBlock {DIV} at (0,0) size 769x18
RenderText {#text} at (0,0) size 86x17
text run at (0,0) width 86: "div after table"
RenderBlock (anonymous) at (0,884) size 769x18
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,14 +317,33 @@ layer at (0,0) size 800x1054
RenderInline {A} at (0,0) size 12x19
RenderText {#text} at (0,0) size 12x19
text run at (0,0) width 12: "X"
RenderBlock (anonymous) at (0,724) size 784x50
RenderBlock (anonymous) at (0,724) size 784x30
RenderTable {TABLE} at (0,0) size 55x30 [border: (1px outset #808080)]
RenderTableSection {TBODY} at (1,1) size 53x28
RenderTableRow {TR} at (0,2) size 53x24
RenderTableCell {TD} at (2,2) size 49x24 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=1]
RenderText {#text} at (2,2) size 45x19
text run at (2,2) width 45: "table-9"
RenderBlock {DIV} at (0,30) size 784x20
RenderBlock (anonymous) at (0,754) size 784x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderBlock (anonymous) at (0,754) size 784x20
RenderBlock {DIV} at (0,0) size 784x20
RenderText {#text} at (0,0) size 89x19
text run at (0,0) width 89: "div after table"
RenderBlock (anonymous) at (0,774) size 784x20
Expand Down Expand Up @@ -429,14 +448,37 @@ layer at (0,0) size 800x1054
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderBlock (anonymous) at (0,900) size 784x50
RenderBlock (anonymous) at (0,900) size 784x30
RenderTable {TABLE} at (0,0) size 62x30 [border: (1px outset #808080)]
RenderTableSection {TBODY} at (1,1) size 60x28
RenderTableRow {TR} at (0,2) size 60x24
RenderTableCell {TD} at (2,2) size 56x24 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=1]
RenderText {#text} at (2,2) size 52x19
text run at (2,2) width 52: "table-11"
RenderBlock {DIV} at (0,30) size 784x20
RenderBlock (anonymous) at (0,930) size 784x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderBlock (anonymous) at (0,930) size 784x20
RenderBlock {DIV} at (0,0) size 784x20
RenderText {#text} at (0,0) size 89x19
text run at (0,0) width 89: "div after table"
RenderBlock (anonymous) at (0,950) size 784x20
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -317,14 +317,33 @@ layer at (0,0) size 785x982
RenderInline {A} at (0,0) size 12x18
RenderText {#text} at (0,0) size 12x18
text run at (0,0) width 12: "X"
RenderBlock (anonymous) at (0,674) size 769x46
RenderBlock (anonymous) at (0,674) size 769x28
RenderTable {TABLE} at (0,0) size 55x28 [border: (1px outset #808080)]
RenderTableSection {TBODY} at (1,1) size 53x26
RenderTableRow {TR} at (0,2) size 53x22
RenderTableCell {TD} at (2,2) size 49x22 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=1]
RenderText {#text} at (2,2) size 45x18
text run at (2,2) width 45: "table-9"
RenderBlock {DIV} at (0,28) size 769x18
RenderBlock (anonymous) at (0,702) size 769x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderBlock (anonymous) at (0,702) size 769x18
RenderBlock {DIV} at (0,0) size 769x18
RenderText {#text} at (0,0) size 89x18
text run at (0,0) width 89: "div after table"
RenderBlock (anonymous) at (0,720) size 769x18
Expand Down Expand Up @@ -429,14 +448,37 @@ layer at (0,0) size 785x982
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderBlock (anonymous) at (0,838) size 769x46
RenderBlock (anonymous) at (0,838) size 769x28
RenderTable {TABLE} at (0,0) size 62x28 [border: (1px outset #808080)]
RenderTableSection {TBODY} at (1,1) size 60x26
RenderTableRow {TR} at (0,2) size 60x22
RenderTableCell {TD} at (2,2) size 56x22 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=1]
RenderText {#text} at (2,2) size 52x18
text run at (2,2) width 52: "table-11"
RenderBlock {DIV} at (0,28) size 769x18
RenderBlock (anonymous) at (0,866) size 769x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderInline {FONT} at (0,0) size 0x0
RenderBlock (anonymous) at (0,866) size 769x18
RenderBlock {DIV} at (0,0) size 769x18
RenderText {#text} at (0,0) size 89x18
text run at (0,0) width 89: "div after table"
RenderBlock (anonymous) at (0,884) size 769x18
Expand Down
4 changes: 2 additions & 2 deletions Source/WebCore/rendering/updating/RenderTreeBuilderInline.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018 Apple Inc. All rights reserved.
* Copyright (C) 2018-2024 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
Expand Down Expand Up @@ -153,7 +153,7 @@ void RenderTreeBuilder::Inline::insertChildToContinuation(RenderInline& parent,
bool childInline = newChildIsInline(parent, *child);
// The goal here is to match up if we can, so that we can coalesce and create the
// minimal # of continuations needed for the inline.
if (childInline == beforeChildAncestor->isInline())
if (childInline == beforeChildAncestor->isInline() || (beforeChild && beforeChild->isInline()))
return m_builder.attachIgnoringContinuation(*beforeChildAncestor, WTFMove(child), beforeChild);
if (flow->isInline() == childInline)
return m_builder.attachIgnoringContinuation(*flow, WTFMove(child)); // Just treat like an append.
Expand Down

0 comments on commit 4af8f05

Please sign in to comment.