Bug 1409520 - part 1: WSRunObject::InsertText() should update aInOutChildAtOffset after it might be modified r?m_kato
WSRunObject::InsertText() may delete given child node at offset with calling
DeleteChars() or CheckLeadingNBSP() before calling HTMLEditor::InsertTextImpl().
Therefore, even though using nsINode::GetChildAt() is slow, it needs to update
aInOutChildAtOffset after calling them.
MozReview-Commit-ID: AbTTfNAjMIK
--- a/editor/libeditor/WSRunObject.cpp
+++ b/editor/libeditor/WSRunObject.cpp
@@ -259,48 +259,67 @@ WSRunObject::InsertText(const nsAString&
FindRun(*aInOutParent, *aInOutOffset, &afterRun, true);
{
// Some scoping for AutoTrackDOMPoint. This will track our insertion
// point while we tweak any surrounding whitespace
AutoTrackDOMPoint tracker(mHTMLEditor->mRangeUpdater, aInOutParent,
aInOutOffset);
+ bool maybeModified = false;
// Handle any changes needed to ws run after inserted text
if (!afterRun || afterRun->mType & WSType::trailingWS) {
// Don't need to do anything. Just insert text. ws won't change.
} else if (afterRun->mType & WSType::leadingWS) {
// Delete the leading ws that is after insertion point, because it
// would become significant after text inserted.
nsresult rv =
DeleteChars(*aInOutParent, *aInOutOffset, afterRun->mEndNode,
afterRun->mEndOffset);
NS_ENSURE_SUCCESS(rv, rv);
+ maybeModified = true;
} else if (afterRun->mType == WSType::normalWS) {
// Try to change an nbsp to a space, if possible, just to prevent nbsp
// proliferation
nsresult rv = CheckLeadingNBSP(afterRun, *aInOutParent, *aInOutOffset);
NS_ENSURE_SUCCESS(rv, rv);
+ maybeModified = true;
}
// Handle any changes needed to ws run before inserted text
if (!beforeRun || beforeRun->mType & WSType::leadingWS) {
// Don't need to do anything. Just insert text. ws won't change.
} else if (beforeRun->mType & WSType::trailingWS) {
// Need to delete the trailing ws that is before insertion point, because
// it would become significant after text inserted.
nsresult rv =
DeleteChars(beforeRun->mStartNode, beforeRun->mStartOffset,
*aInOutParent, *aInOutOffset);
NS_ENSURE_SUCCESS(rv, rv);
+ maybeModified = true;
} else if (beforeRun->mType == WSType::normalWS) {
// Try to change an nbsp to a space, if possible, just to prevent nbsp
// proliferation
nsresult rv = CheckTrailingNBSP(beforeRun, *aInOutParent, *aInOutOffset);
NS_ENSURE_SUCCESS(rv, rv);
+ maybeModified = true;
+ }
+
+ // The child node may be changed. So, even though getting child at offset
+ // is expensive, we need to do it here.
+ if (maybeModified) {
+ if ((*aInOutParent)->HasChildren()) {
+ if (*aInOutOffset == 0) {
+ *aInOutChildAtOffset = (*aInOutParent)->GetFirstChild();
+ } else {
+ *aInOutChildAtOffset = (*aInOutParent)->GetChildAt(*aInOutOffset);
+ }
+ } else {
+ *aInOutChildAtOffset = nullptr;
+ }
}
}
// Next up, tweak head and tail of string as needed. First the head: there
// are a variety of circumstances that would require us to convert a leading
// ws char into an nbsp:
if (nsCRT::IsAsciiSpace(theString[0])) {