Skip to content
Permalink
Browse files
[RenderTreeBuilder] Remove RenderElement::destroyLeftoverChildren.
https://bugs.webkit.org/show_bug.cgi?id=182518
<rdar://problem/37256035>

Reviewed by Antti Koivisto.

Remove leftover children before we call takeChild() on the parent (as opposed to when
we finally call destroy() on the parent).
This patch also explicitly destroys the top level pagination renderers.

Covered by existing tests.

* rendering/RenderElement.cpp:
(WebCore::RenderElement::removeAndDestroyChild):
(WebCore::RenderElement::destroyLeftoverChildren): Deleted.
* rendering/RenderElement.h:
* rendering/RenderObject.cpp:
(WebCore::RenderObject::destroy):
* rendering/updating/RenderTreeUpdater.cpp:
(WebCore::RenderTreeUpdater::tearDownRenderers):
(WebCore::RenderTreeUpdater::tearDownLeftoverPaginationRenderersIfNeeded):
* rendering/updating/RenderTreeUpdater.h:


Canonical link: https://commits.webkit.org/198376@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@228238 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
alanbujtas committed Feb 7, 2018
1 parent 86ad0f3 commit 050354311b592bf9d06b369194ec0461142910b6
@@ -1,3 +1,28 @@
2018-02-07 Zalan Bujtas <zalan@apple.com>

[RenderTreeBuilder] Remove RenderElement::destroyLeftoverChildren.
https://bugs.webkit.org/show_bug.cgi?id=182518
<rdar://problem/37256035>

Reviewed by Antti Koivisto.

Remove leftover children before we call takeChild() on the parent (as opposed to when
we finally call destroy() on the parent).
This patch also explicitly destroys the top level pagination renderers.

Covered by existing tests.

* rendering/RenderElement.cpp:
(WebCore::RenderElement::removeAndDestroyChild):
(WebCore::RenderElement::destroyLeftoverChildren): Deleted.
* rendering/RenderElement.h:
* rendering/RenderObject.cpp:
(WebCore::RenderObject::destroy):
* rendering/updating/RenderTreeUpdater.cpp:
(WebCore::RenderTreeUpdater::tearDownRenderers):
(WebCore::RenderTreeUpdater::tearDownLeftoverPaginationRenderersIfNeeded):
* rendering/updating/RenderTreeUpdater.h:

2018-02-07 Daniel Bates <dabates@apple.com>

Log error when authentication challenge is blocked due to an insecure request
@@ -136,6 +136,7 @@ RenderElement::RenderElement(Document& document, RenderStyle&& style, BaseTypeFl
RenderElement::~RenderElement()
{
// Do not add any code here. Add it to willBeDestroyed() instead.
ASSERT(!m_firstChild);
}

RenderPtr<RenderElement> RenderElement::createFor(Element& element, RenderStyle&& style, RendererCreationType creationType)
@@ -487,16 +488,16 @@ RenderPtr<RenderObject> RenderElement::takeChild(RenderTreeBuilder&, RenderObjec

void RenderElement::removeAndDestroyChild(RenderTreeBuilder& builder, RenderObject& oldChild)
{
auto toDestroy = takeChild(builder, oldChild);
}

void RenderElement::destroyLeftoverChildren()
{
while (m_firstChild) {
if (auto* node = m_firstChild->node())
node->setRenderer(nullptr);
removeAndDestroyChild(*RenderTreeBuilder::current(), *m_firstChild);
if (is<RenderElement>(oldChild)) {
auto& child = downcast<RenderElement>(oldChild);
while (child.firstChild()) {
auto& firstChild = *child.firstChild();
if (auto* node = firstChild.node())
node->setRenderer(nullptr);
child.removeAndDestroyChild(builder, firstChild);
}
}
auto toDestroy = takeChild(builder, oldChild);
}

RenderObject* RenderElement::attachRendererInternal(RenderPtr<RenderObject> child, RenderObject* beforeChild)
@@ -228,7 +228,6 @@ class RenderElement : public RenderObject {
bool isFirstLetter() const { return m_isFirstLetter; }
void setIsFirstLetter() { m_isFirstLetter = true; }

void destroyLeftoverChildren();
RenderObject* attachRendererInternal(RenderPtr<RenderObject> child, RenderObject* beforeChild);
RenderPtr<RenderObject> detachRendererInternal(RenderObject&);

@@ -1477,9 +1477,6 @@ void RenderObject::destroy()
RELEASE_ASSERT(!m_previous);
RELEASE_ASSERT(!m_bitfields.beingDestroyed());

if (is<RenderElement>(*this))
downcast<RenderElement>(*this).destroyLeftoverChildren();

m_bitfields.setBeingDestroyed(true);

#if PLATFORM(IOS)
@@ -47,6 +47,7 @@
#include "RenderMultiColumnSet.h"
#include "RenderMultiColumnSpannerPlaceholder.h"
#include "RenderQuote.h"
#include "RenderTreeBuilder.h"
#include "RenderWidget.h"
#include "ScrollbarTheme.h"
#include "Settings.h"
@@ -613,6 +614,12 @@ bool RenderView::isScrollableOrRubberbandableBox() const
void RenderView::willBeDestroyed()
{
RenderBlockFlow::willBeDestroyed();
// FIXME: This is a workaround for leftover content (see webkit.org/b/182547).
if (firstChild()) {
RenderTreeBuilder builder(*this);
while (firstChild())
removeAndDestroyChild(builder, *firstChild());
}

ASSERT_WITH_MESSAGE(m_rendererCount == 1, "All other renderers in this render tree should have been destroyed");
}
@@ -579,6 +579,8 @@ void RenderTreeUpdater::tearDownRenderers(Element& root, TeardownType teardownTy
}

pop(0);

tearDownLeftoverPaginationRenderersIfNeeded(root);
}

void RenderTreeUpdater::tearDownTextRenderer(Text& text)
@@ -590,6 +592,18 @@ void RenderTreeUpdater::tearDownTextRenderer(Text& text)
text.setRenderer(nullptr);
}

void RenderTreeUpdater::tearDownLeftoverPaginationRenderersIfNeeded(Element& root)
{
if (&root != root.document().documentElement())
return;
for (auto* child = root.document().renderView()->firstChild(); child;) {
auto* nextSibling = child->nextSibling();
if (is<RenderMultiColumnFlow>(*child) || is<RenderMultiColumnSet>(*child))
RenderTreeBuilder::current()->removeFromParentAndDestroyCleaningUpAnonymousWrappers(*child);
child = nextSibling;
}
}

void RenderTreeUpdater::tearDownLeftoverShadowHostChildren(Element& host)
{
for (auto* hostChild = host.firstChild(); hostChild; hostChild = hostChild->nextSibling()) {
@@ -89,6 +89,7 @@ class RenderTreeUpdater {
static void tearDownRenderers(Element&, TeardownType);
static void tearDownTextRenderer(Text&);
static void tearDownLeftoverShadowHostChildren(Element&);
static void tearDownLeftoverPaginationRenderersIfNeeded(Element&);

RenderView& renderView();

0 comments on commit 0503543

Please sign in to comment.