diff options
Diffstat (limited to 'layout/base/ContainStyleScopeManager.h')
-rw-r--r-- | layout/base/ContainStyleScopeManager.h | 139 |
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_ */ |