mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 15:52:07 +00:00
Bug 1461749: Fix slow path for finding the next sibling frame for appending in presence of Shadow DOM. r=mats
In this case we have a shadow hoot with display: contents, with no children. Those children wouldn't be flattened tree children of the shadow host. Instead of using the last light dom child and seek to it, use FlattenedChildIterator's reverse iteration. MozReview-Commit-ID: 18XL5Ong7ww --HG-- extra : rebase_source : 2d34bd5b1fdd509a069ffa5052a7b7b3302be24c
This commit is contained in:
parent
10167dbcac
commit
fb4762b5e6
19
layout/base/crashtests/1461749.html
Normal file
19
layout/base/crashtests/1461749.html
Normal file
@ -0,0 +1,19 @@
|
||||
<style>
|
||||
:last-of-type {
|
||||
display: contents;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
function start() {
|
||||
o1 = document.createElement('footer')
|
||||
o2 = document.createElement('t')
|
||||
document.documentElement.appendChild(o1)
|
||||
document.documentElement.appendChild(o2)
|
||||
o3 = o1.attachShadow({
|
||||
mode: "open"
|
||||
})
|
||||
o2.getClientRects()
|
||||
o3.innerHTML = ">"
|
||||
}
|
||||
window.addEventListener('load', start)
|
||||
</script>
|
@ -534,3 +534,4 @@ load 1453196.html
|
||||
pref(dom.webcomponents.shadowdom.enabled,true) load 1414303.html
|
||||
load 1461812.html
|
||||
load 1462412.html
|
||||
pref(dom.webcomponents.shadowdom.enabled,true) load 1461749.html
|
||||
|
@ -7050,6 +7050,26 @@ nsCSSFrameConstructor::StyleNewChildRange(nsIContent* aStartChild,
|
||||
}
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsCSSFrameConstructor::FindNextSiblingForAppend(const InsertionPoint& aInsertion)
|
||||
{
|
||||
auto SlowPath = [&]() -> nsIFrame* {
|
||||
FlattenedChildIterator iter(aInsertion.mContainer,
|
||||
/* aStartAtBeginning = */ false);
|
||||
iter.GetPreviousChild(); // Prime the iterator.
|
||||
StyleDisplay unused = UNSET_DISPLAY;
|
||||
return FindNextSibling(iter, unused);
|
||||
};
|
||||
|
||||
if (!IsDisplayContents(aInsertion.mContainer) &&
|
||||
!nsLayoutUtils::GetAfterFrame(aInsertion.mContainer)) {
|
||||
MOZ_ASSERT(!SlowPath());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return SlowPath();
|
||||
}
|
||||
|
||||
void
|
||||
nsCSSFrameConstructor::ContentAppended(nsIContent* aFirstNewContent,
|
||||
InsertionKind aInsertionKind)
|
||||
@ -7144,17 +7164,7 @@ nsCSSFrameConstructor::ContentAppended(nsIContent* aFirstNewContent,
|
||||
MOZ_ASSERT(!parentFrame->IsFieldSetFrame() && !parentFrame->IsDetailsFrame(),
|
||||
"Parent frame should not be fieldset or details!");
|
||||
|
||||
// Deal with possible :after generated content on the parent, or display:
|
||||
// contents.
|
||||
nsIFrame* nextSibling = nullptr;
|
||||
if (IsDisplayContents(insertion.mContainer) ||
|
||||
nsLayoutUtils::GetAfterFrame(insertion.mContainer)) {
|
||||
FlattenedChildIterator iter(insertion.mContainer);
|
||||
iter.Seek(insertion.mContainer->GetLastChild());
|
||||
StyleDisplay unused = UNSET_DISPLAY;
|
||||
nextSibling = FindNextSibling(iter, unused);
|
||||
}
|
||||
|
||||
nsIFrame* nextSibling = FindNextSiblingForAppend(insertion);
|
||||
if (nextSibling) {
|
||||
parentFrame = nextSibling->GetParent()->GetContentInsertionFrame();
|
||||
} else {
|
||||
@ -7183,10 +7193,7 @@ nsCSSFrameConstructor::ContentAppended(nsIContent* aFirstNewContent,
|
||||
//
|
||||
// FIXME(emilio): This kinda sucks! :(
|
||||
if (nextSibling && !wf) {
|
||||
FlattenedChildIterator iter(insertion.mContainer);
|
||||
iter.Seek(insertion.mContainer->GetLastChild());
|
||||
StyleDisplay unused = UNSET_DISPLAY;
|
||||
nextSibling = FindNextSibling(iter, unused);
|
||||
nextSibling = FindNextSiblingForAppend(insertion);
|
||||
if (nextSibling) {
|
||||
parentFrame = nextSibling->GetParent()->GetContentInsertionFrame();
|
||||
containingBlock = GetFloatContainingBlock(parentFrame);
|
||||
|
@ -2038,6 +2038,14 @@ private:
|
||||
void CheckForFirstLineInsertion(nsIFrame* aParentFrame,
|
||||
nsFrameItems& aFrameItems);
|
||||
|
||||
/**
|
||||
* Find the next frame for appending to a given insertion point.
|
||||
*
|
||||
* We're appending, so this is almost always null, except for a few edge
|
||||
* cases.
|
||||
*/
|
||||
nsIFrame* FindNextSiblingForAppend(const InsertionPoint&);
|
||||
|
||||
// The direction in which we should look for siblings.
|
||||
enum class SiblingDirection
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user