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:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user