Commit 7b3ead21 authored by Rune Lillesveen's avatar Rune Lillesveen Committed by Commit Bot

Always rebuild layout tree for shadow root when host is rebuilt.

We tried to do a light-weight search for the first in-flow or text
child of the shadow root when shadow root children didn't need a
rebuild. This was done to make the WhiteAttacher point to the correct
text node when re-attaching the ::before element.

This code did not properly handle slots and insertion points. Also,
supporting display:contents for ::after means we will have to traverse
shadow root children from its last node until we find the first in-flow
to properly attach a space inside an ::after element.

For simplicity, and correctness, walk the shadow root children using
RebuildChildrenLayoutTrees() instead.

Bug: 764686
Change-Id: Icb9f8db7172ea54bd876fd95ca722c2906b4c639
Reviewed-on: https://chromium-review.googlesource.com/667138Reviewed-by: default avatarnainar <nainar@chromium.org>
Reviewed-by: default avatarmeade_UTC10 <meade@chromium.org>
Commit-Queue: Rune Lillesveen <rune@opera.com>
Cr-Commit-Position: refs/heads/master@{#502194}
parent 94f29690
<!DOCTYPE html>
<style>
#host::before { content: "A" }
#host.block::before { display: block }
</style>
<p>You should see a space between A and B below.</p>
<div id="host" class="block"></div>
<script>
var root = host.attachShadow({mode:"open"});
root.innerHTML = '<slot name="fallback"> </slot>B</div>';
host.offsetTop;
host.className = "";
</script>
......@@ -156,45 +156,11 @@ void ShadowRoot::RecalcStyle(StyleRecalcChange change) {
}
void ShadowRoot::RebuildLayoutTree(WhitespaceAttacher& whitespace_attacher) {
if (!NeedsReattachLayoutTree() && !ChildNeedsReattachLayoutTree()) {
SkipRebuildLayoutTree(whitespace_attacher);
return;
}
ClearNeedsReattachLayoutTree();
RebuildChildrenLayoutTrees(whitespace_attacher);
ClearChildNeedsReattachLayoutTree();
}
void ShadowRoot::SkipRebuildLayoutTree(
WhitespaceAttacher& whitespace_attacher) const {
// We call this method when neither this, nor our child nodes are marked
// for re-attachment, but the host has been marked with
// childNeedsReattachLayoutTree. That happens when ::before or ::after needs
// re-attachment. In that case, we update nextTextSibling with the first text
// node sibling not preceeded by any in-flow children to allow for correct
// whitespace re-attachment if the ::before element display changes.
DCHECK(GetDocument().InStyleRecalc());
DCHECK(!GetDocument().ChildNeedsDistributionRecalc());
DCHECK(!NeedsStyleRecalc());
DCHECK(!ChildNeedsStyleRecalc());
DCHECK(!NeedsReattachLayoutTree());
DCHECK(!ChildNeedsReattachLayoutTree());
for (Node* sibling = firstChild(); sibling;
sibling = sibling->nextSibling()) {
if (sibling->IsTextNode()) {
whitespace_attacher.DidVisitText(ToText(sibling));
return;
}
LayoutObject* layout_object = sibling->GetLayoutObject();
if (layout_object && !layout_object->IsFloatingOrOutOfFlowPositioned()) {
whitespace_attacher.DidVisitElement(ToElement(sibling));
return;
}
}
}
void ShadowRoot::AttachLayoutTree(AttachContext& context) {
DocumentFragment::AttachLayoutTree(context);
}
......
......@@ -176,7 +176,6 @@ class CORE_EXPORT ShadowRoot final : public DocumentFragment, public TreeScope {
--child_shadow_root_count_;
}
void InvalidateDescendantInsertionPoints();
void SkipRebuildLayoutTree(WhitespaceAttacher&) const;
Member<ShadowRootRareDataV0> shadow_root_rare_data_v0_;
TraceWrapperMember<StyleSheetList> style_sheet_list_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment