Bug 1776056 - Switch to the tab an animation is running and make sure the animation...
[gecko.git] / layout / base / ContainStyleScopeManager.cpp
blobd3388a010bdd05cd16f55d6132e5bb7258079c06
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "ContainStyleScopeManager.h"
9 #include "mozilla/ComputedStyle.h"
10 #include "mozilla/ServoStyleSet.h"
11 #include "CounterStyleManager.h"
12 #include "nsCounterManager.h"
13 #include "nsIContent.h"
14 #include "nsIContentInlines.h"
15 #include "nsIFrame.h"
16 #include "nsLayoutUtils.h"
17 #include "nsQuoteList.h"
19 namespace mozilla {
21 nsGenConNode* ContainStyleScope::GetPrecedingElementInGenConList(
22 nsGenConList* aList) {
23 auto IsAfter = [this](nsGenConNode* aNode) {
24 return nsLayoutUtils::CompareTreePosition(
25 mContent, aNode->mPseudoFrame->GetContent()) > 0;
27 return aList->BinarySearch(IsAfter);
30 void ContainStyleScope::RecalcAllCounters() {
31 GetCounterManager().RecalcAll();
32 for (auto* child : mChildren) {
33 child->RecalcAllCounters();
37 void ContainStyleScope::RecalcAllQuotes() {
38 GetQuoteList().RecalcAll();
39 for (auto* child : mChildren) {
40 child->RecalcAllQuotes();
44 ContainStyleScope& ContainStyleScopeManager::GetOrCreateScopeForContent(
45 nsIContent* aContent) {
46 for (; aContent; aContent = aContent->GetFlattenedTreeParent()) {
47 auto* element = dom::Element::FromNode(*aContent);
48 if (!element) {
49 continue;
52 // Do not allow elements which have `display: contents` to create style
53 // boundaries. See https://github.com/w3c/csswg-drafts/issues/7392.
54 if (element->IsDisplayContents()) {
55 continue;
58 const auto* style = Servo_Element_GetMaybeOutOfDateStyle(element);
59 if (!style) {
60 continue;
63 if (!style->SelfOrAncestorHasContainStyle()) {
64 return GetRootScope();
67 if (!style->StyleDisplay()->IsContainStyle()) {
68 continue;
71 if (auto* scope = mScopes.Get(aContent)) {
72 return *scope;
75 auto& parentScope =
76 GetOrCreateScopeForContent(aContent->GetFlattenedTreeParent());
77 return *mScopes.InsertOrUpdate(
78 aContent, MakeUnique<ContainStyleScope>(this, &parentScope, aContent));
81 return GetRootScope();
84 ContainStyleScope& ContainStyleScopeManager::GetScopeForContent(
85 nsIContent* aContent) {
86 MOZ_ASSERT(aContent);
88 if (auto* element = dom::Element::FromNode(*aContent)) {
89 if (const auto* style = Servo_Element_GetMaybeOutOfDateStyle(element)) {
90 if (!style->SelfOrAncestorHasContainStyle()) {
91 return GetRootScope();
96 for (; aContent; aContent = aContent->GetFlattenedTreeParent()) {
97 if (auto* scope = mScopes.Get(aContent)) {
98 return *scope;
102 return GetRootScope();
105 void ContainStyleScopeManager::Clear() {
106 GetRootScope().GetQuoteList().Clear();
107 GetRootScope().GetCounterManager().Clear();
109 DestroyScope(&GetRootScope());
110 MOZ_DIAGNOSTIC_ASSERT(mScopes.IsEmpty(),
111 "Destroying the root scope should destroy all scopes.");
114 void ContainStyleScopeManager::DestroyScopesFor(nsIFrame* aFrame) {
115 if (auto* scope = mScopes.Get(aFrame->GetContent())) {
116 DestroyScope(scope);
120 void ContainStyleScopeManager::DestroyScope(ContainStyleScope* aScope) {
121 // Deleting a scope modifies the array of children in its parent, so we don't
122 // use an iterator here.
123 while (!aScope->GetChildren().IsEmpty()) {
124 DestroyScope(aScope->GetChildren().ElementAt(0));
126 mScopes.Remove(aScope->GetContent());
129 bool ContainStyleScopeManager::DestroyCounterNodesFor(nsIFrame* aFrame) {
130 bool result = false;
131 for (auto* scope = &GetScopeForContent(aFrame->GetContent()); scope;
132 scope = scope->GetParent()) {
133 result |= scope->GetCounterManager().DestroyNodesFor(aFrame);
135 return result;
138 bool ContainStyleScopeManager::AddCounterChanges(nsIFrame* aNewFrame) {
139 return GetOrCreateScopeForContent(
140 aNewFrame->GetContent()->GetFlattenedTreeParent())
141 .GetCounterManager()
142 .AddCounterChanges(aNewFrame);
145 nsCounterList* ContainStyleScopeManager::GetOrCreateCounterList(
146 dom::Element& aElement, nsAtom* aCounterName) {
147 return GetOrCreateScopeForContent(&aElement)
148 .GetCounterManager()
149 .GetOrCreateCounterList(aCounterName);
152 bool ContainStyleScopeManager::CounterDirty(nsAtom* aCounterName) {
153 return mDirtyCounters.Contains(aCounterName);
156 void ContainStyleScopeManager::SetCounterDirty(nsAtom* aCounterName) {
157 mDirtyCounters.Insert(aCounterName);
160 void ContainStyleScopeManager::RecalcAllCounters() {
161 GetRootScope().RecalcAllCounters();
162 mDirtyCounters.Clear();
165 #if defined(DEBUG) || defined(MOZ_LAYOUT_DEBUGGER)
166 void ContainStyleScopeManager::DumpCounters() {
167 GetRootScope().GetCounterManager().Dump();
168 for (auto& entry : mScopes) {
169 entry.GetWeak()->GetCounterManager().Dump();
172 #endif
174 #ifdef ACCESSIBILITY
175 static bool GetFirstCounterValueForScopeAndFrame(ContainStyleScope* aScope,
176 nsIFrame* aFrame,
177 CounterValue& aOrdinal) {
178 if (aScope->GetCounterManager().GetFirstCounterValueForFrame(aFrame,
179 aOrdinal)) {
180 return true;
182 for (auto* child : aScope->GetChildren()) {
183 if (GetFirstCounterValueForScopeAndFrame(child, aFrame, aOrdinal)) {
184 return true;
188 return false;
191 void ContainStyleScopeManager::GetSpokenCounterText(nsIFrame* aFrame,
192 nsAString& aText) {
193 CounterValue ordinal = 1;
194 GetFirstCounterValueForScopeAndFrame(&GetRootScope(), aFrame, ordinal);
196 CounterStyle* counterStyle =
197 aFrame->PresContext()->CounterStyleManager()->ResolveCounterStyle(
198 aFrame->StyleList()->mCounterStyle);
199 nsAutoString text;
200 bool isBullet;
201 counterStyle->GetSpokenCounterText(ordinal, aFrame->GetWritingMode(), text,
202 isBullet);
203 if (isBullet) {
204 aText = text;
205 if (!counterStyle->IsNone()) {
206 aText.Append(' ');
208 } else {
209 counterStyle->GetPrefix(aText);
210 aText += text;
211 nsAutoString suffix;
212 counterStyle->GetSuffix(suffix);
213 aText += suffix;
216 #endif
218 void ContainStyleScopeManager::SetAllCountersDirty() {
219 GetRootScope().GetCounterManager().SetAllDirty();
220 for (auto& entry : mScopes) {
221 entry.GetWeak()->GetCounterManager().SetAllDirty();
225 bool ContainStyleScopeManager::DestroyQuoteNodesFor(nsIFrame* aFrame) {
226 bool result = false;
227 for (auto* scope = &GetScopeForContent(aFrame->GetContent()); scope;
228 scope = scope->GetParent()) {
229 result |= scope->GetQuoteList().DestroyNodesFor(aFrame);
231 return result;
234 nsQuoteList* ContainStyleScopeManager::QuoteListFor(dom::Element& aElement) {
235 return &GetOrCreateScopeForContent(&aElement).GetQuoteList();
238 void ContainStyleScopeManager::RecalcAllQuotes() {
239 GetRootScope().RecalcAllQuotes();
242 } // namespace mozilla