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
--- 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);
/**