LCOV - code coverage report
Current view: top level - dom/base - nsTextNode.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 23 111 20.7 %
Date: 2017-07-14 16:53:18 Functions: 10 27 37.0 %
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             :  * Implementation of DOM Core's nsIDOMText node.
       9             :  */
      10             : 
      11             : #include "nsTextNode.h"
      12             : #include "mozilla/dom/TextBinding.h"
      13             : #include "nsContentUtils.h"
      14             : #include "mozilla/dom/DirectionalityUtils.h"
      15             : #include "nsIDOMEventListener.h"
      16             : #include "nsIDOMMutationEvent.h"
      17             : #include "nsIDocument.h"
      18             : #include "nsThreadUtils.h"
      19             : #include "nsStubMutationObserver.h"
      20             : #include "mozilla/IntegerPrintfMacros.h"
      21             : #ifdef DEBUG
      22             : #include "nsRange.h"
      23             : #endif
      24             : 
      25             : using namespace mozilla;
      26             : using namespace mozilla::dom;
      27             : 
      28             : /**
      29             :  * class used to implement attr() generated content
      30             :  */
      31             : class nsAttributeTextNode final : public nsTextNode,
      32             :                                   public nsStubMutationObserver
      33             : {
      34             : public:
      35             :   NS_DECL_ISUPPORTS_INHERITED
      36             : 
      37           0 :   nsAttributeTextNode(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
      38             :                       int32_t aNameSpaceID,
      39           0 :                       nsIAtom* aAttrName) :
      40             :     nsTextNode(aNodeInfo),
      41             :     mGrandparent(nullptr),
      42             :     mNameSpaceID(aNameSpaceID),
      43           0 :     mAttrName(aAttrName)
      44             :   {
      45           0 :     NS_ASSERTION(mNameSpaceID != kNameSpaceID_Unknown, "Must know namespace");
      46           0 :     NS_ASSERTION(mAttrName, "Must have attr name");
      47           0 :   }
      48             : 
      49             :   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
      50             :                               nsIContent* aBindingParent,
      51             :                               bool aCompileEventHandlers) override;
      52             :   virtual void UnbindFromTree(bool aDeep = true,
      53             :                               bool aNullParent = true) override;
      54             : 
      55             :   NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
      56             :   NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED
      57             : 
      58           0 :   virtual nsGenericDOMDataNode *CloneDataNode(mozilla::dom::NodeInfo *aNodeInfo,
      59             :                                               bool aCloneText) const override
      60             :   {
      61             :     already_AddRefed<mozilla::dom::NodeInfo> ni =
      62           0 :       RefPtr<mozilla::dom::NodeInfo>(aNodeInfo).forget();
      63             :     nsAttributeTextNode *it = new nsAttributeTextNode(ni,
      64           0 :                                                       mNameSpaceID,
      65           0 :                                                       mAttrName);
      66           0 :     if (it && aCloneText) {
      67           0 :       it->mText = mText;
      68             :     }
      69             : 
      70           0 :     return it;
      71             :   }
      72             : 
      73             :   // Public method for the event to run
      74           0 :   void UpdateText() {
      75           0 :     UpdateText(true);
      76           0 :   }
      77             : 
      78             : private:
      79           0 :   virtual ~nsAttributeTextNode() {
      80           0 :     NS_ASSERTION(!mGrandparent, "We were not unbound!");
      81           0 :   }
      82             : 
      83             :   // Update our text to our parent's current attr value
      84             :   void UpdateText(bool aNotify);
      85             : 
      86             :   // This doesn't need to be a strong pointer because it's only non-null
      87             :   // while we're bound to the document tree, and it points to an ancestor
      88             :   // so the ancestor must be bound to the document tree the whole time
      89             :   // and can't be deleted.
      90             :   nsIContent* mGrandparent;
      91             :   // What attribute we're showing
      92             :   int32_t mNameSpaceID;
      93             :   nsCOMPtr<nsIAtom> mAttrName;
      94             : };
      95             : 
      96           6 : nsTextNode::~nsTextNode()
      97             : {
      98           9 : }
      99             : 
     100        3050 : NS_IMPL_ISUPPORTS_INHERITED(nsTextNode, nsGenericDOMDataNode, nsIDOMNode,
     101             :                             nsIDOMText, nsIDOMCharacterData)
     102             : 
     103             : JSObject*
     104           1 : nsTextNode::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
     105             : {
     106           1 :   return TextBinding::Wrap(aCx, this, aGivenProto);
     107             : }
     108             : 
     109             : bool
     110        1834 : nsTextNode::IsNodeOfType(uint32_t aFlags) const
     111             : {
     112        1834 :   return !(aFlags & ~(eCONTENT | eTEXT | eDATA_NODE));
     113             : }
     114             : 
     115             : nsGenericDOMDataNode*
     116          16 : nsTextNode::CloneDataNode(mozilla::dom::NodeInfo *aNodeInfo, bool aCloneText) const
     117             : {
     118          32 :   already_AddRefed<mozilla::dom::NodeInfo> ni = RefPtr<mozilla::dom::NodeInfo>(aNodeInfo).forget();
     119          16 :   nsTextNode *it = new nsTextNode(ni);
     120          16 :   if (aCloneText) {
     121          16 :     it->mText = mText;
     122             :   }
     123             : 
     124          32 :   return it;
     125             : }
     126             : 
     127             : nsresult
     128           0 : nsTextNode::AppendTextForNormalize(const char16_t* aBuffer, uint32_t aLength,
     129             :                                    bool aNotify, nsIContent* aNextSibling)
     130             : {
     131             :   CharacterDataChangeInfo::Details details = {
     132             :     CharacterDataChangeInfo::Details::eMerge, aNextSibling
     133           0 :   };
     134           0 :   return SetTextInternal(mText.GetLength(), 0, aBuffer, aLength, aNotify, &details);
     135             : }
     136             : 
     137             : nsresult
     138         489 : nsTextNode::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
     139             :                        nsIContent* aBindingParent, bool aCompileEventHandlers)
     140             : {
     141         489 :   nsresult rv = nsGenericDOMDataNode::BindToTree(aDocument, aParent,
     142             :                                                  aBindingParent,
     143         489 :                                                  aCompileEventHandlers);
     144         489 :   NS_ENSURE_SUCCESS(rv, rv);
     145             : 
     146         489 :   SetDirectionFromNewTextNode(this);
     147             : 
     148         489 :   return NS_OK;
     149             : }
     150             : 
     151          30 : void nsTextNode::UnbindFromTree(bool aDeep, bool aNullParent)
     152             : {
     153          30 :   ResetDirectionSetByTextNode(this);
     154             : 
     155          30 :   nsGenericDOMDataNode::UnbindFromTree(aDeep, aNullParent);
     156          30 : }
     157             : 
     158             : #ifdef DEBUG
     159             : void
     160           0 : nsTextNode::List(FILE* out, int32_t aIndent) const
     161             : {
     162             :   int32_t index;
     163           0 :   for (index = aIndent; --index >= 0; ) fputs("  ", out);
     164             : 
     165           0 :   fprintf(out, "Text@%p", static_cast<const void*>(this));
     166           0 :   fprintf(out, " flags=[%08x]", static_cast<unsigned int>(GetFlags()));
     167           0 :   if (IsCommonAncestorForRangeInSelection()) {
     168             :     typedef nsTHashtable<nsPtrHashKey<nsRange> > RangeHashTable;
     169             :     RangeHashTable* ranges =
     170           0 :       static_cast<RangeHashTable*>(GetProperty(nsGkAtoms::range));
     171           0 :     fprintf(out, " ranges:%d", ranges ? ranges->Count() : 0);
     172             :   }
     173           0 :   fprintf(out, " primaryframe=%p", static_cast<void*>(GetPrimaryFrame()));
     174           0 :   fprintf(out, " refcount=%" PRIuPTR "<", mRefCnt.get());
     175             : 
     176           0 :   nsAutoString tmp;
     177           0 :   ToCString(tmp, 0, mText.GetLength());
     178           0 :   fputs(NS_LossyConvertUTF16toASCII(tmp).get(), out);
     179             : 
     180           0 :   fputs(">\n", out);
     181           0 : }
     182             : 
     183             : void
     184           0 : nsTextNode::DumpContent(FILE* out, int32_t aIndent, bool aDumpAll) const
     185             : {
     186           0 :   if(aDumpAll) {
     187             :     int32_t index;
     188           0 :     for (index = aIndent; --index >= 0; ) fputs("  ", out);
     189             : 
     190           0 :     nsAutoString tmp;
     191           0 :     ToCString(tmp, 0, mText.GetLength());
     192             : 
     193           0 :     if(!tmp.EqualsLiteral("\\n")) {
     194           0 :       fputs(NS_LossyConvertUTF16toASCII(tmp).get(), out);
     195           0 :       if(aIndent) fputs("\n", out);
     196             :     }
     197             :   }
     198           0 : }
     199             : #endif
     200             : 
     201             : nsresult
     202           0 : NS_NewAttributeContent(nsNodeInfoManager *aNodeInfoManager,
     203             :                        int32_t aNameSpaceID, nsIAtom* aAttrName,
     204             :                        nsIContent** aResult)
     205             : {
     206           0 :   NS_PRECONDITION(aNodeInfoManager, "Missing nodeInfoManager");
     207           0 :   NS_PRECONDITION(aAttrName, "Must have an attr name");
     208           0 :   NS_PRECONDITION(aNameSpaceID != kNameSpaceID_Unknown, "Must know namespace");
     209             : 
     210           0 :   *aResult = nullptr;
     211             : 
     212           0 :   already_AddRefed<mozilla::dom::NodeInfo> ni = aNodeInfoManager->GetTextNodeInfo();
     213             : 
     214             :   nsAttributeTextNode* textNode = new nsAttributeTextNode(ni,
     215             :                                                           aNameSpaceID,
     216           0 :                                                           aAttrName);
     217           0 :   NS_ADDREF(*aResult = textNode);
     218             : 
     219           0 :   return NS_OK;
     220             : }
     221             : 
     222           0 : NS_IMPL_ISUPPORTS_INHERITED(nsAttributeTextNode, nsTextNode,
     223             :                             nsIMutationObserver)
     224             : 
     225             : nsresult
     226           0 : nsAttributeTextNode::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
     227             :                                 nsIContent* aBindingParent,
     228             :                                 bool aCompileEventHandlers)
     229             : {
     230           0 :   NS_PRECONDITION(aParent && aParent->GetParent(),
     231             :                   "This node can't be a child of the document or of the document root");
     232             : 
     233           0 :   nsresult rv = nsTextNode::BindToTree(aDocument, aParent,
     234           0 :                                        aBindingParent, aCompileEventHandlers);
     235           0 :   NS_ENSURE_SUCCESS(rv, rv);
     236             : 
     237           0 :   NS_ASSERTION(!mGrandparent, "We were already bound!");
     238           0 :   mGrandparent = aParent->GetParent();
     239           0 :   mGrandparent->AddMutationObserver(this);
     240             : 
     241             :   // Note that there is no need to notify here, since we have no
     242             :   // frame yet at this point.
     243           0 :   UpdateText(false);
     244             : 
     245           0 :   return NS_OK;
     246             : }
     247             : 
     248             : void
     249           0 : nsAttributeTextNode::UnbindFromTree(bool aDeep, bool aNullParent)
     250             : {
     251             :   // UnbindFromTree can be called anytime so we have to be safe.
     252           0 :   if (mGrandparent) {
     253             :     // aNullParent might not be true here, but we want to remove the
     254             :     // mutation observer anyway since we only need it while we're
     255             :     // in the document.
     256           0 :     mGrandparent->RemoveMutationObserver(this);
     257           0 :     mGrandparent = nullptr;
     258             :   }
     259           0 :   nsTextNode::UnbindFromTree(aDeep, aNullParent);
     260           0 : }
     261             : 
     262             : void
     263           0 : nsAttributeTextNode::AttributeChanged(nsIDocument* aDocument,
     264             :                                       Element* aElement,
     265             :                                       int32_t aNameSpaceID,
     266             :                                       nsIAtom* aAttribute,
     267             :                                       int32_t aModType,
     268             :                                       const nsAttrValue* aOldValue)
     269             : {
     270           0 :   if (aNameSpaceID == mNameSpaceID && aAttribute == mAttrName &&
     271           0 :       aElement == mGrandparent) {
     272             :     // Since UpdateText notifies, do it when it's safe to run script.  Note
     273             :     // that if we get unbound while the event is up that's ok -- we'll just
     274             :     // have no grandparent when it fires, and will do nothing.
     275           0 :     void (nsAttributeTextNode::*update)() = &nsAttributeTextNode::UpdateText;
     276           0 :     nsContentUtils::AddScriptRunner(
     277           0 :       NewRunnableMethod("nsAttributeTextNode::AttributeChanged", this, update));
     278             :   }
     279           0 : }
     280             : 
     281             : void
     282           0 : nsAttributeTextNode::NodeWillBeDestroyed(const nsINode* aNode)
     283             : {
     284           0 :   NS_ASSERTION(aNode == static_cast<nsINode*>(mGrandparent), "Wrong node!");
     285           0 :   mGrandparent = nullptr;
     286           0 : }
     287             : 
     288             : void
     289           0 : nsAttributeTextNode::UpdateText(bool aNotify)
     290             : {
     291           0 :   if (mGrandparent) {
     292           0 :     nsAutoString attrValue;
     293           0 :     mGrandparent->GetAttr(mNameSpaceID, mAttrName, attrValue);
     294           0 :     SetText(attrValue, aNotify);
     295             :   }
     296           0 : }
     297             : 

Generated by: LCOV version 1.13