fixing 136944: crash typing in editor. r=fm sr=kin

git-svn-id: svn://10.0.0.236/trunk@118944 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
jfrancis%netscape.com
2002-04-13 23:54:59 +00:00
parent 57f46e6115
commit 937e3eda32
4 changed files with 157 additions and 98 deletions

View File

@@ -2337,11 +2337,14 @@ NS_IMETHODIMP nsEditor::InsertTextIntoTextNodeImpl(const nsAString& aStringToIns
listener->WillInsertText(aTextNode, aOffset, aStringToInsert);
}
}
// XXX we may not need these view batches anymore. This is handled at a higher level now I believe
BeginUpdateViewBatch();
result = Do(txn);
EndUpdateViewBatch();
mRangeUpdater.SelAdjInsertText(aTextNode, aOffset, aStringToInsert);
// let listeners know what happened
if (mActionListeners)
{
@@ -2559,6 +2562,8 @@ NS_IMETHODIMP nsEditor::DeleteText(nsIDOMCharacterData *aElement,
result = Do(txn);
mRangeUpdater.SelAdjDeleteText(aElement, aOffset, aLength);
// let listeners know what happened
if (mActionListeners)
{

View File

@@ -462,9 +462,27 @@ nsRangeUpdater::SelAdjJoinNodes(nsIDOMNode *aLeftNode,
nsresult
nsRangeUpdater::SelAdjInsertText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, const nsString &aString)
nsRangeUpdater::SelAdjInsertText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, const nsAString &aString)
{
if (mLock) return NS_OK; // lock set by Will/DidReplaceParent, etc...
if (!aTextNode) return NS_ERROR_NULL_POINTER;
PRInt32 len=aString.Length(), i, count = mArray.Count();
if (!count) return NS_OK;
nsRangeStore *item;
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(aTextNode));
if (!node) NS_ERROR_NULL_POINTER;
for (i=0; i<count; i++)
{
item = (nsRangeStore*)mArray.ElementAt(i);
if (!item) return NS_ERROR_NULL_POINTER;
if ((item->startNode.get() == node) && (item->startOffset > aOffset))
item->startOffset += len;
if ((item->endNode.get() == node) && (item->endOffset > aOffset))
item->endOffset += len;
}
return NS_OK;
}
@@ -473,6 +491,30 @@ nsresult
nsRangeUpdater::SelAdjDeleteText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, PRInt32 aLength)
{
if (mLock) return NS_OK; // lock set by Will/DidReplaceParent, etc...
if (!aTextNode) return NS_ERROR_NULL_POINTER;
PRInt32 len=0, i, count = mArray.Count();
if (!count) return NS_OK;
nsRangeStore *item;
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(aTextNode));
if (!node) NS_ERROR_NULL_POINTER;
for (i=0; i<count; i++)
{
item = (nsRangeStore*)mArray.ElementAt(i);
if (!item) return NS_ERROR_NULL_POINTER;
if ((item->startNode.get() == node) && (item->startOffset > aOffset))
{
item->startOffset -= aLength;
if (item->startOffset < 0) item->startOffset = 0;
}
if ((item->endNode.get() == node) && (item->endOffset > aOffset))
{
item->endOffset -= aLength;
if (item->endOffset < 0) item->endOffset = 0;
}
}
return NS_OK;
}

View File

@@ -116,7 +116,7 @@ class nsRangeUpdater
nsIDOMNode *aParent,
PRInt32 aOffset,
PRInt32 aOldLeftNodeLength);
nsresult SelAdjInsertText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, const nsString &aString);
nsresult SelAdjInsertText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, const nsAString &aString);
nsresult SelAdjDeleteText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, PRInt32 aLength);
// the following gravity routines need will/did sandwiches, because the other gravity
// routines will be called inside of these sandwiches, but should be ignored.

View File

@@ -221,63 +221,69 @@ nsWSRunObject::InsertBreak(nsCOMPtr<nsIDOMNode> *aInOutParent,
res = FindRun(*aInOutParent, *aInOutOffset, &beforeRun, PR_FALSE);
res = FindRun(*aInOutParent, *aInOutOffset, &afterRun, PR_TRUE);
// handle any changes needed to ws run after inserted br
if (!afterRun)
{
// dont need to do anything. just insert break. ws wont change.
}
else if (afterRun->mType & eTrailingWS)
{
// dont need to do anything. just insert break. ws wont change.
}
else if (afterRun->mType == eLeadingWS)
{
// delete the leading ws that is after insertion point. We don't
// have to (it would still not be significant after br), but it's
// just more aesthetically pleasing to.
res = DeleteChars(*aInOutParent, *aInOutOffset, afterRun->mEndNode, afterRun->mEndOffset);
NS_ENSURE_SUCCESS(res, res);
}
else if (afterRun->mType == eNormalWS)
{
// need to determine if break at front of non-nbsp run. if so
// convert run to nbsp.
WSPoint thePoint;
res = GetCharAfter(*aInOutParent, *aInOutOffset, &thePoint);
if ( (NS_SUCCEEDED(res)) && thePoint.mTextNode && (nsCRT::IsAsciiSpace(thePoint.mChar)) )
// some scoping for nsAutoTrackDOMPoint. This will track our insertion point
// while we tweak any surrounding whitespace
nsAutoTrackDOMPoint tracker(mHTMLEditor->mRangeUpdater, aInOutParent, aInOutOffset);
// handle any changes needed to ws run after inserted br
if (!afterRun)
{
WSPoint prevPoint;
res = GetCharBefore(thePoint, &prevPoint);
if ( (NS_FAILED(res)) || (prevPoint.mTextNode && !nsCRT::IsAsciiSpace(prevPoint.mChar)) )
// dont need to do anything. just insert break. ws wont change.
}
else if (afterRun->mType & eTrailingWS)
{
// dont need to do anything. just insert break. ws wont change.
}
else if (afterRun->mType == eLeadingWS)
{
// delete the leading ws that is after insertion point. We don't
// have to (it would still not be significant after br), but it's
// just more aesthetically pleasing to.
res = DeleteChars(*aInOutParent, *aInOutOffset, afterRun->mEndNode, afterRun->mEndOffset);
NS_ENSURE_SUCCESS(res, res);
}
else if (afterRun->mType == eNormalWS)
{
// need to determine if break at front of non-nbsp run. if so
// convert run to nbsp.
WSPoint thePoint;
res = GetCharAfter(*aInOutParent, *aInOutOffset, &thePoint);
if ( (NS_SUCCEEDED(res)) && thePoint.mTextNode && (nsCRT::IsAsciiSpace(thePoint.mChar)) )
{
// we are at start of non-nbsps. convert to a single nbsp.
res = ConvertToNBSP(thePoint);
NS_ENSURE_SUCCESS(res, res);
WSPoint prevPoint;
res = GetCharBefore(thePoint, &prevPoint);
if ( (NS_FAILED(res)) || (prevPoint.mTextNode && !nsCRT::IsAsciiSpace(prevPoint.mChar)) )
{
// we are at start of non-nbsps. convert to a single nbsp.
res = ConvertToNBSP(thePoint);
NS_ENSURE_SUCCESS(res, res);
}
}
}
}
// handle any changes needed to ws run before inserted br
if (!beforeRun)
{
// dont need to do anything. just insert break. ws wont change.
}
else if (beforeRun->mType & eLeadingWS)
{
// dont need to do anything. just insert break. ws wont change.
}
else if (beforeRun->mType == eTrailingWS)
{
// need to delete the trailing ws that is before insertion point, because it
// would become significant after break inserted.
res = DeleteChars(beforeRun->mStartNode, beforeRun->mStartOffset, *aInOutParent, *aInOutOffset);
NS_ENSURE_SUCCESS(res, res);
}
else if (beforeRun->mType == eNormalWS)
{
// try to change an nbsp to a space, if possible, just to prevent nbsp proliferation
res = CheckTrailingNBSP(beforeRun, *aInOutParent, *aInOutOffset);
NS_ENSURE_SUCCESS(res, res);
// handle any changes needed to ws run before inserted br
if (!beforeRun)
{
// dont need to do anything. just insert break. ws wont change.
}
else if (beforeRun->mType & eLeadingWS)
{
// dont need to do anything. just insert break. ws wont change.
}
else if (beforeRun->mType == eTrailingWS)
{
// need to delete the trailing ws that is before insertion point, because it
// would become significant after break inserted.
res = DeleteChars(beforeRun->mStartNode, beforeRun->mStartOffset, *aInOutParent, *aInOutOffset);
NS_ENSURE_SUCCESS(res, res);
}
else if (beforeRun->mType == eNormalWS)
{
// try to change an nbsp to a space, if possible, just to prevent nbsp proliferation
res = CheckTrailingNBSP(beforeRun, *aInOutParent, *aInOutOffset);
NS_ENSURE_SUCCESS(res, res);
}
}
// ready, aim, fire!
@@ -310,50 +316,56 @@ nsWSRunObject::InsertText(const nsAString& aStringToInsert,
res = FindRun(*aInOutParent, *aInOutOffset, &beforeRun, PR_FALSE);
res = FindRun(*aInOutParent, *aInOutOffset, &afterRun, PR_TRUE);
// handle any changes needed to ws run after inserted text
if (!afterRun)
{
// dont need to do anything. just insert text. ws wont change.
}
else if (afterRun->mType & eTrailingWS)
{
// dont need to do anything. just insert text. ws wont change.
}
else if (afterRun->mType == eLeadingWS)
{
// delete the leading ws that is after insertion point, because it
// would become significant after text inserted.
res = DeleteChars(*aInOutParent, *aInOutOffset, afterRun->mEndNode, afterRun->mEndOffset);
NS_ENSURE_SUCCESS(res, res);
}
else if (afterRun->mType == eNormalWS)
{
// try to change an nbsp to a space, if possible, just to prevent nbsp proliferation
res = CheckLeadingNBSP(afterRun, *aInOutParent, *aInOutOffset);
NS_ENSURE_SUCCESS(res, res);
}
// handle any changes needed to ws run before inserted text
if (!beforeRun)
{
// dont need to do anything. just insert text. ws wont change.
}
else if (beforeRun->mType & eLeadingWS)
{
// dont need to do anything. just insert text. ws wont change.
}
else if (beforeRun->mType == eTrailingWS)
{
// need to delete the trailing ws that is before insertion point, because it
// would become significant after text inserted.
res = DeleteChars(beforeRun->mStartNode, beforeRun->mStartOffset, *aInOutParent, *aInOutOffset);
NS_ENSURE_SUCCESS(res, res);
}
else if (beforeRun->mType == eNormalWS)
{
// try to change an nbsp to a space, if possible, just to prevent nbsp proliferation
res = CheckTrailingNBSP(beforeRun, *aInOutParent, *aInOutOffset);
NS_ENSURE_SUCCESS(res, res);
// some scoping for nsAutoTrackDOMPoint. This will track our insertion point
// while we tweak any surrounding whitespace
nsAutoTrackDOMPoint tracker(mHTMLEditor->mRangeUpdater, aInOutParent, aInOutOffset);
// handle any changes needed to ws run after inserted text
if (!afterRun)
{
// dont need to do anything. just insert text. ws wont change.
}
else if (afterRun->mType & eTrailingWS)
{
// dont need to do anything. just insert text. ws wont change.
}
else if (afterRun->mType == eLeadingWS)
{
// delete the leading ws that is after insertion point, because it
// would become significant after text inserted.
res = DeleteChars(*aInOutParent, *aInOutOffset, afterRun->mEndNode, afterRun->mEndOffset);
NS_ENSURE_SUCCESS(res, res);
}
else if (afterRun->mType == eNormalWS)
{
// try to change an nbsp to a space, if possible, just to prevent nbsp proliferation
res = CheckLeadingNBSP(afterRun, *aInOutParent, *aInOutOffset);
NS_ENSURE_SUCCESS(res, res);
}
// handle any changes needed to ws run before inserted text
if (!beforeRun)
{
// dont need to do anything. just insert text. ws wont change.
}
else if (beforeRun->mType & eLeadingWS)
{
// dont need to do anything. just insert text. ws wont change.
}
else if (beforeRun->mType == eTrailingWS)
{
// need to delete the trailing ws that is before insertion point, because it
// would become significant after text inserted.
res = DeleteChars(beforeRun->mStartNode, beforeRun->mStartOffset, *aInOutParent, *aInOutOffset);
NS_ENSURE_SUCCESS(res, res);
}
else if (beforeRun->mType == eNormalWS)
{
// try to change an nbsp to a space, if possible, just to prevent nbsp proliferation
res = CheckTrailingNBSP(beforeRun, *aInOutParent, *aInOutOffset);
NS_ENSURE_SUCCESS(res, res);
}
}
// next up, tweak head and tail of string as needed.