summaryrefslogtreecommitdiffstats
path: root/layout/base/ContainStyleScopeManager.h
diff options
context:
space:
mode:
Diffstat (limited to 'layout/base/ContainStyleScopeManager.h')
-rw-r--r--layout/base/ContainStyleScopeManager.h139
1 files changed, 139 insertions, 0 deletions
diff --git a/layout/base/ContainStyleScopeManager.h b/layout/base/ContainStyleScopeManager.h
new file mode 100644
index 0000000000..890344c93e
--- /dev/null
+++ b/layout/base/ContainStyleScopeManager.h
@@ -0,0 +1,139 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef ContainStyleScopeManager_h_
+#define ContainStyleScopeManager_h_
+
+#include "nsClassHashtable.h"
+#include "nsTHashSet.h"
+#include "nsQuoteList.h"
+#include "nsCounterManager.h"
+#include <memory>
+
+class nsIContent;
+class nsAtom;
+
+namespace mozilla {
+
+namespace dom {
+class Element;
+}
+
+class ContainStyleScopeManager;
+
+/* Implementation of a self-contained `contain: style` scope which manages its
+ * own counters and quotes. Since the `counters()` function has read access to
+ * other `contain: style` scopes, USE counter nodes may link across `contain:
+ * style` scopes. */
+class ContainStyleScope final {
+ public:
+ ContainStyleScope(ContainStyleScopeManager* aManager,
+ ContainStyleScope* aParent, nsIContent* aContent)
+ : mQuoteList(this),
+ mCounterManager(this),
+ mScopeManager(aManager),
+ mParent(aParent),
+ mContent(aContent) {
+ MOZ_ASSERT(aManager);
+ if (mParent) {
+ mParent->AddChild(this);
+ }
+ }
+
+ ~ContainStyleScope() {
+ if (mParent) {
+ mParent->RemoveChild(this);
+ }
+ }
+
+ nsQuoteList& GetQuoteList() { return mQuoteList; }
+ nsCounterManager& GetCounterManager() { return mCounterManager; }
+ ContainStyleScopeManager& GetScopeManager() { return *mScopeManager; }
+ ContainStyleScope* GetParent() { return mParent; }
+ nsIContent* GetContent() { return mContent; }
+
+ void AddChild(ContainStyleScope* aScope) { mChildren.AppendElement(aScope); }
+ void RemoveChild(ContainStyleScope* aScope) {
+ mChildren.RemoveElement(aScope);
+ }
+ const nsTArray<ContainStyleScope*>& GetChildren() const { return mChildren; }
+
+ void RecalcAllCounters();
+ void RecalcAllQuotes();
+
+ // Find the element in the given nsGenConList that directly precedes
+ // the mContent node of this ContainStyleScope in the flat tree. Can
+ // return null if no element in the list precedes the content.
+ nsGenConNode* GetPrecedingElementInGenConList(nsGenConList*);
+
+ private:
+ nsQuoteList mQuoteList;
+ nsCounterManager mCounterManager;
+
+ // We are owned by the |mScopeManager|, so this is guaranteed to be a live
+ // pointer as long as we are alive as well.
+ ContainStyleScopeManager* mScopeManager;
+
+ // Although parent and child relationships are represented as raw pointers
+ // here, |mScopeManager| is responsible for managing creation and deletion of
+ // all these data structures and also that it happens in the correct order.
+ ContainStyleScope* mParent;
+ nsTArray<ContainStyleScope*> mChildren;
+
+ // |mContent| is guaranteed to outlive this scope because mScopeManager will
+ // delete the scope when the corresponding frame for |mContent| is destroyed.
+ nsIContent* mContent;
+};
+
+/* Management of the tree `contain: style` scopes. This class ensures that
+ * recalculation is done top-down, so that nodes that rely on other nodes in
+ * ancestor `contain: style` scopes are calculated properly. */
+class ContainStyleScopeManager {
+ public:
+ ContainStyleScopeManager() : mRootScope(this, nullptr, nullptr) {}
+ ContainStyleScope& GetRootScope() { return mRootScope; }
+ ContainStyleScope& GetOrCreateScopeForContent(nsIContent*);
+ ContainStyleScope& GetScopeForContent(nsIContent*);
+
+ void Clear();
+
+ // If this frame creates a `contain: style` scope, destroy that scope and
+ // all of its child scopes.
+ void DestroyScopesFor(nsIFrame*);
+
+ // Destroy this scope and all its children starting from the leaf nodes.
+ void DestroyScope(ContainStyleScope*);
+
+ bool DestroyCounterNodesFor(nsIFrame*);
+ bool AddCounterChanges(nsIFrame* aNewFrame);
+ nsCounterList* GetOrCreateCounterList(dom::Element&, nsAtom* aCounterName);
+
+ bool CounterDirty(nsAtom* aCounterName);
+ void SetCounterDirty(nsAtom* aCounterName);
+ void RecalcAllCounters();
+ void SetAllCountersDirty();
+
+ bool DestroyQuoteNodesFor(nsIFrame*);
+ nsQuoteList* QuoteListFor(dom::Element&);
+ void RecalcAllQuotes();
+
+#if defined(DEBUG) || defined(MOZ_LAYOUT_DEBUGGER)
+ void DumpCounters();
+#endif
+
+#ifdef ACCESSIBILITY
+ void GetSpokenCounterText(nsIFrame* aFrame, nsAString& aText);
+#endif
+
+ private:
+ ContainStyleScope mRootScope;
+ nsClassHashtable<nsPtrHashKey<nsIContent>, ContainStyleScope> mScopes;
+ nsTHashSet<RefPtr<nsAtom>> mDirtyCounters;
+};
+
+} // namespace mozilla
+
+#endif /* ContainStyleScopeManager_h_ */