content/base/public/FragmentOrElement.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 /*
     7  * Base class for all element classes as well as nsDocumentFragment.  This
     8  * provides an implementation of nsIDOMNode, implements nsIContent, provides
     9  * utility methods for subclasses, and so forth.
    10  */
    12 #ifndef FragmentOrElement_h___
    13 #define FragmentOrElement_h___
    15 #include "mozilla/Attributes.h"
    16 #include "mozilla/MemoryReporting.h"
    17 #include "nsAttrAndChildArray.h"          // member
    18 #include "nsCycleCollectionParticipant.h" // NS_DECL_CYCLE_*
    19 #include "nsIContent.h"                   // base class
    20 #include "nsIDOMXPathNSResolver.h"        // base class
    21 #include "nsINodeList.h"                  // base class
    22 #include "nsIWeakReference.h"             // base class
    23 #include "nsNodeUtils.h"                  // class member nsNodeUtils::CloneNodeImpl
    24 #include "nsIHTMLCollection.h"
    26 class ContentUnbinder;
    27 class nsContentList;
    28 class nsDOMAttributeMap;
    29 class nsDOMTokenList;
    30 class nsIControllers;
    31 class nsICSSDeclaration;
    32 class nsIDocument;
    33 class nsDOMStringMap;
    34 class nsINodeInfo;
    35 class nsIURI;
    37 /**
    38  * Class that implements the nsIDOMNodeList interface (a list of children of
    39  * the content), by holding a reference to the content and delegating GetLength
    40  * and Item to its existing child list.
    41  * @see nsIDOMNodeList
    42  */
    43 class nsChildContentList MOZ_FINAL : public nsINodeList
    44 {
    45 public:
    46   nsChildContentList(nsINode* aNode)
    47     : mNode(aNode)
    48   {
    49     SetIsDOMBinding();
    50   }
    52   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
    53   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(nsChildContentList)
    55   // nsWrapperCache
    56   virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
    58   // nsIDOMNodeList interface
    59   NS_DECL_NSIDOMNODELIST
    61   // nsINodeList interface
    62   virtual int32_t IndexOf(nsIContent* aContent) MOZ_OVERRIDE;
    63   virtual nsIContent* Item(uint32_t aIndex) MOZ_OVERRIDE;
    65   void DropReference()
    66   {
    67     mNode = nullptr;
    68   }
    70   virtual nsINode* GetParentObject() MOZ_OVERRIDE
    71   {
    72     return mNode;
    73   }
    75 private:
    76   // The node whose children make up the list (weak reference)
    77   nsINode* mNode;
    78 };
    80 /**
    81  * A tearoff class for FragmentOrElement to implement additional interfaces
    82  */
    83 class nsNode3Tearoff : public nsIDOMXPathNSResolver
    84 {
    85 public:
    86   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
    88   NS_DECL_CYCLE_COLLECTION_CLASS(nsNode3Tearoff)
    90   NS_DECL_NSIDOMXPATHNSRESOLVER
    92   nsNode3Tearoff(nsINode *aNode) : mNode(aNode)
    93   {
    94   }
    96 protected:
    97   virtual ~nsNode3Tearoff() {}
    99 private:
   100   nsCOMPtr<nsINode> mNode;
   101 };
   103 /**
   104  * A class that implements nsIWeakReference
   105  */
   107 class nsNodeWeakReference MOZ_FINAL : public nsIWeakReference
   108 {
   109 public:
   110   nsNodeWeakReference(nsINode* aNode)
   111     : mNode(aNode)
   112   {
   113   }
   115   ~nsNodeWeakReference();
   117   // nsISupports
   118   NS_DECL_ISUPPORTS
   120   // nsIWeakReference
   121   NS_DECL_NSIWEAKREFERENCE
   123   void NoticeNodeDestruction()
   124   {
   125     mNode = nullptr;
   126   }
   128 private:
   129   nsINode* mNode;
   130 };
   132 /**
   133  * Tearoff to use for nodes to implement nsISupportsWeakReference
   134  */
   135 class nsNodeSupportsWeakRefTearoff MOZ_FINAL : public nsISupportsWeakReference
   136 {
   137 public:
   138   nsNodeSupportsWeakRefTearoff(nsINode* aNode)
   139     : mNode(aNode)
   140   {
   141   }
   143   // nsISupports
   144   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   146   // nsISupportsWeakReference
   147   NS_DECL_NSISUPPORTSWEAKREFERENCE
   149   NS_DECL_CYCLE_COLLECTION_CLASS(nsNodeSupportsWeakRefTearoff)
   151 private:
   152   nsCOMPtr<nsINode> mNode;
   153 };
   155 /**
   156  * A generic base class for DOM elements, implementing many nsIContent,
   157  * nsIDOMNode and nsIDOMElement methods.
   158  */
   159 namespace mozilla {
   160 namespace dom {
   162 class ShadowRoot;
   163 class UndoManager;
   165 class FragmentOrElement : public nsIContent
   166 {
   167 public:
   168   FragmentOrElement(already_AddRefed<nsINodeInfo>& aNodeInfo);
   169   FragmentOrElement(already_AddRefed<nsINodeInfo>&& aNodeInfo);
   170   virtual ~FragmentOrElement();
   172   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   174   NS_DECL_SIZEOF_EXCLUDING_THIS
   176   // nsINode interface methods
   177   virtual uint32_t GetChildCount() const MOZ_OVERRIDE;
   178   virtual nsIContent *GetChildAt(uint32_t aIndex) const MOZ_OVERRIDE;
   179   virtual nsIContent * const * GetChildArray(uint32_t* aChildCount) const MOZ_OVERRIDE;
   180   virtual int32_t IndexOf(const nsINode* aPossibleChild) const MOZ_OVERRIDE;
   181   virtual nsresult InsertChildAt(nsIContent* aKid, uint32_t aIndex,
   182                                  bool aNotify) MOZ_OVERRIDE;
   183   virtual void RemoveChildAt(uint32_t aIndex, bool aNotify) MOZ_OVERRIDE;
   184   virtual void GetTextContentInternal(nsAString& aTextContent) MOZ_OVERRIDE;
   185   virtual void SetTextContentInternal(const nsAString& aTextContent,
   186                                       mozilla::ErrorResult& aError) MOZ_OVERRIDE;
   188   // nsIContent interface methods
   189   virtual already_AddRefed<nsINodeList> GetChildren(uint32_t aFilter) MOZ_OVERRIDE;
   190   virtual const nsTextFragment *GetText() MOZ_OVERRIDE;
   191   virtual uint32_t TextLength() const MOZ_OVERRIDE;
   192   virtual nsresult SetText(const char16_t* aBuffer, uint32_t aLength,
   193                            bool aNotify) MOZ_OVERRIDE;
   194   // Need to implement this here too to avoid hiding.
   195   nsresult SetText(const nsAString& aStr, bool aNotify)
   196   {
   197     return SetText(aStr.BeginReading(), aStr.Length(), aNotify);
   198   }
   199   virtual nsresult AppendText(const char16_t* aBuffer, uint32_t aLength,
   200                               bool aNotify) MOZ_OVERRIDE;
   201   virtual bool TextIsOnlyWhitespace() MOZ_OVERRIDE;
   202   virtual bool HasTextForTranslation() MOZ_OVERRIDE;
   203   virtual void AppendTextTo(nsAString& aResult) MOZ_OVERRIDE;
   204   virtual bool AppendTextTo(nsAString& aResult,
   205                             const mozilla::fallible_t&) MOZ_OVERRIDE NS_WARN_UNUSED_RESULT; 
   206   virtual nsIContent *GetBindingParent() const MOZ_OVERRIDE;
   207   virtual nsXBLBinding *GetXBLBinding() const MOZ_OVERRIDE;
   208   virtual void SetXBLBinding(nsXBLBinding* aBinding,
   209                              nsBindingManager* aOldBindingManager = nullptr) MOZ_OVERRIDE;
   210   virtual ShadowRoot *GetShadowRoot() const MOZ_OVERRIDE;
   211   virtual ShadowRoot *GetContainingShadow() const MOZ_OVERRIDE;
   212   virtual void SetShadowRoot(ShadowRoot* aBinding) MOZ_OVERRIDE;
   213   virtual nsIContent *GetXBLInsertionParent() const MOZ_OVERRIDE;
   214   virtual void SetXBLInsertionParent(nsIContent* aContent) MOZ_OVERRIDE;
   215   virtual bool IsLink(nsIURI** aURI) const MOZ_OVERRIDE;
   217   virtual CustomElementData *GetCustomElementData() const MOZ_OVERRIDE;
   218   virtual void SetCustomElementData(CustomElementData* aData) MOZ_OVERRIDE;
   220   virtual void DestroyContent() MOZ_OVERRIDE;
   221   virtual void SaveSubtreeState() MOZ_OVERRIDE;
   223   virtual const nsAttrValue* DoGetClasses() const MOZ_OVERRIDE;
   224   NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker) MOZ_OVERRIDE;
   226   nsIHTMLCollection* Children();
   227   uint32_t ChildElementCount()
   228   {
   229     return Children()->Length();
   230   }
   232 public:
   233   /**
   234    * If there are listeners for DOMNodeInserted event, fires the event on all
   235    * aNodes
   236    */
   237   static void FireNodeInserted(nsIDocument* aDoc,
   238                                nsINode* aParent,
   239                                nsTArray<nsCOMPtr<nsIContent> >& aNodes);
   241   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(FragmentOrElement)
   243   /**
   244    * Fire a DOMNodeRemoved mutation event for all children of this node
   245    */
   246   void FireNodeRemovedForChildren();
   248   virtual bool OwnedOnlyByTheDOMTree() MOZ_OVERRIDE
   249   {
   250     uint32_t rc = mRefCnt.get();
   251     if (GetParent()) {
   252       --rc;
   253     }
   254     rc -= mAttrsAndChildren.ChildCount();
   255     return rc == 0;
   256   }
   258   virtual bool IsPurple() MOZ_OVERRIDE
   259   {
   260     return mRefCnt.IsPurple();
   261   }
   263   virtual void RemovePurple() MOZ_OVERRIDE
   264   {
   265     mRefCnt.RemovePurple();
   266   }
   268   static void ClearContentUnbinder();
   269   static bool CanSkip(nsINode* aNode, bool aRemovingAllowed);
   270   static bool CanSkipInCC(nsINode* aNode);
   271   static bool CanSkipThis(nsINode* aNode);
   272   static void RemoveBlackMarkedNode(nsINode* aNode);
   273   static void MarkNodeChildren(nsINode* aNode);
   274   static void InitCCCallbacks();
   275   static void MarkUserData(void* aObject, nsIAtom* aKey, void* aChild,
   276                            void *aData);
   277   static void MarkUserDataHandler(void* aObject, nsIAtom* aKey, void* aChild,
   278                                   void* aData);
   280 protected:
   281   /**
   282    * Copy attributes and state to another element
   283    * @param aDest the object to copy to
   284    */
   285   nsresult CopyInnerTo(FragmentOrElement* aDest);
   287 public:
   288   // Because of a bug in MS C++ compiler nsDOMSlots must be declared public,
   289   // otherwise nsXULElement::nsXULSlots doesn't compile.
   290   /**
   291    * There are a set of DOM- and scripting-specific instance variables
   292    * that may only be instantiated when a content object is accessed
   293    * through the DOM. Rather than burn actual slots in the content
   294    * objects for each of these instance variables, we put them off
   295    * in a side structure that's only allocated when the content is
   296    * accessed through the DOM.
   297    */
   298   class nsDOMSlots : public nsINode::nsSlots
   299   {
   300   public:
   301     nsDOMSlots();
   302     virtual ~nsDOMSlots();
   304     void Traverse(nsCycleCollectionTraversalCallback &cb, bool aIsXUL);
   305     void Unlink(bool aIsXUL);
   307     size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
   309     /**
   310      * The .style attribute (an interface that forwards to the actual
   311      * style rules)
   312      * @see nsGenericHTMLElement::GetStyle
   313      */
   314     nsCOMPtr<nsICSSDeclaration> mStyle;
   316     /**
   317      * The .dataset attribute.
   318      * @see nsGenericHTMLElement::GetDataset
   319      */
   320     nsDOMStringMap* mDataset; // [Weak]
   322     /**
   323      * The .undoManager property.
   324      * @see nsGenericHTMLElement::GetUndoManager
   325      */
   326     nsRefPtr<UndoManager> mUndoManager;
   328     /**
   329      * SMIL Overridde style rules (for SMIL animation of CSS properties)
   330      * @see nsIContent::GetSMILOverrideStyle
   331      */
   332     nsCOMPtr<nsICSSDeclaration> mSMILOverrideStyle;
   334     /**
   335      * Holds any SMIL override style rules for this element.
   336      */
   337     nsRefPtr<mozilla::css::StyleRule> mSMILOverrideStyleRule;
   339     /**
   340      * An object implementing nsIDOMMozNamedAttrMap for this content (attributes)
   341      * @see FragmentOrElement::GetAttributes
   342      */
   343     nsRefPtr<nsDOMAttributeMap> mAttributeMap;
   345     union {
   346       /**
   347       * The nearest enclosing content node with a binding that created us.
   348       * @see FragmentOrElement::GetBindingParent
   349       */
   350       nsIContent* mBindingParent;  // [Weak]
   352       /**
   353       * The controllers of the XUL Element.
   354       */
   355       nsIControllers* mControllers; // [OWNER]
   356     };
   358     /**
   359      * An object implementing the .children property for this element.
   360      */
   361     nsRefPtr<nsContentList> mChildrenList;
   363     /**
   364      * An object implementing the .classList property for this element.
   365      */
   366     nsRefPtr<nsDOMTokenList> mClassList;
   368     /**
   369      * ShadowRoot bound to the element.
   370      */
   371     nsRefPtr<ShadowRoot> mShadowRoot;
   373     /**
   374      * The root ShadowRoot of this element if it is in a shadow tree.
   375      */
   376     nsRefPtr<ShadowRoot> mContainingShadow;
   378     /**
   379      * XBL binding installed on the element.
   380      */
   381     nsRefPtr<nsXBLBinding> mXBLBinding;
   383     /**
   384      * XBL binding installed on the lement.
   385      */
   386     nsCOMPtr<nsIContent> mXBLInsertionParent;
   388     /**
   389      * Web components custom element data.
   390      */
   391     nsAutoPtr<CustomElementData> mCustomElementData;
   392   };
   394 protected:
   395   void GetMarkup(bool aIncludeSelf, nsAString& aMarkup);
   396   void SetInnerHTMLInternal(const nsAString& aInnerHTML, ErrorResult& aError);
   398   // Override from nsINode
   399   virtual nsINode::nsSlots* CreateSlots() MOZ_OVERRIDE;
   401   nsDOMSlots *DOMSlots()
   402   {
   403     return static_cast<nsDOMSlots*>(Slots());
   404   }
   406   nsDOMSlots *GetExistingDOMSlots() const
   407   {
   408     return static_cast<nsDOMSlots*>(GetExistingSlots());
   409   }
   411   friend class ::ContentUnbinder;
   412   /**
   413    * Array containing all attributes and children for this element
   414    */
   415   nsAttrAndChildArray mAttrsAndChildren;
   416 };
   418 } // namespace dom
   419 } // namespace mozilla
   421 #define NS_ELEMENT_INTERFACE_TABLE_TO_MAP_SEGUE                               \
   422     if (NS_SUCCEEDED(rv))                                                     \
   423       return rv;                                                              \
   424                                                                               \
   425     rv = FragmentOrElement::QueryInterface(aIID, aInstancePtr);               \
   426     NS_INTERFACE_TABLE_TO_MAP_SEGUE
   428 #endif /* FragmentOrElement_h___ */

mercurial