Bug 1446533 part 4. Remove nsIDOMCharacterData::SubstringData. r=mystor
authorBoris Zbarsky <bzbarsky@mit.edu>
Mon, 19 Mar 2018 15:18:07 -0400
changeset 408819 0cd517334cd515e4fb3c07409c4fcf1293b487b0
parent 408818 e43988b4ba26410a0d6f1a9969364074833458ed
child 408820 87162a82c06235c8b42a7d248bb22e5ee5d06fb9
push id101056
push userbzbarsky@mozilla.com
push dateMon, 19 Mar 2018 19:51:43 +0000
treeherdermozilla-inbound@1a0cc5a0be89 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmystor
bugs1446533, 1447098
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1446533 part 4. Remove nsIDOMCharacterData::SubstringData. r=mystor FromContent will be renamed to FromNode in bug 1447098. MozReview-Commit-ID: DhiN6mCOb34
dom/base/CharacterData.cpp
dom/base/CharacterData.h
dom/base/nsDocumentEncoder.cpp
dom/base/nsIContent.h
dom/base/nsINode.h
dom/base/nsRange.cpp
dom/interfaces/core/nsIDOMCharacterData.idl
editor/libeditor/DeleteTextTransaction.cpp
editor/libeditor/EditorBase.cpp
--- a/dom/base/CharacterData.cpp
+++ b/dom/base/CharacterData.cpp
@@ -186,25 +186,16 @@ CharacterData::SetData(const nsAString& 
 
 nsresult
 CharacterData::GetLength(uint32_t* aLength)
 {
   *aLength = mText.GetLength();
   return NS_OK;
 }
 
-nsresult
-CharacterData::SubstringData(uint32_t aStart, uint32_t aCount,
-                             nsAString& aReturn)
-{
-  ErrorResult rv;
-  SubstringData(aStart, aCount, aReturn, rv);
-  return rv.StealNSResult();
-}
-
 void
 CharacterData::SubstringData(uint32_t aStart, uint32_t aCount,
                              nsAString& aReturn, ErrorResult& rv)
 {
   aReturn.Truncate();
 
   uint32_t textLength = mText.GetLength();
   if (aStart > textLength) {
--- a/dom/base/CharacterData.h
+++ b/dom/base/CharacterData.h
@@ -84,24 +84,24 @@ public:
   explicit CharacterData(already_AddRefed<dom::NodeInfo>& aNodeInfo);
   explicit CharacterData(already_AddRefed<dom::NodeInfo>&& aNodeInfo);
 
   void MarkAsMaybeModifiedFrequently()
   {
     SetFlags(NS_MAYBE_MODIFIED_FREQUENTLY);
   }
 
+  NS_IMPL_FROMCONTENT_HELPER(CharacterData, IsCharacterData())
+
   virtual void GetNodeValueInternal(nsAString& aNodeValue) override;
   virtual void SetNodeValueInternal(const nsAString& aNodeValue,
                                     ErrorResult& aError) override;
 
   // Implementation for nsIDOMCharacterData
   nsresult GetLength(uint32_t* aLength);
-  nsresult SubstringData(uint32_t aOffset, uint32_t aCount,
-                         nsAString& aReturn);
   nsresult AppendData(const nsAString& aArg);
   nsresult InsertData(uint32_t aOffset, const nsAString& aArg);
   nsresult DeleteData(uint32_t aOffset, uint32_t aCount);
   nsresult ReplaceData(uint32_t aOffset, uint32_t aCount,
                        const nsAString& aArg);
 
   // nsINode methods
   virtual uint32_t GetChildCount() const override;
--- a/dom/base/nsDocumentEncoder.cpp
+++ b/dom/base/nsDocumentEncoder.cpp
@@ -41,16 +41,17 @@
 #include "nsTArray.h"
 #include "nsIFrame.h"
 #include "nsStringBuffer.h"
 #include "mozilla/dom/Comment.h"
 #include "mozilla/dom/DocumentType.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/ProcessingInstruction.h"
 #include "mozilla/dom/ShadowRoot.h"
+#include "mozilla/dom/Text.h"
 #include "nsLayoutUtils.h"
 #include "mozilla/ScopeExit.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 nsresult NS_NewDomSelection(nsISelection **aDomSelection);
 
@@ -1594,27 +1595,26 @@ nsHTMLCopyEncoder::GetPromotedPoint(Endp
 
   if (common == node)
     return NS_OK;
 
   if (aWhere == kStart)
   {
     // some special casing for text nodes
     nsCOMPtr<nsINode> t = do_QueryInterface(aNode);
-    if (IsTextNode(t))
+    if (auto nodeAsText = t->GetAsText())
     {
       // if not at beginning of text node, we are done
       if (offset >  0)
       {
         // unless everything before us in just whitespace.  NOTE: we need a more
         // general solution that truly detects all cases of non-significant
         // whitesace with no false alarms.
-        nsCOMPtr<nsIDOMCharacterData> nodeAsText = do_QueryInterface(aNode);
         nsAutoString text;
-        nodeAsText->SubstringData(0, offset, text);
+        nodeAsText->SubstringData(0, offset, text, IgnoreErrors());
         text.CompressWhitespace();
         if (!text.IsEmpty())
           return NS_OK;
         bResetPromotion = true;
       }
       // else
       rv = GetNodeLocation(aNode, address_of(parent), &offset);
       NS_ENSURE_SUCCESS(rv, rv);
@@ -1670,28 +1670,27 @@ nsHTMLCopyEncoder::GetPromotedPoint(Endp
       return rv;
     }
   }
 
   if (aWhere == kEnd)
   {
     // some special casing for text nodes
     nsCOMPtr<nsINode> n = do_QueryInterface(aNode);
-    if (IsTextNode(n))
+    if (auto nodeAsText = n->GetAsText())
     {
       // if not at end of text node, we are done
       uint32_t len = n->Length();
       if (offset < (int32_t)len)
       {
         // unless everything after us in just whitespace.  NOTE: we need a more
         // general solution that truly detects all cases of non-significant
         // whitespace with no false alarms.
-        nsCOMPtr<nsIDOMCharacterData> nodeAsText = do_QueryInterface(aNode);
         nsAutoString text;
-        nodeAsText->SubstringData(offset, len-offset, text);
+        nodeAsText->SubstringData(offset, len-offset, text, IgnoreErrors());
         text.CompressWhitespace();
         if (!text.IsEmpty())
           return NS_OK;
         bResetPromotion = true;
       }
       rv = GetNodeLocation(aNode, address_of(parent), &offset);
       NS_ENSURE_SUCCESS(rv, rv);
     }
--- a/dom/base/nsIContent.h
+++ b/dom/base/nsIContent.h
@@ -1004,29 +1004,29 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIContent
 
 inline nsIContent* nsINode::AsContent()
 {
   MOZ_ASSERT(IsContent());
   return static_cast<nsIContent*>(this);
 }
 
 #define NS_IMPL_FROMCONTENT_HELPER(_class, _check)                             \
-  static _class* FromContent(nsIContent* aContent)                             \
+  static _class* FromContent(nsINode* aContent)                                \
   {                                                                            \
     return aContent->_check ? static_cast<_class*>(aContent) : nullptr;        \
   }                                                                            \
-  static const _class* FromContent(const nsIContent* aContent)                 \
+  static const _class* FromContent(const nsINode* aContent)                    \
   {                                                                            \
     return aContent->_check ? static_cast<const _class*>(aContent) : nullptr;  \
   }                                                                            \
-  static _class* FromContentOrNull(nsIContent* aContent)                       \
+  static _class* FromContentOrNull(nsINode* aContent)                          \
   {                                                                            \
     return aContent ? FromContent(aContent) : nullptr;                         \
   }                                                                            \
-  static const _class* FromContentOrNull(const nsIContent* aContent)           \
+  static const _class* FromContentOrNull(const nsINode* aContent)              \
   {                                                                            \
     return aContent ? FromContent(aContent) : nullptr;                         \
   }
 
 #define NS_IMPL_FROMCONTENT(_class, _nsid)                                     \
   NS_IMPL_FROMCONTENT_HELPER(_class, IsInNamespace(_nsid))
 
 #define NS_IMPL_FROMCONTENT_WITH_TAG(_class, _nsid, _tag)                      \
--- a/dom/base/nsINode.h
+++ b/dom/base/nsINode.h
@@ -518,16 +518,29 @@ public:
   /*
    * Return whether the node is a ProcessingInstruction node.
    */
   bool IsProcessingInstruction() const
   {
     return NodeType() == PROCESSING_INSTRUCTION_NODE;
   }
 
+  /*
+   * Return whether the node is a CharacterData node (text, cdata,
+   * comment, processing instruction)
+   */
+  bool IsCharacterData() const
+  {
+    uint32_t nodeType = NodeType();
+    return nodeType == TEXT_NODE ||
+           nodeType == CDATA_SECTION_NODE ||
+           nodeType == PROCESSING_INSTRUCTION_NODE ||
+           nodeType == COMMENT_NODE;
+  }
+
   virtual nsIDOMNode* AsDOMNode() = 0;
 
   /**
    * Return if this node has any children.
    */
   bool HasChildren() const { return !!mFirstChild; }
 
   /**
--- a/dom/base/nsRange.cpp
+++ b/dom/base/nsRange.cpp
@@ -2284,37 +2284,37 @@ nsRange::CutContents(DocumentFragment** 
     handled = false;
 
     // If it's CharacterData, make sure we might need to delete
     // part of the data, instead of removing the whole node.
     //
     // XXX_kin: We need to also handle ProcessingInstruction
     // XXX_kin: according to the spec.
 
-    nsCOMPtr<nsIDOMCharacterData> charData(do_QueryInterface(node));
-
-    if (charData)
+    if (auto charData = CharacterData::FromContent(node))
     {
       uint32_t dataLength = 0;
 
       if (node == startContainer)
       {
         if (node == endContainer)
         {
           // This range is completely contained within a single text node.
           // Delete or extract the data between startOffset and endOffset.
 
           if (endOffset > startOffset)
           {
             if (retval) {
               nsAutoString cutValue;
-              rv = charData->SubstringData(startOffset, endOffset - startOffset,
-                                           cutValue);
-              NS_ENSURE_SUCCESS(rv, rv);
               ErrorResult err;
+              charData->SubstringData(startOffset, endOffset - startOffset,
+                                      cutValue, err);
+              if (NS_WARN_IF(err.Failed())) {
+                return err.StealNSResult();
+              }
               nsCOMPtr<nsINode> clone = node->CloneNode(false, err);
               if (NS_WARN_IF(err.Failed())) {
                 return err.StealNSResult();
               }
               clone->SetNodeValue(cutValue, err);
               if (NS_WARN_IF(err.Failed())) {
                 return err.StealNSResult();
               }
@@ -2335,19 +2335,21 @@ nsRange::CutContents(DocumentFragment** 
           // Delete or extract everything after startOffset.
 
           rv = charData->GetLength(&dataLength);
           NS_ENSURE_SUCCESS(rv, rv);
 
           if (dataLength >= startOffset) {
             if (retval) {
               nsAutoString cutValue;
-              rv = charData->SubstringData(startOffset, dataLength, cutValue);
-              NS_ENSURE_SUCCESS(rv, rv);
               ErrorResult err;
+              charData->SubstringData(startOffset, dataLength, cutValue, err);
+              if (NS_WARN_IF(err.Failed())) {
+                return err.StealNSResult();
+              }
               nsCOMPtr<nsINode> clone = node->CloneNode(false, err);
               if (NS_WARN_IF(err.Failed())) {
                 return err.StealNSResult();
               }
               clone->SetNodeValue(cutValue, err);
               if (NS_WARN_IF(err.Failed())) {
                 return err.StealNSResult();
               }
@@ -2364,19 +2366,21 @@ nsRange::CutContents(DocumentFragment** 
           handled = true;
         }
       }
       else if (node == endContainer)
       {
         // Delete or extract everything before endOffset.
         if (retval) {
           nsAutoString cutValue;
-          rv = charData->SubstringData(0, endOffset, cutValue);
-          NS_ENSURE_SUCCESS(rv, rv);
           ErrorResult err;
+          charData->SubstringData(0, endOffset, cutValue, err);
+          if (NS_WARN_IF(err.Failed())) {
+            return err.StealNSResult();
+          }
           nsCOMPtr<nsINode> clone = node->CloneNode(false, err);
           if (NS_WARN_IF(err.Failed())) {
             return err.StealNSResult();
           }
           clone->SetNodeValue(cutValue, err);
           if (NS_WARN_IF(err.Failed())) {
             return err.StealNSResult();
           }
--- a/dom/interfaces/core/nsIDOMCharacterData.idl
+++ b/dom/interfaces/core/nsIDOMCharacterData.idl
@@ -12,19 +12,16 @@
  * For more information on this interface please see 
  * http://www.w3.org/TR/DOM-Level-2-Core/
  */
 
 [uuid(4109a2d2-e7af-445d-bb72-c7c9b875f35e)]
 interface nsIDOMCharacterData : nsIDOMNode
 {
   readonly attribute unsigned long        length;
-  DOMString                 substringData(in unsigned long offset, 
-                                          in unsigned long count)
-                                  raises(DOMException);
   void                      appendData(in DOMString arg)
                                   raises(DOMException);
   void                      insertData(in unsigned long offset, 
                                        in DOMString arg)
                                   raises(DOMException);
   void                      deleteData(in unsigned long offset, 
                                        in unsigned long count)
                                   raises(DOMException);
--- a/editor/libeditor/DeleteTextTransaction.cpp
+++ b/editor/libeditor/DeleteTextTransaction.cpp
@@ -118,22 +118,25 @@ DeleteTextTransaction::CanDoIt() const
 NS_IMETHODIMP
 DeleteTextTransaction::DoTransaction()
 {
   if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mCharData)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   // Get the text that we're about to delete
-  nsresult rv = mCharData->SubstringData(mOffset, mLengthToDelete,
-                                         mDeletedText);
-  MOZ_ASSERT(NS_SUCCEEDED(rv));
-  rv = mCharData->DeleteData(mOffset, mLengthToDelete);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
+  ErrorResult err;
+  mCharData->SubstringData(mOffset, mLengthToDelete, mDeletedText, err);
+  if (NS_WARN_IF(err.Failed())) {
+    return err.StealNSResult();
+  }
+
+  mCharData->DeleteData(mOffset, mLengthToDelete, err);
+  if (NS_WARN_IF(err.Failed())) {
+    return err.StealNSResult();
   }
 
   mEditorBase->RangeUpdaterRef().
                  SelAdjDeleteText(mCharData, mOffset, mLengthToDelete);
 
   // Only set selection to deletion point if editor gives permission
   if (mEditorBase->GetShouldTxnSetSelection()) {
     RefPtr<Selection> selection = mEditorBase->GetSelection();
--- a/editor/libeditor/EditorBase.cpp
+++ b/editor/libeditor/EditorBase.cpp
@@ -3216,17 +3216,17 @@ EditorBase::SplitNodeImpl(const EditorDO
   if (!aStartOfRightNode.IsStartOfContainer()) {
     // If it's a text node, just shuffle around some text
     Text* rightAsText = aStartOfRightNode.GetContainerAsText();
     Text* leftAsText = aNewLeftNode.GetAsText();
     if (rightAsText && leftAsText) {
       // Fix right node
       nsAutoString leftText;
       rightAsText->SubstringData(0, aStartOfRightNode.Offset(),
-                                 leftText);
+                                 leftText, IgnoreErrors());
       rightAsText->DeleteData(0, aStartOfRightNode.Offset());
       // Fix left node
       leftAsText->GetAsText()->SetData(leftText, IgnoreErrors());
     } else {
       MOZ_DIAGNOSTIC_ASSERT(!rightAsText && !leftAsText);
       // Otherwise it's an interior node, so shuffle around the children. Go
       // through list backwards so deletes don't interfere with the iteration.
       if (!firstChildOfRightNode) {