LCOV - code coverage report
Current view: directory - content/base/src - nsGenericDOMDataNode.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 390 189 48.5 %
Date: 2012-06-02 Functions: 79 31 39.2 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is Mozilla Communicator client code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *
      24                 :  * Alternatively, the contents of this file may be used under the terms of
      25                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      26                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      28                 :  * of those above. If you wish to allow use of your version of this file only
      29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      30                 :  * use your version of this file under the terms of the MPL, indicate your
      31                 :  * decision by deleting the provisions above and replace them with the notice
      32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      33                 :  * the provisions above, a recipient may use your version of this file under
      34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      35                 :  *
      36                 :  * ***** END LICENSE BLOCK ***** */
      37                 : 
      38                 : /*
      39                 :  * Base class for DOM Core's nsIDOMComment, nsIDOMDocumentType, nsIDOMText,
      40                 :  * nsIDOMCDATASection, and nsIDOMProcessingInstruction nodes.
      41                 :  */
      42                 : 
      43                 : #include "nsGenericDOMDataNode.h"
      44                 : #include "nsGenericElement.h"
      45                 : #include "nsIDocument.h"
      46                 : #include "nsEventListenerManager.h"
      47                 : #include "nsIDOMDocument.h"
      48                 : #include "nsReadableUtils.h"
      49                 : #include "nsMutationEvent.h"
      50                 : #include "nsINameSpaceManager.h"
      51                 : #include "nsIURI.h"
      52                 : #include "nsIPrivateDOMEvent.h"
      53                 : #include "nsIDOMEvent.h"
      54                 : #include "nsIDOMText.h"
      55                 : #include "nsCOMPtr.h"
      56                 : #include "nsDOMString.h"
      57                 : #include "nsIDOMUserDataHandler.h"
      58                 : #include "nsChangeHint.h"
      59                 : #include "nsEventDispatcher.h"
      60                 : #include "nsCOMArray.h"
      61                 : #include "nsNodeUtils.h"
      62                 : #include "nsBindingManager.h"
      63                 : #include "nsCCUncollectableMarker.h"
      64                 : #include "mozAutoDocUpdate.h"
      65                 : #include "nsAsyncDOMEvent.h"
      66                 : 
      67                 : #include "pldhash.h"
      68                 : #include "prprf.h"
      69                 : #include "nsWrapperCacheInlines.h"
      70                 : 
      71                 : using namespace mozilla;
      72                 : 
      73           74985 : nsGenericDOMDataNode::nsGenericDOMDataNode(already_AddRefed<nsINodeInfo> aNodeInfo)
      74           74985 :   : nsIContent(aNodeInfo)
      75                 : {
      76           74985 :   NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::TEXT_NODE ||
      77                 :                     mNodeInfo->NodeType() == nsIDOMNode::CDATA_SECTION_NODE ||
      78                 :                     mNodeInfo->NodeType() == nsIDOMNode::COMMENT_NODE ||
      79                 :                     mNodeInfo->NodeType() ==
      80                 :                       nsIDOMNode::PROCESSING_INSTRUCTION_NODE ||
      81                 :                     mNodeInfo->NodeType() == nsIDOMNode::DOCUMENT_TYPE_NODE,
      82                 :                     "Bad NodeType in aNodeInfo");
      83           74985 : }
      84                 : 
      85          149966 : nsGenericDOMDataNode::~nsGenericDOMDataNode()
      86                 : {
      87           74983 :   NS_PRECONDITION(!IsInDoc(),
      88                 :                   "Please remove this from the document properly");
      89           74983 :   if (GetParent()) {
      90               0 :     NS_RELEASE(mParent);
      91                 :   }
      92          149966 : }
      93                 : 
      94            1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(nsGenericDOMDataNode)
      95                 : 
      96           90491 : NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsGenericDOMDataNode)
      97           90491 :   nsINode::Trace(tmp, aCallback, aClosure);
      98           90491 : NS_IMPL_CYCLE_COLLECTION_TRACE_END
      99                 : 
     100          195326 : NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsGenericDOMDataNode)
     101          195326 :   return nsGenericElement::CanSkip(tmp, aRemovingAllowed);
     102                 : NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
     103                 : 
     104           61403 : NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsGenericDOMDataNode)
     105           61403 :   return nsGenericElement::CanSkipInCC(tmp);
     106                 : NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
     107                 : 
     108           75161 : NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsGenericDOMDataNode)
     109           75161 :   return nsGenericElement::CanSkipThis(tmp);
     110                 : NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
     111                 : 
     112           90491 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsGenericDOMDataNode)
     113                 :   // Always need to traverse script objects, so do that before we check
     114                 :   // if we're uncollectable.
     115           90491 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
     116                 : 
     117           90491 :   if (!nsINode::Traverse(tmp, cb)) {
     118               0 :     return NS_SUCCESS_INTERRUPTED_TRAVERSE;
     119                 :   }
     120                 : 
     121           90491 :   tmp->OwnerDoc()->BindingManager()->Traverse(tmp, cb);
     122           90491 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     123                 : 
     124           74786 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGenericDOMDataNode)
     125           74786 :   nsINode::Unlink(tmp);
     126           74786 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
     127                 : 
     128          200531 : NS_INTERFACE_MAP_BEGIN(nsGenericDOMDataNode)
     129          200531 :   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
     130          187702 :   NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsGenericDOMDataNode)
     131          148134 :   NS_INTERFACE_MAP_ENTRY(nsIContent)
     132             180 :   NS_INTERFACE_MAP_ENTRY(nsINode)
     133             180 :   NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
     134             157 :   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsISupportsWeakReference,
     135                 :                                  new nsNodeSupportsWeakRefTearoff(this))
     136              73 :   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMXPathNSResolver,
     137                 :                                  new nsNode3Tearoff(this))
     138                 :   // nsNodeSH::PreCreate() depends on the identity pointer being the
     139                 :   // same as nsINode (which nsIContent inherits), so if you change the
     140                 :   // below line, make sure nsNodeSH::PreCreate() still does the right
     141                 :   // thing!
     142              73 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContent)
     143              73 : NS_INTERFACE_MAP_END
     144                 : 
     145          480817 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsGenericDOMDataNode)
     146          480815 : NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_DESTROY(nsGenericDOMDataNode,
     147                 :                                               nsNodeUtils::LastRelease(this))
     148                 : 
     149                 : 
     150                 : nsresult
     151             764 : nsGenericDOMDataNode::GetNodeValue(nsAString& aNodeValue)
     152                 : {
     153             764 :   return GetData(aNodeValue);
     154                 : }
     155                 : 
     156                 : nsresult
     157               5 : nsGenericDOMDataNode::SetNodeValue(const nsAString& aNodeValue)
     158                 : {
     159                 :   return SetTextInternal(0, mText.GetLength(), aNodeValue.BeginReading(),
     160               5 :                          aNodeValue.Length(), true);
     161                 : }
     162                 : 
     163                 : nsresult
     164               0 : nsGenericDOMDataNode::GetNamespaceURI(nsAString& aNamespaceURI)
     165                 : {
     166               0 :   SetDOMStringToNull(aNamespaceURI);
     167                 : 
     168               0 :   return NS_OK;
     169                 : }
     170                 : 
     171                 : nsresult
     172               0 : nsGenericDOMDataNode::GetPrefix(nsAString& aPrefix)
     173                 : {
     174               0 :   SetDOMStringToNull(aPrefix);
     175                 : 
     176               0 :   return NS_OK;
     177                 : }
     178                 : 
     179                 : nsresult
     180               0 : nsGenericDOMDataNode::IsSupported(const nsAString& aFeature,
     181                 :                                   const nsAString& aVersion,
     182                 :                                   bool* aReturn)
     183                 : {
     184                 :   return nsGenericElement::InternalIsSupported(static_cast<nsIContent*>(this),
     185               0 :                                                aFeature, aVersion, aReturn);
     186                 : }
     187                 : 
     188                 : //----------------------------------------------------------------------
     189                 : 
     190                 : // Implementation of nsIDOMCharacterData
     191                 : 
     192                 : nsresult
     193             837 : nsGenericDOMDataNode::GetData(nsAString& aData) const
     194                 : {
     195             837 :   if (mText.Is2b()) {
     196               0 :     aData.Assign(mText.Get2b(), mText.GetLength());
     197                 :   } else {
     198                 :     // Must use Substring() since nsDependentCString() requires null
     199                 :     // terminated strings.
     200                 : 
     201             837 :     const char *data = mText.Get1b();
     202                 : 
     203             837 :     if (data) {
     204             820 :       CopyASCIItoUTF16(Substring(data, data + mText.GetLength()), aData);
     205                 :     } else {
     206              17 :       aData.Truncate();
     207                 :     }
     208                 :   }
     209                 : 
     210             837 :   return NS_OK;
     211                 : }
     212                 : 
     213                 : nsresult
     214               0 : nsGenericDOMDataNode::SetData(const nsAString& aData)
     215                 : {
     216                 :   return SetTextInternal(0, mText.GetLength(), aData.BeginReading(),
     217               0 :                          aData.Length(), true);
     218                 : }
     219                 : 
     220                 : nsresult
     221              35 : nsGenericDOMDataNode::GetLength(PRUint32* aLength)
     222                 : {
     223              35 :   *aLength = mText.GetLength();
     224              35 :   return NS_OK;
     225                 : }
     226                 : 
     227                 : nsresult
     228               9 : nsGenericDOMDataNode::SubstringData(PRUint32 aStart, PRUint32 aCount,
     229                 :                                     nsAString& aReturn)
     230                 : {
     231               9 :   aReturn.Truncate();
     232                 : 
     233               9 :   PRUint32 textLength = mText.GetLength();
     234               9 :   if (aStart > textLength) {
     235               0 :     return NS_ERROR_DOM_INDEX_SIZE_ERR;
     236                 :   }
     237                 : 
     238               9 :   PRUint32 amount = aCount;
     239               9 :   if (amount > textLength - aStart) {
     240               0 :     amount = textLength - aStart;
     241                 :   }
     242                 : 
     243               9 :   if (mText.Is2b()) {
     244               0 :     aReturn.Assign(mText.Get2b() + aStart, amount);
     245                 :   } else {
     246                 :     // Must use Substring() since nsDependentCString() requires null
     247                 :     // terminated strings.
     248                 : 
     249               9 :     const char *data = mText.Get1b() + aStart;
     250               9 :     CopyASCIItoUTF16(Substring(data, data + amount), aReturn);
     251                 :   }
     252                 : 
     253               9 :   return NS_OK;
     254                 : }
     255                 : 
     256                 : //----------------------------------------------------------------------
     257                 : 
     258                 : nsresult
     259               0 : nsGenericDOMDataNode::AppendData(const nsAString& aData)
     260                 : {
     261                 :   return SetTextInternal(mText.GetLength(), 0, aData.BeginReading(),
     262               0 :                          aData.Length(), true);
     263                 : }
     264                 : 
     265                 : nsresult
     266               0 : nsGenericDOMDataNode::InsertData(PRUint32 aOffset,
     267                 :                                  const nsAString& aData)
     268                 : {
     269                 :   return SetTextInternal(aOffset, 0, aData.BeginReading(),
     270               0 :                          aData.Length(), true);
     271                 : }
     272                 : 
     273                 : nsresult
     274               9 : nsGenericDOMDataNode::DeleteData(PRUint32 aOffset, PRUint32 aCount)
     275                 : {
     276               9 :   return SetTextInternal(aOffset, aCount, nsnull, 0, true);
     277                 : }
     278                 : 
     279                 : nsresult
     280               0 : nsGenericDOMDataNode::ReplaceData(PRUint32 aOffset, PRUint32 aCount,
     281                 :                                   const nsAString& aData)
     282                 : {
     283                 :   return SetTextInternal(aOffset, aCount, aData.BeginReading(),
     284               0 :                          aData.Length(), true);
     285                 : }
     286                 : 
     287                 : nsresult
     288           74499 : nsGenericDOMDataNode::SetTextInternal(PRUint32 aOffset, PRUint32 aCount,
     289                 :                                       const PRUnichar* aBuffer,
     290                 :                                       PRUint32 aLength, bool aNotify,
     291                 :                                       CharacterDataChangeInfo::Details* aDetails)
     292                 : {
     293           74499 :   NS_PRECONDITION(aBuffer || !aLength,
     294                 :                   "Null buffer passed to SetTextInternal!");
     295                 : 
     296                 :   // sanitize arguments
     297           74499 :   PRUint32 textLength = mText.GetLength();
     298           74499 :   if (aOffset > textLength) {
     299               0 :     return NS_ERROR_DOM_INDEX_SIZE_ERR;
     300                 :   }
     301                 : 
     302           74499 :   if (aCount > textLength - aOffset) {
     303               0 :     aCount = textLength - aOffset;
     304                 :   }
     305                 : 
     306           74499 :   PRUint32 endOffset = aOffset + aCount;
     307                 : 
     308                 :   // Make sure the text fragment can hold the new data.
     309           74499 :   if (aLength > aCount && !mText.CanGrowBy(aLength - aCount)) {
     310                 :     // This exception isn't per spec, but the spec doesn't actually
     311                 :     // say what to do here.
     312                 : 
     313               0 :     return NS_ERROR_DOM_DOMSTRING_SIZE_ERR;
     314                 :   }
     315                 : 
     316           74499 :   nsIDocument *document = GetCurrentDoc();
     317          148998 :   mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
     318                 : 
     319                 :   bool haveMutationListeners = aNotify &&
     320                 :     nsContentUtils::HasMutationListeners(this,
     321                 :       NS_EVENT_BITS_MUTATION_CHARACTERDATAMODIFIED,
     322           74499 :       this);
     323                 : 
     324          148998 :   nsCOMPtr<nsIAtom> oldValue;
     325           74499 :   if (haveMutationListeners) {
     326               0 :     oldValue = GetCurrentValueAtom();
     327                 :   }
     328                 :     
     329           74499 :   if (aNotify) {
     330                 :     CharacterDataChangeInfo info = {
     331                 :       aOffset == textLength,
     332                 :       aOffset,
     333                 :       endOffset,
     334                 :       aLength,
     335                 :       aDetails
     336              32 :     };
     337              32 :     nsNodeUtils::CharacterDataWillChange(this, &info);
     338                 :   }
     339                 : 
     340           74499 :   if (aOffset == 0 && endOffset == textLength) {
     341                 :     // Replacing whole text or old text was empty.  Don't bother to check for
     342                 :     // bidi in this string if the document already has bidi enabled.
     343           74476 :     mText.SetTo(aBuffer, aLength, !document || !document->GetBidiEnabled());
     344                 :   }
     345              23 :   else if (aOffset == textLength) {
     346                 :     // Appending to existing
     347              10 :     mText.Append(aBuffer, aLength, !document || !document->GetBidiEnabled());
     348                 :   }
     349                 :   else {
     350                 :     // Merging old and new
     351                 : 
     352                 :     // Allocate new buffer
     353              13 :     PRInt32 newLength = textLength - aCount + aLength;
     354              26 :     PRUnichar* to = new PRUnichar[newLength];
     355              13 :     NS_ENSURE_TRUE(to, NS_ERROR_OUT_OF_MEMORY);
     356                 : 
     357                 :     // Copy over appropriate data
     358              13 :     if (aOffset) {
     359               9 :       mText.CopyTo(to, 0, aOffset);
     360                 :     }
     361              13 :     if (aLength) {
     362               0 :       memcpy(to + aOffset, aBuffer, aLength * sizeof(PRUnichar));
     363                 :     }
     364              13 :     if (endOffset != textLength) {
     365              11 :       mText.CopyTo(to + aOffset + aLength, endOffset, textLength - endOffset);
     366                 :     }
     367                 : 
     368                 :     // XXX Add OOM checking to this
     369              13 :     mText.SetTo(to, newLength, !document || !document->GetBidiEnabled());
     370                 : 
     371              13 :     delete [] to;
     372                 :   }
     373                 : 
     374           74499 :   if (document && mText.IsBidi()) {
     375                 :     // If we found bidi characters in mText.SetTo() above, indicate that the
     376                 :     // document contains bidi characters.
     377               0 :     document->SetBidiEnabled();
     378                 :   }
     379                 : 
     380                 :   // Notify observers
     381           74499 :   if (aNotify) {
     382                 :     CharacterDataChangeInfo info = {
     383                 :       aOffset == textLength,
     384                 :       aOffset,
     385                 :       endOffset,
     386                 :       aLength,
     387                 :       aDetails
     388              32 :     };
     389              32 :     nsNodeUtils::CharacterDataChanged(this, &info);
     390                 : 
     391              32 :     if (haveMutationListeners) {
     392               0 :       nsMutationEvent mutation(true, NS_MUTATION_CHARACTERDATAMODIFIED);
     393                 : 
     394               0 :       mutation.mPrevAttrValue = oldValue;
     395               0 :       if (aLength > 0) {
     396               0 :         nsAutoString val;
     397               0 :         mText.AppendTo(val);
     398               0 :         mutation.mNewAttrValue = do_GetAtom(val);
     399                 :       }
     400                 : 
     401               0 :       mozAutoSubtreeModified subtree(OwnerDoc(), this);
     402               0 :       (new nsAsyncDOMEvent(this, mutation))->RunDOMEventWhenSafe();
     403                 :     }
     404                 :   }
     405                 : 
     406           74499 :   return NS_OK;
     407                 : }
     408                 : 
     409                 : //----------------------------------------------------------------------
     410                 : 
     411                 : // Implementation of nsIContent
     412                 : 
     413                 : #ifdef DEBUG
     414                 : void
     415               0 : nsGenericDOMDataNode::ToCString(nsAString& aBuf, PRInt32 aOffset,
     416                 :                                 PRInt32 aLen) const
     417                 : {
     418               0 :   if (mText.Is2b()) {
     419               0 :     const PRUnichar* cp = mText.Get2b() + aOffset;
     420               0 :     const PRUnichar* end = cp + aLen;
     421                 : 
     422               0 :     while (cp < end) {
     423               0 :       PRUnichar ch = *cp++;
     424               0 :       if (ch == '&') {
     425               0 :         aBuf.AppendLiteral("&amp;");
     426               0 :       } else if (ch == '<') {
     427               0 :         aBuf.AppendLiteral("&lt;");
     428               0 :       } else if (ch == '>') {
     429               0 :         aBuf.AppendLiteral("&gt;");
     430               0 :       } else if ((ch < ' ') || (ch >= 127)) {
     431                 :         char buf[10];
     432               0 :         PR_snprintf(buf, sizeof(buf), "\\u%04x", ch);
     433               0 :         AppendASCIItoUTF16(buf, aBuf);
     434                 :       } else {
     435               0 :         aBuf.Append(ch);
     436                 :       }
     437                 :     }
     438                 :   } else {
     439               0 :     unsigned char* cp = (unsigned char*)mText.Get1b() + aOffset;
     440               0 :     const unsigned char* end = cp + aLen;
     441                 : 
     442               0 :     while (cp < end) {
     443               0 :       PRUnichar ch = *cp++;
     444               0 :       if (ch == '&') {
     445               0 :         aBuf.AppendLiteral("&amp;");
     446               0 :       } else if (ch == '<') {
     447               0 :         aBuf.AppendLiteral("&lt;");
     448               0 :       } else if (ch == '>') {
     449               0 :         aBuf.AppendLiteral("&gt;");
     450               0 :       } else if ((ch < ' ') || (ch >= 127)) {
     451                 :         char buf[10];
     452               0 :         PR_snprintf(buf, sizeof(buf), "\\u%04x", ch);
     453               0 :         AppendASCIItoUTF16(buf, aBuf);
     454                 :       } else {
     455               0 :         aBuf.Append(ch);
     456                 :       }
     457                 :     }
     458                 :   }
     459               0 : }
     460                 : #endif
     461                 : 
     462                 : 
     463                 : nsresult
     464           74006 : nsGenericDOMDataNode::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
     465                 :                                  nsIContent* aBindingParent,
     466                 :                                  bool aCompileEventHandlers)
     467                 : {
     468           74006 :   NS_PRECONDITION(aParent || aDocument, "Must have document if no parent!");
     469           74006 :   NS_PRECONDITION(HasSameOwnerDoc(NODE_FROM(aParent, aDocument)),
     470                 :                   "Must have the same owner document");
     471           74006 :   NS_PRECONDITION(!aParent || aDocument == aParent->GetCurrentDoc(),
     472                 :                   "aDocument must be current doc of aParent");
     473           74006 :   NS_PRECONDITION(!GetCurrentDoc() && !IsInDoc(),
     474                 :                   "Already have a document.  Unbind first!");
     475                 :   // Note that as we recurse into the kids, they'll have a non-null parent.  So
     476                 :   // only assert if our parent is _changing_ while we have a parent.
     477           74006 :   NS_PRECONDITION(!GetParent() || aParent == GetParent(),
     478                 :                   "Already have a parent.  Unbind first!");
     479           74006 :   NS_PRECONDITION(!GetBindingParent() ||
     480                 :                   aBindingParent == GetBindingParent() ||
     481                 :                   (!aBindingParent && aParent &&
     482                 :                    aParent->GetBindingParent() == GetBindingParent()),
     483                 :                   "Already have a binding parent.  Unbind first!");
     484           74006 :   NS_PRECONDITION(aBindingParent != this,
     485                 :                   "Content must not be its own binding parent");
     486           74006 :   NS_PRECONDITION(!IsRootOfNativeAnonymousSubtree() || 
     487                 :                   aBindingParent == aParent,
     488                 :                   "Native anonymous content must have its parent as its "
     489                 :                   "own binding parent");
     490                 : 
     491           74006 :   if (!aBindingParent && aParent) {
     492           73904 :     aBindingParent = aParent->GetBindingParent();
     493                 :   }
     494                 : 
     495                 :   // First set the binding parent
     496           74006 :   if (aBindingParent) {
     497               0 :     nsDataSlots *slots = GetDataSlots();
     498               0 :     NS_ENSURE_TRUE(slots, NS_ERROR_OUT_OF_MEMORY);
     499                 : 
     500               0 :     NS_ASSERTION(IsRootOfNativeAnonymousSubtree() ||
     501                 :                  !HasFlag(NODE_IS_IN_ANONYMOUS_SUBTREE) ||
     502                 :                  (aParent && aParent->IsInNativeAnonymousSubtree()),
     503                 :                  "Trying to re-bind content from native anonymous subtree to "
     504                 :                  "non-native anonymous parent!");
     505               0 :     slots->mBindingParent = aBindingParent; // Weak, so no addref happens.
     506               0 :     if (aParent->IsInNativeAnonymousSubtree()) {
     507               0 :       SetFlags(NODE_IS_IN_ANONYMOUS_SUBTREE);
     508                 :     }
     509                 :   }
     510                 : 
     511                 :   // Set parent
     512           74006 :   if (aParent) {
     513           73904 :     if (!GetParent()) {
     514           73897 :       NS_ADDREF(aParent);
     515                 :     }
     516           73904 :     mParent = aParent;
     517                 :   }
     518                 :   else {
     519             102 :     mParent = aDocument;
     520                 :   }
     521           74006 :   SetParentIsContent(aParent);
     522                 : 
     523                 :   // XXXbz sXBL/XBL2 issue!
     524                 : 
     525                 :   // Set document
     526           74006 :   if (aDocument) {
     527                 :     // XXX See the comment in nsGenericElement::BindToTree
     528           73458 :     SetInDocument();
     529           73458 :     if (mText.IsBidi()) {
     530               4 :       aDocument->SetBidiEnabled();
     531                 :     }
     532                 :     // Clear the lazy frame construction bits.
     533           73458 :     UnsetFlags(NODE_NEEDS_FRAME | NODE_DESCENDANTS_NEED_FRAMES);
     534                 :   }
     535                 : 
     536           74006 :   nsNodeUtils::ParentChainChanged(this);
     537                 : 
     538           74006 :   UpdateEditableState(false);
     539                 : 
     540           74006 :   NS_POSTCONDITION(aDocument == GetCurrentDoc(), "Bound to wrong document");
     541           74006 :   NS_POSTCONDITION(aParent == GetParent(), "Bound to wrong parent");
     542           74006 :   NS_POSTCONDITION(aBindingParent == GetBindingParent(),
     543                 :                    "Bound to wrong binding parent");
     544                 : 
     545           74006 :   return NS_OK;
     546                 : }
     547                 : 
     548                 : void
     549          250948 : nsGenericDOMDataNode::UnbindFromTree(bool aDeep, bool aNullParent)
     550                 : {
     551                 :   // Unset frame flags; if we need them again later, they'll get set again.
     552                 :   UnsetFlags(NS_CREATE_FRAME_IF_NON_WHITESPACE |
     553          250948 :              NS_REFRAME_IF_WHITESPACE);
     554                 :   
     555          250948 :   nsIDocument *document = GetCurrentDoc();
     556          250948 :   if (document) {
     557                 :     // Notify XBL- & nsIAnonymousContentCreator-generated
     558                 :     // anonymous content that the document is changing.
     559                 :     // This is needed to update the insertion point.
     560           73456 :     document->BindingManager()->RemovedFromDocument(this, document);
     561                 :   }
     562                 : 
     563          250948 :   if (aNullParent) {
     564           73997 :     if (GetParent()) {
     565           73895 :       NS_RELEASE(mParent);
     566                 :     } else {
     567             102 :       mParent = nsnull;
     568                 :     }
     569           73997 :     SetParentIsContent(false);
     570                 :   }
     571          250948 :   ClearInDocument();
     572                 : 
     573          250948 :   nsDataSlots *slots = GetExistingDataSlots();
     574          250948 :   if (slots) {
     575              23 :     slots->mBindingParent = nsnull;
     576                 :   }
     577                 : 
     578          250948 :   nsNodeUtils::ParentChainChanged(this);
     579          250948 : }
     580                 : 
     581                 : already_AddRefed<nsINodeList>
     582               0 : nsGenericDOMDataNode::GetChildren(PRUint32 aFilter)
     583                 : {
     584               0 :   return nsnull;
     585                 : }
     586                 : 
     587                 : nsIAtom *
     588               0 : nsGenericDOMDataNode::GetIDAttributeName() const
     589                 : {
     590               0 :   return nsnull;
     591                 : }
     592                 : 
     593                 : already_AddRefed<nsINodeInfo>
     594               0 : nsGenericDOMDataNode::GetExistingAttrNameFromQName(const nsAString& aStr) const
     595                 : {
     596               0 :   return nsnull;
     597                 : }
     598                 : 
     599                 : nsresult
     600               0 : nsGenericDOMDataNode::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttr,
     601                 :                               nsIAtom* aPrefix, const nsAString& aValue,
     602                 :                               bool aNotify)
     603                 : {
     604               0 :   return NS_OK;
     605                 : }
     606                 : 
     607                 : nsresult
     608               0 : nsGenericDOMDataNode::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttr,
     609                 :                                 bool aNotify)
     610                 : {
     611               0 :   return NS_OK;
     612                 : }
     613                 : 
     614                 : bool
     615               0 : nsGenericDOMDataNode::GetAttr(PRInt32 aNameSpaceID, nsIAtom *aAttr,
     616                 :                               nsAString& aResult) const
     617                 : {
     618               0 :   aResult.Truncate();
     619                 : 
     620               0 :   return false;
     621                 : }
     622                 : 
     623                 : bool
     624               0 : nsGenericDOMDataNode::HasAttr(PRInt32 aNameSpaceID, nsIAtom *aAttribute) const
     625                 : {
     626               0 :   return false;
     627                 : }
     628                 : 
     629                 : const nsAttrName*
     630               0 : nsGenericDOMDataNode::GetAttrNameAt(PRUint32 aIndex) const
     631                 : {
     632               0 :   return nsnull;
     633                 : }
     634                 : 
     635                 : PRUint32
     636               0 : nsGenericDOMDataNode::GetAttrCount() const
     637                 : {
     638               0 :   return 0;
     639                 : }
     640                 : 
     641                 : PRUint32
     642              12 : nsGenericDOMDataNode::GetChildCount() const
     643                 : {
     644              12 :   return 0;
     645                 : }
     646                 : 
     647                 : nsIContent *
     648               0 : nsGenericDOMDataNode::GetChildAt(PRUint32 aIndex) const
     649                 : {
     650               0 :   return nsnull;
     651                 : }
     652                 : 
     653                 : nsIContent * const *
     654               0 : nsGenericDOMDataNode::GetChildArray(PRUint32* aChildCount) const
     655                 : {
     656               0 :   *aChildCount = 0;
     657               0 :   return nsnull;
     658                 : }
     659                 : 
     660                 : PRInt32
     661               0 : nsGenericDOMDataNode::IndexOf(nsINode* aPossibleChild) const
     662                 : {
     663               0 :   return -1;
     664                 : }
     665                 : 
     666                 : nsresult
     667               0 : nsGenericDOMDataNode::InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
     668                 :                                     bool aNotify)
     669                 : {
     670               0 :   return NS_OK;
     671                 : }
     672                 : 
     673                 : nsresult
     674               0 : nsGenericDOMDataNode::RemoveChildAt(PRUint32 aIndex, bool aNotify)
     675                 : {
     676               0 :   return NS_OK;
     677                 : }
     678                 : 
     679                 : nsIContent *
     680          154595 : nsGenericDOMDataNode::GetBindingParent() const
     681                 : {
     682          154595 :   nsDataSlots *slots = GetExistingDataSlots();
     683          154595 :   return slots ? slots->mBindingParent : nsnull;
     684                 : }
     685                 : 
     686                 : bool
     687               0 : nsGenericDOMDataNode::IsNodeOfType(PRUint32 aFlags) const
     688                 : {
     689               0 :   return !(aFlags & ~(eCONTENT | eDATA_NODE));
     690                 : }
     691                 : 
     692                 : void
     693               0 : nsGenericDOMDataNode::SaveSubtreeState()
     694                 : {
     695               0 : }
     696                 : 
     697                 : void
     698               0 : nsGenericDOMDataNode::DestroyContent()
     699                 : {
     700                 :   // XXX We really should let cycle collection do this, but that currently still
     701                 :   //     leaks (see https://bugzilla.mozilla.org/show_bug.cgi?id=406684).
     702               0 :   nsContentUtils::ReleaseWrapper(this, this);
     703               0 : }
     704                 : 
     705                 : #ifdef DEBUG
     706                 : void
     707               0 : nsGenericDOMDataNode::List(FILE* out, PRInt32 aIndent) const
     708                 : {
     709               0 : }
     710                 : 
     711                 : void
     712               0 : nsGenericDOMDataNode::DumpContent(FILE* out, PRInt32 aIndent,
     713                 :                                   bool aDumpAll) const 
     714                 : {
     715               0 : }
     716                 : #endif
     717                 : 
     718                 : bool
     719               0 : nsGenericDOMDataNode::IsLink(nsIURI** aURI) const
     720                 : {
     721               0 :   *aURI = nsnull;
     722               0 :   return false;
     723                 : }
     724                 : 
     725                 : nsINode::nsSlots*
     726              23 : nsGenericDOMDataNode::CreateSlots()
     727                 : {
     728              23 :   return new nsDataSlots();
     729                 : }
     730                 : 
     731                 : //----------------------------------------------------------------------
     732                 : 
     733                 : // Implementation of the nsIDOMText interface
     734                 : 
     735                 : nsresult
     736               4 : nsGenericDOMDataNode::SplitData(PRUint32 aOffset, nsIContent** aReturn,
     737                 :                                 bool aCloneAfterOriginal)
     738                 : {
     739               4 :   *aReturn = nsnull;
     740               4 :   nsresult rv = NS_OK;
     741               8 :   nsAutoString cutText;
     742               4 :   PRUint32 length = TextLength();
     743                 : 
     744               4 :   if (aOffset > length) {
     745               0 :     return NS_ERROR_DOM_INDEX_SIZE_ERR;
     746                 :   }
     747                 : 
     748               4 :   PRUint32 cutStartOffset = aCloneAfterOriginal ? aOffset : 0;
     749               4 :   PRUint32 cutLength = aCloneAfterOriginal ? length - aOffset : aOffset;
     750               4 :   rv = SubstringData(cutStartOffset, cutLength, cutText);
     751               4 :   if (NS_FAILED(rv)) {
     752               0 :     return rv;
     753                 :   }
     754                 : 
     755               4 :   nsIDocument* document = GetCurrentDoc();
     756               8 :   mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, true);
     757                 : 
     758                 :   // Use Clone for creating the new node so that the new node is of same class
     759                 :   // as this node!
     760               8 :   nsCOMPtr<nsIContent> newContent = CloneDataNode(mNodeInfo, false);
     761               4 :   if (!newContent) {
     762               0 :     return NS_ERROR_OUT_OF_MEMORY;
     763                 :   }
     764               4 :   newContent->SetText(cutText, true); // XXX should be false?
     765                 : 
     766                 :   CharacterDataChangeInfo::Details details = {
     767                 :     CharacterDataChangeInfo::Details::eSplit, newContent
     768               4 :   };
     769                 :   rv = SetTextInternal(cutStartOffset, cutLength, nsnull, 0, true,
     770               4 :                        aCloneAfterOriginal ? &details : nsnull);
     771               4 :   if (NS_FAILED(rv)) {
     772               0 :     return rv;
     773                 :   }
     774                 : 
     775               8 :   nsCOMPtr<nsINode> parent = GetNodeParent();
     776               4 :   if (parent) {
     777               4 :     PRInt32 insertionIndex = parent->IndexOf(this);
     778               4 :     if (aCloneAfterOriginal) {
     779               2 :       ++insertionIndex;
     780                 :     }
     781               4 :     parent->InsertChildAt(newContent, insertionIndex, true);
     782                 :   }
     783                 : 
     784               4 :   newContent.swap(*aReturn);
     785               4 :   return rv;
     786                 : }
     787                 : 
     788                 : nsresult
     789               0 : nsGenericDOMDataNode::SplitText(PRUint32 aOffset, nsIDOMText** aReturn)
     790                 : {
     791               0 :   nsCOMPtr<nsIContent> newChild;
     792               0 :   nsresult rv = SplitData(aOffset, getter_AddRefs(newChild));
     793               0 :   if (NS_SUCCEEDED(rv)) {
     794               0 :     rv = CallQueryInterface(newChild, aReturn);
     795                 :   }
     796               0 :   return rv;
     797                 : }
     798                 : 
     799                 : /* static */ PRInt32
     800               0 : nsGenericDOMDataNode::FirstLogicallyAdjacentTextNode(nsIContent* aParent,
     801                 :                                                      PRInt32 aIndex)
     802                 : {
     803               0 :   while (aIndex-- > 0) {
     804               0 :     nsIContent* sibling = aParent->GetChildAt(aIndex);
     805               0 :     if (!sibling->IsNodeOfType(nsINode::eTEXT))
     806               0 :       return aIndex + 1;
     807                 :   }
     808               0 :   return 0;
     809                 : }
     810                 : 
     811                 : /* static */ PRInt32
     812               0 : nsGenericDOMDataNode::LastLogicallyAdjacentTextNode(nsIContent* aParent,
     813                 :                                                     PRInt32 aIndex,
     814                 :                                                     PRUint32 aCount)
     815                 : {
     816               0 :   while (++aIndex < PRInt32(aCount)) {
     817               0 :     nsIContent* sibling = aParent->GetChildAt(aIndex);
     818               0 :     if (!sibling->IsNodeOfType(nsINode::eTEXT))
     819               0 :       return aIndex - 1;
     820                 :   }
     821               0 :   return aCount - 1;
     822                 : }
     823                 : 
     824                 : nsresult
     825               0 : nsGenericDOMDataNode::GetWholeText(nsAString& aWholeText)
     826                 : {
     827               0 :   nsIContent* parent = GetParent();
     828                 : 
     829                 :   // Handle parent-less nodes
     830               0 :   if (!parent)
     831               0 :     return GetData(aWholeText);
     832                 : 
     833               0 :   PRInt32 index = parent->IndexOf(this);
     834               0 :   NS_WARN_IF_FALSE(index >= 0,
     835                 :                    "Trying to use .wholeText with an anonymous"
     836                 :                     "text node child of a binding parent?");
     837               0 :   NS_ENSURE_TRUE(index >= 0, NS_ERROR_DOM_NOT_SUPPORTED_ERR);
     838                 :   PRInt32 first =
     839               0 :     FirstLogicallyAdjacentTextNode(parent, index);
     840                 :   PRInt32 last =
     841               0 :     LastLogicallyAdjacentTextNode(parent, index, parent->GetChildCount());
     842                 : 
     843               0 :   aWholeText.Truncate();
     844                 : 
     845               0 :   nsCOMPtr<nsIDOMText> node;
     846               0 :   nsAutoString tmp;
     847               0 :   do {
     848               0 :     node = do_QueryInterface(parent->GetChildAt(first));
     849               0 :     node->GetData(tmp);
     850               0 :     aWholeText.Append(tmp);
     851                 :   } while (first++ < last);
     852                 : 
     853               0 :   return NS_OK;
     854                 : }
     855                 : 
     856                 : //----------------------------------------------------------------------
     857                 : 
     858                 : // Implementation of the nsIContent interface text functions
     859                 : 
     860                 : const nsTextFragment *
     861             535 : nsGenericDOMDataNode::GetText()
     862                 : {
     863             535 :   return &mText;
     864                 : }
     865                 : 
     866                 : PRUint32
     867             102 : nsGenericDOMDataNode::TextLength()
     868                 : {
     869             102 :   return mText.GetLength();
     870                 : }
     871                 : 
     872                 : nsresult
     873           74323 : nsGenericDOMDataNode::SetText(const PRUnichar* aBuffer,
     874                 :                               PRUint32 aLength,
     875                 :                               bool aNotify)
     876                 : {
     877           74323 :   return SetTextInternal(0, mText.GetLength(), aBuffer, aLength, aNotify);
     878                 : }
     879                 : 
     880                 : nsresult
     881               1 : nsGenericDOMDataNode::AppendText(const PRUnichar* aBuffer,
     882                 :                                  PRUint32 aLength,
     883                 :                                  bool aNotify)
     884                 : {
     885               1 :   return SetTextInternal(mText.GetLength(), 0, aBuffer, aLength, aNotify);
     886                 : }
     887                 : 
     888                 : bool
     889               0 : nsGenericDOMDataNode::TextIsOnlyWhitespace()
     890                 : {
     891               0 :   if (mText.Is2b()) {
     892                 :     // The fragment contains non-8bit characters and such characters
     893                 :     // are never considered whitespace.
     894               0 :     return false;
     895                 :   }
     896                 : 
     897               0 :   const char* cp = mText.Get1b();
     898               0 :   const char* end = cp + mText.GetLength();
     899                 : 
     900               0 :   while (cp < end) {
     901               0 :     char ch = *cp;
     902                 : 
     903               0 :     if (!XP_IS_SPACE(ch)) {
     904               0 :       return false;
     905                 :     }
     906                 : 
     907               0 :     ++cp;
     908                 :   }
     909                 : 
     910               0 :   return true;
     911                 : }
     912                 : 
     913                 : void
     914            8436 : nsGenericDOMDataNode::AppendTextTo(nsAString& aResult)
     915                 : {
     916            8436 :   mText.AppendTo(aResult);
     917            8436 : }
     918                 : 
     919                 : already_AddRefed<nsIAtom>
     920               0 : nsGenericDOMDataNode::GetCurrentValueAtom()
     921                 : {
     922               0 :   nsAutoString val;
     923               0 :   GetData(val);
     924               0 :   return NS_NewAtom(val);
     925                 : }
     926                 : 
     927                 : nsIAtom*
     928               0 : nsGenericDOMDataNode::DoGetID() const
     929                 : {
     930               0 :   return nsnull;
     931                 : }
     932                 : 
     933                 : const nsAttrValue*
     934               0 : nsGenericDOMDataNode::DoGetClasses() const
     935                 : {
     936               0 :   NS_NOTREACHED("Shouldn't ever be called");
     937               0 :   return nsnull;
     938                 : }
     939                 : 
     940                 : NS_IMETHODIMP
     941               0 : nsGenericDOMDataNode::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
     942                 : {
     943               0 :   return NS_OK;
     944                 : }
     945                 : 
     946                 : nsIDOMCSSStyleDeclaration*
     947               0 : nsGenericDOMDataNode::GetSMILOverrideStyle()
     948                 : {
     949               0 :   return nsnull;
     950                 : }
     951                 : 
     952                 : css::StyleRule*
     953               0 : nsGenericDOMDataNode::GetSMILOverrideStyleRule()
     954                 : {
     955               0 :   return nsnull;
     956                 : }
     957                 : 
     958                 : nsresult
     959               0 : nsGenericDOMDataNode::SetSMILOverrideStyleRule(css::StyleRule* aStyleRule,
     960                 :                                                bool aNotify)
     961                 : {
     962               0 :   NS_NOTREACHED("How come we're setting SMILOverrideStyle on a non-element?");
     963               0 :   return NS_ERROR_UNEXPECTED;
     964                 : }
     965                 : 
     966                 : css::StyleRule*
     967               0 : nsGenericDOMDataNode::GetInlineStyleRule()
     968                 : {
     969               0 :   return nsnull;
     970                 : }
     971                 : 
     972                 : NS_IMETHODIMP
     973               0 : nsGenericDOMDataNode::SetInlineStyleRule(css::StyleRule* aStyleRule,
     974                 :                                          bool aNotify)
     975                 : {
     976               0 :   NS_NOTREACHED("How come we're setting inline style on a non-element?");
     977               0 :   return NS_ERROR_UNEXPECTED;
     978                 : }
     979                 : 
     980                 : NS_IMETHODIMP_(bool)
     981               0 : nsGenericDOMDataNode::IsAttributeMapped(const nsIAtom* aAttribute) const
     982                 : {
     983               0 :   return false;
     984                 : }
     985                 : 
     986                 : nsChangeHint
     987               0 : nsGenericDOMDataNode::GetAttributeChangeHint(const nsIAtom* aAttribute,
     988                 :                                              PRInt32 aModType) const
     989                 : {
     990               0 :   NS_NOTREACHED("Shouldn't be calling this!");
     991               0 :   return nsChangeHint(0);
     992                 : }
     993                 : 
     994                 : nsIAtom*
     995               0 : nsGenericDOMDataNode::GetClassAttributeName() const
     996                 : {
     997               0 :   return nsnull;
     998                 : }
     999                 : 
    1000                 : size_t
    1001               0 : nsGenericDOMDataNode::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
    1002                 : {
    1003               0 :   size_t n = nsIContent::SizeOfExcludingThis(aMallocSizeOf);
    1004               0 :   n += mText.SizeOfExcludingThis(aMallocSizeOf);
    1005               0 :   return n;
    1006            4392 : }
    1007                 : 

Generated by: LCOV version 1.7