Bug 1816672 - Deal with async root element insertions in layout. r=dshin

Differential Revision: https://phabricator.services.mozilla.com/D171578
This commit is contained in:
Emilio Cobos Álvarez
2023-03-08 13:55:19 +00:00
parent cd18313191
commit 82a78f8e6d
4 changed files with 51 additions and 6 deletions

View File

@@ -2356,6 +2356,7 @@ nsIFrame* nsCSSFrameConstructor::ConstructDocElementFrame(
if (!aDocElement->HasServoData()) {
mPresShell->StyleSet()->StyleNewSubtree(aDocElement);
}
aDocElement->UnsetFlags(NODE_DESCENDANTS_NEED_FRAMES | NODE_NEEDS_FRAME);
// Make sure to call UpdateViewportScrollStylesOverride before
// SetUpDocElementContainingBlock, since it sets up our scrollbar state
@@ -6376,9 +6377,12 @@ nsCSSFrameConstructor::GetRangeInsertionPoint(nsIContent* aStartChild,
nsIContent* aEndChild,
InsertionKind aInsertionKind) {
MOZ_ASSERT(aStartChild);
MOZ_ASSERT(aStartChild->GetParent());
nsIContent* parent = aStartChild->GetParent();
if (!parent) {
IssueSingleInsertNofications(aStartChild, aEndChild, aInsertionKind);
return {};
}
// If the children of the container may be distributed to different insertion
// points, insert them separately and bail out, letting ContentInserted handle
@@ -6868,13 +6872,17 @@ void nsCSSFrameConstructor::ContentRangeInserted(nsIContent* aStartChild,
MOZ_ASSERT(isSingleInsert,
"root node insertion should be a single insertion");
Element* docElement = mDocument->GetRootElement();
if (aStartChild != docElement) {
// Not the root element; just bail out
return;
}
MOZ_ASSERT(!mRootElementFrame, "root element frame already created");
if (aInsertionKind == InsertionKind::Async) {
docElement->SetFlags(NODE_NEEDS_FRAME);
LazilyStyleNewChildRange(docElement, nullptr);
return;
}
// Create frames for the document element and its child elements
if (ConstructDocElementFrame(docElement)) {

View File

@@ -801,6 +801,12 @@ bool ServoStyleSet::StyleDocument(ServoTraversalFlags aFlags) {
return false;
}
Element* rootElement = mDocument->GetRootElement();
if (rootElement && MOZ_UNLIKELY(!rootElement->HasServoData())) {
StyleNewSubtree(rootElement);
return true;
}
PreTraverse(aFlags);
AutoPrepareTraversal guard(this);
const SnapshotTable& snapshots = Snapshots();
@@ -809,9 +815,6 @@ bool ServoStyleSet::StyleDocument(ServoTraversalFlags aFlags) {
// NAC subtree roots.
bool postTraversalRequired = false;
Element* rootElement = mDocument->GetRootElement();
MOZ_ASSERT_IF(rootElement, rootElement->HasServoData());
if (ShouldTraverseInParallel()) {
aFlags |= ServoTraversalFlags::ParallelTraversal;
}

View File

@@ -0,0 +1,34 @@
<!doctype html>
<meta charset="utf-8">
<link rel="help" href="https://drafts.csswg.org/css-transitions/#starting">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1816672">
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
<link rel="author" title="Mozilla" href="https://mozilla.org">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<iframe></iframe>
<script>
let t = async_test("Transitions don't incorrectly start on dynamic document element insertion");
window.onload = t.step_func_done(function() {
let frame = document.querySelector("iframe");
let doc = frame.contentDocument;
doc.open();
doc.write("<!doctype html>");
let root = doc.createElement("html");
root.innerHTML = `
<style>
div {
width: 100px;
height: 100px;
background-color: blue;
transition: margin-left 10s ease;
margin-left: 100px;
}
</style>
<div></div>
`;
doc.appendChild(root);
doc.close();
assert_equals(frame.contentWindow.getComputedStyle(doc.querySelector("div")).marginLeft, "100px", "Transition shouldn't have started");
});
</script>

View File

@@ -2,7 +2,7 @@
<meta charset="utf-8">
<link rel="help" href="https://drafts.csswg.org/css-transitions/#starting">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1461070">
<link rel="author" title="Emilio Cobos Álvarez" href="emilio@crisal.io">
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>