1355787 - nsIdentifierMapEntry should let one...

This commit is contained in:
Fedor 2020-09-17 07:18:58 +03:00
parent c2ac69a62d
commit 29dd0b47ce
4 changed files with 76 additions and 22 deletions

View File

@ -319,8 +319,7 @@ ShadowRoot::GetElementsByTagNameNS(const nsAString& aNamespaceURI,
void void
ShadowRoot::AddToIdTable(Element* aElement, nsIAtom* aId) ShadowRoot::AddToIdTable(Element* aElement, nsIAtom* aId)
{ {
nsIdentifierMapEntry *entry = nsIdentifierMapEntry* entry = mIdentifierMap.PutEntry(aId);
mIdentifierMap.PutEntry(nsDependentAtomString(aId));
if (entry) { if (entry) {
entry->AddIdElement(aElement); entry->AddIdElement(aElement);
} }
@ -329,8 +328,7 @@ ShadowRoot::AddToIdTable(Element* aElement, nsIAtom* aId)
void void
ShadowRoot::RemoveFromIdTable(Element* aElement, nsIAtom* aId) ShadowRoot::RemoveFromIdTable(Element* aElement, nsIAtom* aId)
{ {
nsIdentifierMapEntry *entry = nsIdentifierMapEntry* entry = mIdentifierMap.GetEntry(aId);
mIdentifierMap.GetEntry(nsDependentAtomString(aId));
if (entry) { if (entry) {
entry->RemoveIdElement(aElement); entry->RemoveIdElement(aElement);
if (entry->IsEmpty()) { if (entry->IsEmpty()) {

View File

@ -537,7 +537,7 @@ nsIdentifierMapEntry::HasIdElementExposedAsHTMLDocumentProperty()
size_t size_t
nsIdentifierMapEntry::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const nsIdentifierMapEntry::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
{ {
return nsStringHashKey::SizeOfExcludingThis(aMallocSizeOf); return mKey.mString.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
} }
// Helper structs for the content->subdoc map // Helper structs for the content->subdoc map
@ -2704,8 +2704,7 @@ nsDocument::AddToNameTable(Element *aElement, nsIAtom* aName)
"Only put elements that need to be exposed as document['name'] in " "Only put elements that need to be exposed as document['name'] in "
"the named table."); "the named table.");
nsIdentifierMapEntry *entry = nsIdentifierMapEntry* entry = mIdentifierMap.PutEntry(aName);
mIdentifierMap.PutEntry(nsDependentAtomString(aName));
// Null for out-of-memory // Null for out-of-memory
if (entry) { if (entry) {
@ -2724,8 +2723,7 @@ nsDocument::RemoveFromNameTable(Element *aElement, nsIAtom* aName)
if (mIdentifierMap.Count() == 0) if (mIdentifierMap.Count() == 0)
return; return;
nsIdentifierMapEntry *entry = nsIdentifierMapEntry* entry = mIdentifierMap.GetEntry(aName);
mIdentifierMap.GetEntry(nsDependentAtomString(aName));
if (!entry) // Could be false if the element was anonymous, hence never added if (!entry) // Could be false if the element was anonymous, hence never added
return; return;
@ -2739,8 +2737,7 @@ nsDocument::RemoveFromNameTable(Element *aElement, nsIAtom* aName)
void void
nsDocument::AddToIdTable(Element *aElement, nsIAtom* aId) nsDocument::AddToIdTable(Element *aElement, nsIAtom* aId)
{ {
nsIdentifierMapEntry *entry = nsIdentifierMapEntry* entry = mIdentifierMap.PutEntry(aId);
mIdentifierMap.PutEntry(nsDependentAtomString(aId));
if (entry) { /* True except on OOM */ if (entry) { /* True except on OOM */
if (nsGenericHTMLElement::ShouldExposeIdAsHTMLDocumentProperty(aElement) && if (nsGenericHTMLElement::ShouldExposeIdAsHTMLDocumentProperty(aElement) &&
@ -2762,8 +2759,7 @@ nsDocument::RemoveFromIdTable(Element *aElement, nsIAtom* aId)
return; return;
} }
nsIdentifierMapEntry *entry = nsIdentifierMapEntry* entry = mIdentifierMap.GetEntry(aId);
mIdentifierMap.GetEntry(nsDependentAtomString(aId));
if (!entry) // Can be null for XML elements with changing ids. if (!entry) // Can be null for XML elements with changing ids.
return; return;
@ -4783,7 +4779,7 @@ nsDocument::AddIDTargetObserver(nsIAtom* aID, IDTargetObserver aObserver,
if (!CheckGetElementByIdArg(id)) if (!CheckGetElementByIdArg(id))
return nullptr; return nullptr;
nsIdentifierMapEntry *entry = mIdentifierMap.PutEntry(id); nsIdentifierMapEntry* entry = mIdentifierMap.PutEntry(aID);
NS_ENSURE_TRUE(entry, nullptr); NS_ENSURE_TRUE(entry, nullptr);
entry->AddContentChangeCallback(aObserver, aData, aForImage); entry->AddContentChangeCallback(aObserver, aData, aForImage);
@ -4799,7 +4795,7 @@ nsDocument::RemoveIDTargetObserver(nsIAtom* aID, IDTargetObserver aObserver,
if (!CheckGetElementByIdArg(id)) if (!CheckGetElementByIdArg(id))
return; return;
nsIdentifierMapEntry *entry = mIdentifierMap.GetEntry(id); nsIdentifierMapEntry* entry = mIdentifierMap.GetEntry(aID);
if (!entry) { if (!entry) {
return; return;
} }

View File

@ -40,22 +40,45 @@ class nsIContent;
* Perhaps the document.all results should have their own hashtable * Perhaps the document.all results should have their own hashtable
* in nsHTMLDocument. * in nsHTMLDocument.
*/ */
class nsIdentifierMapEntry : public nsStringHashKey class nsIdentifierMapEntry : public PLDHashEntryHdr
{ {
public: public:
struct AtomOrString
{
MOZ_IMPLICIT AtomOrString(nsIAtom* aAtom) : mAtom(aAtom) {}
MOZ_IMPLICIT AtomOrString(const nsAString& aString) : mString(aString) {}
AtomOrString(const AtomOrString& aOther)
: mAtom(aOther.mAtom)
, mString(aOther.mString)
{
}
AtomOrString(AtomOrString&& aOther)
: mAtom(aOther.mAtom.forget())
, mString(aOther.mString)
{
}
nsCOMPtr<nsIAtom> mAtom;
const nsString mString;
};
typedef const AtomOrString& KeyType;
typedef const AtomOrString* KeyTypePointer;
typedef mozilla::dom::Element Element; typedef mozilla::dom::Element Element;
typedef mozilla::net::ReferrerPolicy ReferrerPolicy; typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
explicit nsIdentifierMapEntry(const nsAString& aKey) : explicit nsIdentifierMapEntry(const AtomOrString& aKey)
nsStringHashKey(&aKey), mNameContentList(nullptr) : mKey(aKey)
{ {
} }
explicit nsIdentifierMapEntry(const nsAString* aKey) : explicit nsIdentifierMapEntry(const AtomOrString* aKey)
nsStringHashKey(aKey), mNameContentList(nullptr) : mKey(aKey ? *aKey : nullptr)
{ {
} }
nsIdentifierMapEntry(nsIdentifierMapEntry&& aOther) : nsIdentifierMapEntry(nsIdentifierMapEntry&& aOther) :
nsStringHashKey(&aOther.GetKey()), mKey(mozilla::Move(aOther.GetKey())),
mIdContentList(mozilla::Move(aOther.mIdContentList)), mIdContentList(mozilla::Move(aOther.mIdContentList)),
mNameContentList(aOther.mNameContentList.forget()), mNameContentList(aOther.mNameContentList.forget()),
mChangeCallbacks(aOther.mChangeCallbacks.forget()), mChangeCallbacks(aOther.mChangeCallbacks.forget()),
@ -64,6 +87,42 @@ public:
} }
~nsIdentifierMapEntry(); ~nsIdentifierMapEntry();
KeyType GetKey() const { return mKey; }
nsString GetKeyAsString() const
{
if (mKey.mAtom) {
return nsAtomString(mKey.mAtom);
}
return mKey.mString;
}
bool KeyEquals(const KeyTypePointer aOtherKey) const
{
if (mKey.mAtom) {
if (aOtherKey->mAtom) {
return mKey.mAtom == aOtherKey->mAtom;
}
return mKey.mAtom->Equals(aOtherKey->mString);
}
if (aOtherKey->mAtom) {
return aOtherKey->mAtom->Equals(mKey.mString);
}
return mKey.mString.Equals(aOtherKey->mString);
}
static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
static PLDHashNumber HashKey(const KeyTypePointer aKey)
{
return aKey->mAtom ?
aKey->mAtom->hash() : mozilla::HashString(aKey->mString);
}
enum { ALLOW_MEMMOVE = false }; enum { ALLOW_MEMMOVE = false };
void AddNameElement(nsINode* aDocument, Element* aElement); void AddNameElement(nsINode* aDocument, Element* aElement);
@ -167,6 +226,7 @@ private:
void FireChangeCallbacks(Element* aOldElement, Element* aNewElement, void FireChangeCallbacks(Element* aOldElement, Element* aNewElement,
bool aImageOnly = false); bool aImageOnly = false);
AtomOrString mKey;
// empty if there are no elements with this ID. // empty if there are no elements with this ID.
// The elements are stored as weak pointers. // The elements are stored as weak pointers.
AutoTArray<Element*, 1> mIdContentList; AutoTArray<Element*, 1> mIdContentList;

View File

@ -2094,7 +2094,7 @@ nsHTMLDocument::GetSupportedNames(nsTArray<nsString>& aNames)
nsIdentifierMapEntry* entry = iter.Get(); nsIdentifierMapEntry* entry = iter.Get();
if (entry->HasNameElement() || if (entry->HasNameElement() ||
entry->HasIdElementExposedAsHTMLDocumentProperty()) { entry->HasIdElementExposedAsHTMLDocumentProperty()) {
aNames.AppendElement(entry->GetKey()); aNames.AppendElement(entry->GetKeyAsString());
} }
} }
} }