LCOV - code coverage report
Current view: top level - dom/base - nsIdentifierMapEntry.h (source / functions) Hit Total Coverage
Test: output.info Lines: 33 48 68.8 %
Date: 2017-07-14 16:53:18 Functions: 14 18 77.8 %
Legend: Lines: hit not hit

          Line data    Source code
       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/. */
       6             : 
       7             : /*
       8             :  * Base class for all our document implementations.
       9             :  */
      10             : 
      11             : #ifndef nsIdentifierMapEntry_h
      12             : #define nsIdentifierMapEntry_h
      13             : 
      14             : #include "PLDHashTable.h"
      15             : 
      16             : #include "mozilla/MemoryReporting.h"
      17             : #include "mozilla/Move.h"
      18             : #include "mozilla/dom/Element.h"
      19             : #include "mozilla/net/ReferrerPolicy.h"
      20             : 
      21             : #include "nsCOMArray.h"
      22             : #include "nsCOMPtr.h"
      23             : #include "nsContentList.h"
      24             : #include "nsIAtom.h"
      25             : #include "nsIDocument.h"
      26             : #include "nsTArray.h"
      27             : #include "nsTHashtable.h"
      28             : 
      29             : class nsIContent;
      30             : 
      31             : /**
      32             :  * Right now our identifier map entries contain information for 'name'
      33             :  * and 'id' mappings of a given string. This is so that
      34             :  * nsHTMLDocument::ResolveName only has to do one hash lookup instead
      35             :  * of two. It's not clear whether this still matters for performance.
      36             :  *
      37             :  * We also store the document.all result list here. This is mainly so that
      38             :  * when all elements with the given ID are removed and we remove
      39             :  * the ID's nsIdentifierMapEntry, the document.all result is released too.
      40             :  * Perhaps the document.all results should have their own hashtable
      41             :  * in nsHTMLDocument.
      42             :  */
      43             : class nsIdentifierMapEntry : public PLDHashEntryHdr
      44             : {
      45             : public:
      46        4335 :   struct AtomOrString
      47             :   {
      48        2208 :     MOZ_IMPLICIT AtomOrString(nsIAtom* aAtom) : mAtom(aAtom) {}
      49         551 :     MOZ_IMPLICIT AtomOrString(const nsAString& aString) : mString(aString) {}
      50        2600 :     AtomOrString(const AtomOrString& aOther)
      51        2600 :       : mAtom(aOther.mAtom)
      52        2600 :       , mString(aOther.mString)
      53             :     {
      54        2600 :     }
      55             : 
      56             :     AtomOrString(AtomOrString&& aOther)
      57             :       : mAtom(aOther.mAtom.forget())
      58             :       , mString(aOther.mString)
      59             :     {
      60             :     }
      61             : 
      62             :     nsCOMPtr<nsIAtom> mAtom;
      63             :     const nsString mString;
      64             :   };
      65             : 
      66             :   typedef const AtomOrString& KeyType;
      67             :   typedef const AtomOrString* KeyTypePointer;
      68             : 
      69             :   typedef mozilla::dom::Element Element;
      70             :   typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
      71             : 
      72             :   explicit nsIdentifierMapEntry(const AtomOrString& aKey)
      73             :     : mKey(aKey)
      74             :   {
      75             :   }
      76        1052 :   explicit nsIdentifierMapEntry(const AtomOrString* aKey)
      77        1052 :     : mKey(aKey ? *aKey : nullptr)
      78             :   {
      79        1052 :   }
      80        1548 :   nsIdentifierMapEntry(nsIdentifierMapEntry&& aOther) :
      81        1548 :     mKey(mozilla::Move(aOther.GetKey())),
      82        1548 :     mIdContentList(mozilla::Move(aOther.mIdContentList)),
      83        3096 :     mNameContentList(aOther.mNameContentList.forget()),
      84             :     mChangeCallbacks(aOther.mChangeCallbacks.forget()),
      85        7740 :     mImageElement(aOther.mImageElement.forget())
      86             :   {
      87        1548 :   }
      88             :   ~nsIdentifierMapEntry();
      89             : 
      90        1548 :   KeyType GetKey() const { return mKey; }
      91             : 
      92           0 :   nsString GetKeyAsString() const
      93             :   {
      94           0 :     if (mKey.mAtom) {
      95           0 :       return nsAtomString(mKey.mAtom);
      96             :     }
      97             : 
      98           0 :     return mKey.mString;
      99             :   }
     100             : 
     101        1516 :   bool KeyEquals(const KeyTypePointer aOtherKey) const
     102             :   {
     103        1516 :     if (mKey.mAtom) {
     104        1516 :       if (aOtherKey->mAtom) {
     105        1131 :         return mKey.mAtom == aOtherKey->mAtom;
     106             :       }
     107             : 
     108         385 :       return mKey.mAtom->Equals(aOtherKey->mString);
     109             :     }
     110             : 
     111           0 :     if (aOtherKey->mAtom) {
     112           0 :       return aOtherKey->mAtom->Equals(mKey.mString);
     113             :     }
     114             : 
     115           0 :     return mKey.mString.Equals(aOtherKey->mString);
     116             :   }
     117             : 
     118        2759 :   static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
     119             : 
     120        2715 :   static PLDHashNumber HashKey(const KeyTypePointer aKey)
     121             :   {
     122        5430 :     return aKey->mAtom ?
     123        8145 :       aKey->mAtom->hash() : mozilla::HashString(aKey->mString);
     124             :   }
     125             : 
     126             :   enum { ALLOW_MEMMOVE = false };
     127             : 
     128             :   void AddNameElement(nsINode* aDocument, Element* aElement);
     129             :   void RemoveNameElement(Element* aElement);
     130             :   bool IsEmpty();
     131           0 :   nsBaseContentList* GetNameContentList() {
     132           0 :     return mNameContentList;
     133             :   }
     134           0 :   bool HasNameElement() const {
     135           0 :     return mNameContentList && mNameContentList->Length() != 0;
     136             :   }
     137             : 
     138             :   /**
     139             :    * Returns the element if we know the element associated with this
     140             :    * id. Otherwise returns null.
     141             :    */
     142             :   Element* GetIdElement();
     143             :   /**
     144             :    * Returns the list of all elements associated with this id.
     145             :    */
     146           3 :   const nsTArray<Element*>& GetIdElements() const {
     147           3 :     return mIdContentList;
     148             :   }
     149             :   /**
     150             :    * If this entry has a non-null image element set (using SetImageElement),
     151             :    * the image element will be returned, otherwise the same as GetIdElement().
     152             :    */
     153             :   Element* GetImageIdElement();
     154             :   /**
     155             :    * Append all the elements with this id to aElements
     156             :    */
     157             :   void AppendAllIdContent(nsCOMArray<nsIContent>* aElements);
     158             :   /**
     159             :    * This can fire ID change callbacks.
     160             :    * @return true if the content could be added, false if we failed due
     161             :    * to OOM.
     162             :    */
     163             :   bool AddIdElement(Element* aElement);
     164             :   /**
     165             :    * This can fire ID change callbacks.
     166             :    */
     167             :   void RemoveIdElement(Element* aElement);
     168             :   /**
     169             :    * Set the image element override for this ID. This will be returned by
     170             :    * GetIdElement(true) if non-null.
     171             :    */
     172             :   void SetImageElement(Element* aElement);
     173             :   bool HasIdElementExposedAsHTMLDocumentProperty();
     174             : 
     175             :   bool HasContentChangeCallback() { return mChangeCallbacks != nullptr; }
     176             :   void AddContentChangeCallback(nsIDocument::IDTargetObserver aCallback,
     177             :                                 void* aData, bool aForImage);
     178             :   void RemoveContentChangeCallback(nsIDocument::IDTargetObserver aCallback,
     179             :                                 void* aData, bool aForImage);
     180             : 
     181             :   void Traverse(nsCycleCollectionTraversalCallback* aCallback);
     182             : 
     183             :   struct ChangeCallback {
     184             :     nsIDocument::IDTargetObserver mCallback;
     185             :     void* mData;
     186             :     bool mForImage;
     187             :   };
     188             : 
     189             :   struct ChangeCallbackEntry : public PLDHashEntryHdr {
     190             :     typedef const ChangeCallback KeyType;
     191             :     typedef const ChangeCallback* KeyTypePointer;
     192             : 
     193          25 :     explicit ChangeCallbackEntry(const ChangeCallback* aKey) :
     194          25 :       mKey(*aKey) { }
     195             :     ChangeCallbackEntry(const ChangeCallbackEntry& toCopy) :
     196             :       mKey(toCopy.mKey) { }
     197             : 
     198             :     KeyType GetKey() const { return mKey; }
     199           0 :     bool KeyEquals(KeyTypePointer aKey) const {
     200           0 :       return aKey->mCallback == mKey.mCallback &&
     201           0 :              aKey->mData == mKey.mData &&
     202           0 :              aKey->mForImage == mKey.mForImage;
     203             :     }
     204             : 
     205          25 :     static KeyTypePointer KeyToPointer(KeyType& aKey) { return &aKey; }
     206          25 :     static PLDHashNumber HashKey(KeyTypePointer aKey)
     207             :     {
     208          25 :       return mozilla::HashGeneric(aKey->mCallback, aKey->mData);
     209             :     }
     210             :     enum { ALLOW_MEMMOVE = true };
     211             : 
     212             :     ChangeCallback mKey;
     213             :   };
     214             : 
     215             :   size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
     216             : 
     217             : private:
     218             :   nsIdentifierMapEntry(const nsIdentifierMapEntry& aOther) = delete;
     219             :   nsIdentifierMapEntry& operator=(const nsIdentifierMapEntry& aOther) = delete;
     220             : 
     221             :   void FireChangeCallbacks(Element* aOldElement, Element* aNewElement,
     222             :                            bool aImageOnly = false);
     223             : 
     224             :   AtomOrString mKey;
     225             :   // empty if there are no elements with this ID.
     226             :   // The elements are stored as weak pointers.
     227             :   AutoTArray<Element*, 1> mIdContentList;
     228             :   RefPtr<nsBaseContentList> mNameContentList;
     229             :   nsAutoPtr<nsTHashtable<ChangeCallbackEntry> > mChangeCallbacks;
     230             :   RefPtr<Element> mImageElement;
     231             : };
     232             : 
     233             : #endif // #ifndef nsIdentifierMapEntry_h

Generated by: LCOV version 1.13