Bug 1924195: Support multiple anchors with the same name. r=layout-reviewers,emilio
Differential Revision: https://phabricator.services.mozilla.com/D247785
This commit is contained in:
committed by
jjalkanen@mozilla.com
parent
93dad181f3
commit
03056ee940
@@ -11508,23 +11508,59 @@ nsIFrame* PresShell::GetAbsoluteContainingBlock(nsIFrame* aFrame) {
|
||||
|
||||
nsIFrame* PresShell::GetAnchorPosAnchor(const nsAtom* aName) const {
|
||||
MOZ_ASSERT(aName);
|
||||
if (auto entry = mAnchorPosAnchors.Lookup(aName)) {
|
||||
return entry.Data();
|
||||
if (const auto& entry = mAnchorPosAnchors.Lookup(aName)) {
|
||||
return entry->SafeLastElement(nullptr);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void PresShell::AddAnchorPosAnchor(const nsAtom* aName, nsIFrame* aFrame) {
|
||||
MOZ_ASSERT(aName);
|
||||
mAnchorPosAnchors.InsertOrUpdate(aName, aFrame);
|
||||
|
||||
auto& entry = mAnchorPosAnchors.LookupOrInsertWith(
|
||||
aName, []() { return nsTArray<nsIFrame*>(); });
|
||||
|
||||
if (entry.IsEmpty()) {
|
||||
entry.AppendElement(aFrame);
|
||||
return;
|
||||
}
|
||||
|
||||
struct FrameTreeComparator {
|
||||
nsIFrame* mFrame;
|
||||
|
||||
constexpr int32_t operator()(nsIFrame* aOther) const {
|
||||
return nsLayoutUtils::CompareTreePosition(aOther, mFrame, nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
FrameTreeComparator cmp{aFrame};
|
||||
|
||||
size_t matchOrInsertionIdx = entry.Length();
|
||||
// If the same element is already in the array,
|
||||
// someone forgot to call RemoveAnchorPosAnchor.
|
||||
if (BinarySearchIf(entry, 0, entry.Length(), cmp, &matchOrInsertionIdx)) {
|
||||
MOZ_ASSERT_UNREACHABLE("Anchor added already");
|
||||
return;
|
||||
}
|
||||
|
||||
*entry.InsertElementAt(matchOrInsertionIdx) = aFrame;
|
||||
}
|
||||
|
||||
void PresShell::RemoveAnchorPosAnchor(const nsAtom* aName, nsIFrame* aFrame) {
|
||||
MOZ_ASSERT(aName);
|
||||
if (auto entry = mAnchorPosAnchors.Lookup(aName)) {
|
||||
if (entry.Data() == aFrame) {
|
||||
entry.Remove();
|
||||
}
|
||||
auto entry = mAnchorPosAnchors.Lookup(aName);
|
||||
if (!entry) {
|
||||
return; // Nothing to remove.
|
||||
}
|
||||
|
||||
auto& anchorArray = entry.Data();
|
||||
MOZ_ASSERT(!anchorArray.IsEmpty());
|
||||
MOZ_ASSERT(anchorArray.Contains(aFrame));
|
||||
|
||||
anchorArray.RemoveElement(aFrame);
|
||||
if (anchorArray.IsEmpty()) {
|
||||
entry.Remove();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3029,7 +3029,7 @@ class PresShell final : public nsStubDocumentObserver,
|
||||
// A hash table of heap allocated weak frames.
|
||||
nsTHashSet<WeakFrame*> mWeakFrames;
|
||||
|
||||
nsTHashMap<RefPtr<const nsAtom>, nsIFrame*> mAnchorPosAnchors;
|
||||
nsTHashMap<RefPtr<const nsAtom>, nsTArray<nsIFrame*>> mAnchorPosAnchors;
|
||||
|
||||
// Reflow roots that need to be reflowed.
|
||||
DepthOrderedFrameList mDirtyRoots;
|
||||
|
||||
Reference in New Issue
Block a user