Bug 1467802 - part 4: Create TextEditor::ComputeValueInternal() for internal use of nsIPlaintextEditor::OutputToString() r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Wed, 18 Jul 2018 21:27:30 +0900
changeset 820224 089f2163463146aca58abc5e7f15ad289a849386
parent 820223 32117d853d7551b912c72da20dc00975b18999b3
child 820239 3d6bc34b5042e6cda4b72e95b86f6298628fdf87
push id116753
push usermasayuki@d-toybox.com
push dateThu, 19 Jul 2018 06:22:48 +0000
reviewersm_kato
bugs1467802
milestone63.0a1
Bug 1467802 - part 4: Create TextEditor::ComputeValueInternal() for internal use of nsIPlaintextEditor::OutputToString() r?m_kato For reducing virtual calls of nsIPlaintextEditor::OutputToString(), TextEditor should have new non-virtual public method, ComputeTextValue() and shared code between it and OutputToString() as ComputeValueInternal(). MozReview-Commit-ID: KFeovQ568bf
dom/html/nsTextEditorState.cpp
editor/libeditor/TextEditor.cpp
editor/libeditor/TextEditor.h
--- a/dom/html/nsTextEditorState.cpp
+++ b/dom/html/nsTextEditorState.cpp
@@ -2216,18 +2216,18 @@ nsTextEditorState::GetValue(nsAString& a
     // has to be going through some scriptable object to do that and that
     // already does the relevant security checks.
     // XXXbz if we could just get the textContent of our anonymous content (eg
     // if plaintext editor didn't create <br> nodes all over), we wouldn't need
     // this.
     { /* Scope for AutoNoJSAPI. */
       AutoNoJSAPI nojsapi;
 
-      mTextEditor->OutputToString(NS_LITERAL_STRING("text/plain"), flags,
-                                  aValue);
+      DebugOnly<nsresult> rv = mTextEditor->ComputeTextValue(flags, aValue);
+      NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to get value");
     }
     // Only when the result doesn't include line breaks caused by hard-wrap,
     // mCacheValue should cache the value.
     if (!(flags & nsIDocumentEncoder::OutputWrap)) {
       mBoundFrame->CacheValue(aValue);
     } else {
       mBoundFrame->ClearCachedValue();
     }
--- a/editor/libeditor/TextEditor.cpp
+++ b/editor/libeditor/TextEditor.cpp
@@ -1781,25 +1781,34 @@ TextEditor::GetAndInitDocEncoder(const n
     }
   }
 
   return docEncoder.forget();
 }
 
 NS_IMETHODIMP
 TextEditor::OutputToString(const nsAString& aFormatType,
-                           uint32_t aFlags,
+                           uint32_t aDocumentEncoderFlags,
                            nsAString& aOutputString)
 {
+  return ComputeValueInternal(aFormatType, aDocumentEncoderFlags,
+                              aOutputString);
+}
+
+nsresult
+TextEditor::ComputeValueInternal(const nsAString& aFormatType,
+                                 uint32_t aDocumentEncoderFlags,
+                                 nsAString& aOutputString) const
+{
   // Protect the edit rules object from dying
   RefPtr<TextEditRules> rules(mRules);
 
   EditSubActionInfo subActionInfo(EditSubAction::eComputeTextToOutput);
   subActionInfo.outString = &aOutputString;
-  subActionInfo.flags = aFlags;
+  subActionInfo.flags = aDocumentEncoderFlags;
   subActionInfo.outputFormat = &aFormatType;
   Selection* selection = GetSelection();
   if (NS_WARN_IF(!selection)) {
     return NS_ERROR_FAILURE;
   }
   bool cancel, handled;
   nsresult rv =
     rules->WillDoAction(selection, subActionInfo, &cancel, &handled);
@@ -1813,17 +1822,17 @@ TextEditor::OutputToString(const nsAStri
 
   nsAutoCString charset;
   rv = GetDocumentCharsetInternal(charset);
   if (NS_FAILED(rv) || charset.IsEmpty()) {
     charset.AssignLiteral("windows-1252");
   }
 
   nsCOMPtr<nsIDocumentEncoder> encoder =
-    GetAndInitDocEncoder(aFormatType, aFlags, charset);
+    GetAndInitDocEncoder(aFormatType, aDocumentEncoderFlags, charset);
   if (NS_WARN_IF(!encoder)) {
     return NS_ERROR_FAILURE;
   }
 
   // XXX Why don't we call TextEditRules::DidDoAction() here?
   return encoder->EncodeToString(aOutputString);
 }
 
@@ -1954,18 +1963,17 @@ TextEditor::SharedOutputString(uint32_t 
   NS_ENSURE_TRUE(selection, NS_ERROR_NOT_INITIALIZED);
 
   *aIsCollapsed = selection->IsCollapsed();
 
   if (!*aIsCollapsed) {
     aFlags |= nsIDocumentEncoder::OutputSelectionOnly;
   }
   // If the selection isn't collapsed, we'll use the whole document.
-
-  return OutputToString(NS_LITERAL_STRING("text/plain"), aFlags, aResult);
+  return ComputeValueInternal(NS_LITERAL_STRING("text/plain"), aFlags, aResult);
 }
 
 NS_IMETHODIMP
 TextEditor::Rewrap(bool aRespectNewlines)
 {
   // Rewrap makes no sense if there's no wrap column; default to 72.
   int32_t wrapWidth = WrapWidth();
   if (wrapWidth <= 0) {
--- a/editor/libeditor/TextEditor.h
+++ b/editor/libeditor/TextEditor.h
@@ -185,16 +185,30 @@ public:
   void OnCompositionEnd(WidgetCompositionEvent& aCompositionEndEvent);
 
   /**
    * OnDrop() is called from EditorEventListener::Drop that is handler of drop
    * event.
    */
   nsresult OnDrop(dom::DragEvent* aDropEvent);
 
+  /**
+   * ComputeTextValue() computes plaintext value of this editor.  This may be
+   * too expensive if it's in hot path.
+   *
+   * @param aDocumentEncoderFlags   Flags of nsIDocumentEncoder.
+   * @param aCharset                Encoding of the document.
+   */
+  nsresult ComputeTextValue(uint32_t aDocumentEncoderFlags,
+                            nsAString& aOutputString) const
+  {
+    return ComputeValueInternal(NS_LITERAL_STRING("text/plain"),
+                                aDocumentEncoderFlags, aOutputString);
+  }
+
 protected: // May be called by friends.
   /****************************************************************************
    * Some classes like TextEditRules, HTMLEditRules, WSRunObject which are
    * part of handling edit actions are allowed to call the following protected
    * methods.  However, those methods won't prepare caches of some objects
    * which are necessary for them.  So, if you want some following methods
    * to do that for you, you need to create a wrapper method in public scope
    * and call it.
@@ -337,16 +351,28 @@ protected: // Shouldn't be used by frien
    * @param aCharset                Encoding of the document.
    */
   already_AddRefed<nsIDocumentEncoder>
   GetAndInitDocEncoder(const nsAString& aFormatType,
                        uint32_t aDocumentEncoderFlags,
                        const nsACString& aCharset) const;
 
   /**
+   * ComputeValueInternal() computes string value of this editor for given
+   * format.  This may be too expensive if it's in hot path.
+   *
+   * @param aFormatType             MIME type like "text/plain".
+   * @param aDocumentEncoderFlags   Flags of nsIDocumentEncoder.
+   * @param aCharset                Encoding of the document.
+   */
+  nsresult ComputeValueInternal(const nsAString& aFormatType,
+                                uint32_t aDocumentEncoderFlags,
+                                nsAString& aOutputString) const;
+
+  /**
    * Factored methods for handling insertion of data from transferables
    * (drag&drop or clipboard).
    */
   virtual nsresult PrepareTransferable(nsITransferable** transferable);
 
   nsresult InsertTextFromTransferable(nsITransferable* transferable);
 
   /**