commit 28d9e40f24df6d3dfa65f748f4a293c52b3fd286
parent 0bf0548a9c74d9ab35f8961b603659771491eef6
Author: Emilio Cobos Álvarez <emilio@crisal.io>
Date: Fri, 19 Dec 2025 19:53:22 +0000
Bug 2006998 - Avoid creating ::backdrop pseudo-elements for leaf frames. r=layout-reviewers,firefox-style-system-reviewers,dshin
This prevents special frames from having unexpected children. This
technically avoids having ::backdrop on things like a full-screen
<input>, but that seems unlikely and consistent with
::before / ::after / ::marker.
Differential Revision: https://phabricator.services.mozilla.com/D277188
Diffstat:
3 files changed, 22 insertions(+), 15 deletions(-)
diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp
@@ -9655,25 +9655,24 @@ void nsCSSFrameConstructor::ProcessChildren(
AddFCItemsForAnonymousContent(aState, aFrame, anonymousItems,
itemsToConstruct, pageNameTracker);
- // Generated content content should have the same style parent as normal kids.
- //
- // Note that we don't use this style for looking up things like special
- // block styles because in some cases involving table pseudo-frames it has
- // nothing to do with the parent frame's desired behavior.
- auto* styleParentFrame =
- nsIFrame::CorrectStyleParentFrame(aFrame, PseudoStyleType::NotPseudo);
- ComputedStyle* parentStyle = styleParentFrame->Style();
- if (parentStyle->StyleDisplay()->mTopLayer == StyleTopLayer::Auto &&
- !aContent->IsInNativeAnonymousSubtree()) {
- CreateGeneratedContentItem(aState, aFrame, *aContent->AsElement(),
- *parentStyle, PseudoStyleType::backdrop,
- itemsToConstruct);
- }
-
nsBlockFrame* listItem = nullptr;
bool isOutsideMarker = false;
if (!aPossiblyLeafFrame->IsLeaf()) {
+ // Generated content should have the same style parent as normal kids.
+ //
+ // Note that we don't use this style for looking up things like special
+ // block styles because in some cases involving table pseudo-frames it has
+ // nothing to do with the parent frame's desired behavior.
+ auto* styleParentFrame =
+ nsIFrame::CorrectStyleParentFrame(aFrame, PseudoStyleType::NotPseudo);
+ ComputedStyle* parentStyle = styleParentFrame->Style();
if (aCanHaveGeneratedContent) {
+ if (parentStyle->StyleDisplay()->mTopLayer == StyleTopLayer::Auto &&
+ !aContent->IsInNativeAnonymousSubtree()) {
+ CreateGeneratedContentItem(aState, aFrame, *aContent->AsElement(),
+ *parentStyle, PseudoStyleType::backdrop,
+ itemsToConstruct);
+ }
if (parentStyle->StyleDisplay()->IsListItem() &&
(listItem = do_QueryFrame(aFrame)) &&
!styleParentFrame->IsFieldSetFrame()) {
diff --git a/layout/style/RestyleManager.cpp b/layout/style/RestyleManager.cpp
@@ -2770,6 +2770,9 @@ static ServoPostTraversalFlags SendA11yNotifications(
static bool NeedsToReframeForConditionallyCreatedPseudoElement(
Element* aElement, ComputedStyle* aNewStyle, nsIFrame* aStyleFrame,
ServoRestyleState& aRestyleState) {
+ if (MOZ_UNLIKELY(aStyleFrame->IsLeaf())) {
+ return false;
+ }
const auto& disp = *aStyleFrame->StyleDisplay();
if (disp.IsListItem() && aStyleFrame->IsBlockFrameOrSubclass() &&
!nsLayoutUtils::GetMarkerPseudo(aElement)) {
diff --git a/testing/web-platform/tests/css/selectors/backdrop-input-crash.html b/testing/web-platform/tests/css/selectors/backdrop-input-crash.html
@@ -0,0 +1,5 @@
+<input popover="" id="a" style="direction: rtl"/>
+<script>
+a.showPopover();
+</script>
+