Skip to content
Permalink
Browse files
Content disappears on mouse over.
https://bugs.webkit.org/show_bug.cgi?id=157073
<rdar://problem/24389168>

Reviewed by Simon Fraser.

When a redundant inlinebox is found after constructing the line, we remove it from the tree.
The remove operation marks the ancestor tree dirty (and this newly constructed line is supposed to be clean).
This patch resets this dirty flag on the boxes all the way up to the rootlinebox.
Previously we only cleared the rootinlinebox and we ended up with dirty inlineflowboxes.

Source/WebCore:

Test: fast/text/text-node-remains-dirty-after-calling-surroundContents.html

* rendering/BidiRun.h:
(WebCore::BidiRun::setBox):
* rendering/RenderBlockFlow.h:
* rendering/RenderBlockLineLayout.cpp:
(WebCore::RenderBlockFlow::constructLine):
(WebCore::RenderBlockFlow::removeLineBoxIfNeeded):
(WebCore::RenderBlockFlow::computeBlockDirectionPositionsForLine):
* rendering/RenderBox.cpp:
(WebCore::RenderBox::positionLineBox): Deleted.
* rendering/RenderText.cpp:
(WebCore::RenderText::setText):
(WebCore::RenderText::positionLineBox): Deleted.

LayoutTests:

* fast/text/text-node-remains-dirty-after-calling-surroundContents-expected.html: Added.
* fast/text/text-node-remains-dirty-after-calling-surroundContents.html: Added.


Canonical link: https://commits.webkit.org/175266@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@200220 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
alanbujtas committed Apr 29, 2016
1 parent 027abe7 commit 5d9d15b829bd7b0b1d033a87a564aea7c779704f
@@ -1,3 +1,19 @@
2016-04-28 Zalan Bujtas <zalan@apple.com>

Content disappears on mouse over.
https://bugs.webkit.org/show_bug.cgi?id=157073
<rdar://problem/24389168>

Reviewed by Simon Fraser.

When a redundant inlinebox is found after constructing the line, we remove it from the tree.
The remove operation marks the ancestor tree dirty (and this newly constructed line is supposed to be clean).
This patch resets this dirty flag on the boxes all the way up to the rootlinebox.
Previously we only cleared the rootinlinebox and we ended up with dirty inlineflowboxes.

* fast/text/text-node-remains-dirty-after-calling-surroundContents-expected.html: Added.
* fast/text/text-node-remains-dirty-after-calling-surroundContents.html: Added.

2016-04-27 Brent Fulgham <bfulgham@apple.com>

Make sure we don't mishandle HTMLFrameOwnerElement lifecycle
@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<title>This tests that the span content gets properly laid out after calling surroundContents.</title>
<style>
span {
font-family: -apple-system;
font-size: 12px;
margin-right: 2px;
text-decoration: underline;
}
</style>
</head>
<body>
<span>foobar</span>
<br>PASS if foobar gets underlined while hovering.
</body>
</html>
@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<title>This tests that the span content gets properly laid out after calling surroundContents.</title>
<style>
span {
font-family: -apple-system;
font-size: 12px;
margin-right: 2px;
}

.highlight {
text-decoration: underline;
}
</style>
</head>
<body>
<span id=container>foobar </span>
<br>PASS if foobar gets underlined while hovering.
<script>
var container = document.getElementById("container");
var range = document.createRange();
var newspan = document.createElement("span");
newspan.className = "highlight";

range.selectNodeContents(document.getElementById("container").firstChild);
range.setEnd(document.getElementById("container").firstChild, 6);
range.surroundContents(newspan);
</script>
</body>
</html>
@@ -1,3 +1,31 @@
2016-04-28 Zalan Bujtas <zalan@apple.com>

Content disappears on mouse over.
https://bugs.webkit.org/show_bug.cgi?id=157073
<rdar://problem/24389168>

Reviewed by Simon Fraser.

When a redundant inlinebox is found after constructing the line, we remove it from the tree.
The remove operation marks the ancestor tree dirty (and this newly constructed line is supposed to be clean).
This patch resets this dirty flag on the boxes all the way up to the rootlinebox.
Previously we only cleared the rootinlinebox and we ended up with dirty inlineflowboxes.

Test: fast/text/text-node-remains-dirty-after-calling-surroundContents.html

* rendering/BidiRun.h:
(WebCore::BidiRun::setBox):
* rendering/RenderBlockFlow.h:
* rendering/RenderBlockLineLayout.cpp:
(WebCore::RenderBlockFlow::constructLine):
(WebCore::RenderBlockFlow::removeLineBoxIfNeeded):
(WebCore::RenderBlockFlow::computeBlockDirectionPositionsForLine):
* rendering/RenderBox.cpp:
(WebCore::RenderBox::positionLineBox): Deleted.
* rendering/RenderText.cpp:
(WebCore::RenderText::setText):
(WebCore::RenderText::positionLineBox): Deleted.

2016-04-28 John Wilander <wilander@apple.com>

Allow non-standard HTTP headers in WebSocket handshake
@@ -41,7 +41,7 @@ struct BidiRun : BidiCharacterRun {
std::unique_ptr<BidiRun> takeNext();
RenderObject& renderer() { return m_renderer; }
InlineBox* box() { return m_box; }
void setBox(InlineBox& box) { m_box = &box; }
void setBox(InlineBox* box) { m_box = box; }

private:
RenderObject& m_renderer;
@@ -604,6 +604,8 @@ class RenderBlockFlow : public RenderBlock {
#endif
void setSelectionState(SelectionState) final;

void removeInlineBox(BidiRun&, const RootInlineBox&) const;

public:
// FIXME-BLOCKFLOW: These can be made protected again once all callers have been moved here.
void adjustLinePositionForPagination(RootInlineBox*, LayoutUnit& deltaOffset, bool& overflowsRegion, RenderFlowThread*); // Computes a deltaOffset value that put a line at the top of the next page if it doesn't fit on the current page.
@@ -293,7 +293,7 @@ RootInlineBox* RenderBlockFlow::constructLine(BidiRunList<BidiRun>& bidiRuns, co
continue;

InlineBox* box = createInlineBoxForRenderer(&r->renderer(), false, isOnlyRun);
r->setBox(*box);
r->setBox(box);

if (!rootHasSelectedChildren && box->renderer().selectionState() != RenderObject::SelectionNone)
rootHasSelectedChildren = true;
@@ -950,36 +950,68 @@ BidiRun* RenderBlockFlow::computeInlineDirectionPositionsForSegment(RootInlineBo
return run;
}

void RenderBlockFlow::removeInlineBox(BidiRun& run, const RootInlineBox& rootLineBox) const
{
auto* inlineBox = run.box();
#if !ASSERT_DISABLED
auto* inlineParent = inlineBox->parent();
while (inlineParent && inlineParent != &rootLineBox) {
ASSERT(!inlineParent->isDirty());
inlineParent = inlineParent->parent();
}
ASSERT(!rootLineBox.isDirty());
#endif
auto* parent = inlineBox->parent();
inlineBox->removeFromParent();

auto& renderer = run.renderer();
if (is<RenderText>(renderer))
downcast<RenderText>(renderer).removeTextBox(downcast<InlineTextBox>(*inlineBox));
delete inlineBox;
run.setBox(nullptr);
// removeFromParent() unnecessarily dirties the ancestor subtree.
auto* ancestor = parent;
while (ancestor) {
ancestor->markDirty(false);
if (ancestor == &rootLineBox)
break;
ancestor = ancestor->parent();
}
}

void RenderBlockFlow::computeBlockDirectionPositionsForLine(RootInlineBox* lineBox, BidiRun* firstRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap,
VerticalPositionCache& verticalPositionCache)
{
setLogicalHeight(lineBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, verticalPositionCache));

// Now make sure we place replaced render objects correctly.
for (BidiRun* run = firstRun; run; run = run->next()) {
for (auto* run = firstRun; run; run = run->next()) {
ASSERT(run->box());
if (!run->box())
continue; // Skip runs with no line boxes.

InlineBox& box = *run->box();

// Align positioned boxes with the top of the line box. This is
// a reasonable approximation of an appropriate y position.
if (run->renderer().isOutOfFlowPositioned())
box.setLogicalTop(logicalHeight());
auto& renderer = run->renderer();
if (renderer.isOutOfFlowPositioned())
run->box()->setLogicalTop(logicalHeight());

// Position is used to properly position both replaced elements and
// to update the static normal flow x/y of positioned elements.
if (is<RenderText>(run->renderer()))
downcast<RenderText>(run->renderer()).positionLineBox(downcast<InlineTextBox>(box));
else if (is<RenderBox>(run->renderer()))
downcast<RenderBox>(run->renderer()).positionLineBox(downcast<InlineElementBox>(box));
else if (is<RenderLineBreak>(run->renderer()))
downcast<RenderLineBreak>(run->renderer()).replaceInlineBoxWrapper(downcast<InlineElementBox>(box));
}
// Positioned objects and zero-length text nodes destroy their boxes in
// position(), which unnecessarily dirties the line.
lineBox->markDirty(false);
bool inlineBoxIsRedundant = false;
if (is<RenderText>(renderer)) {
auto& inlineTextBox = downcast<InlineTextBox>(*run->box());
downcast<RenderText>(renderer).positionLineBox(inlineTextBox);
inlineBoxIsRedundant = !inlineTextBox.len();
} else if (is<RenderBox>(renderer)) {
downcast<RenderBox>(renderer).positionLineBox(downcast<InlineElementBox>(*run->box()));
inlineBoxIsRedundant = renderer.isOutOfFlowPositioned();
} else if (is<RenderLineBreak>(renderer))
downcast<RenderLineBreak>(renderer).replaceInlineBoxWrapper(downcast<InlineElementBox>(*run->box()));
// Check if we need to keep this box on the line at all.
if (inlineBoxIsRedundant)
removeInlineBox(*run, *lineBox);
}
}

static inline bool isCollapsibleSpace(UChar character, const RenderText& renderer)
@@ -2157,10 +2157,6 @@ void RenderBox::positionLineBox(InlineElementBox& box)
if (style().hasStaticBlockPosition(box.isHorizontal()))
setChildNeedsLayout(MarkOnlyThis); // Just mark the positioned object as needing layout, so it will update its position properly.
}

// Nuke the box.
box.removeFromParent();
delete &box;
return;
}

@@ -1268,15 +1268,8 @@ std::unique_ptr<InlineTextBox> RenderText::createTextBox()

void RenderText::positionLineBox(InlineTextBox& textBox)
{
// FIXME: should not be needed!!!
if (!textBox.len()) {
// We want the box to be destroyed.
textBox.removeFromParent();
m_lineBoxes.remove(textBox);
delete &textBox;
if (!textBox.len())
return;
}

m_containsReversedText |= !textBox.isLeftToRightDirection();
}

0 comments on commit 5d9d15b

Please sign in to comment.