Fix for bug 21346.

This is actually a major reworking of how the low level editor txns perturb selection.  There is a mode now for telling the txns not to disturb the selection.  There is also a fix for unlisting lists (sometimes list items got merged unintentionally when unlisting).


git-svn-id: svn://10.0.0.236/trunk@56714 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
jfrancis%netscape.com
2000-01-04 03:09:41 +00:00
parent adf7e5ae40
commit 11faed23b2
35 changed files with 795 additions and 512 deletions

View File

@@ -64,7 +64,7 @@ InsertTextTxn::~InsertTextTxn()
NS_IMETHODIMP InsertTextTxn::Init(nsIDOMCharacterData *aElement,
PRUint32 aOffset,
const nsString &aStringToInsert,
nsWeakPtr aPresShellWeak)
nsIEditor *aEditor)
{
#if 0 //def DEBUG_cmanske
nsAutoString text;
@@ -74,58 +74,54 @@ NS_IMETHODIMP InsertTextTxn::Init(nsIDOMCharacterData *aElement,
printf("\n");
#endif
NS_ASSERTION(aElement && aPresShellWeak, "bad args");
if (!aElement || !aPresShellWeak) return NS_ERROR_NULL_POINTER;
NS_ASSERTION(aElement && aEditor, "bad args");
if (!aElement || !aEditor) return NS_ERROR_NULL_POINTER;
mElement = do_QueryInterface(aElement);
mOffset = aOffset;
mStringToInsert = aStringToInsert;
mPresShellWeak = aPresShellWeak;
mEditor = aEditor;
return NS_OK;
}
NS_IMETHODIMP InsertTextTxn::Do(void)
{
if (gNoisy) { printf("Do Insert Text element = %p\n", mElement.get()); }
NS_ASSERTION(mElement && mPresShellWeak, "bad state");
if (!mElement || !mPresShellWeak) { return NS_ERROR_NOT_INITIALIZED; }
nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
if (!ps) return NS_ERROR_NOT_INITIALIZED;
NS_ASSERTION(mElement && mEditor, "bad state");
if (!mElement || !mEditor) { return NS_ERROR_NOT_INITIALIZED; }
// advance caret: This requires the presentation shell to get the selection.
nsCOMPtr<nsIDOMSelection> selection;
nsresult result = ps->GetSelection(SELECTION_NORMAL, getter_AddRefs(selection));
nsresult result = mElement->InsertData(mOffset, mStringToInsert);
if (NS_FAILED(result)) return result;
if (!selection) return NS_ERROR_NULL_POINTER;
result = mElement->InsertData(mOffset, mStringToInsert);
if (NS_SUCCEEDED(result))
// only set selection to insertion point if editor gives permission
PRBool bAdjustSelection;
mEditor->ShouldTxnSetSelection(&bAdjustSelection);
if (bAdjustSelection)
{
nsCOMPtr<nsIDOMSelection> selection;
result = mEditor->GetSelection(getter_AddRefs(selection));
if (NS_FAILED(result)) return result;
if (!selection) return NS_ERROR_NULL_POINTER;
result = selection->Collapse(mElement, mOffset+mStringToInsert.Length());
NS_ASSERTION((NS_SUCCEEDED(result)), "selection could not be collapsed after insert.");
}
else
{
// do nothing - dom range gravity will adjust selection
}
return result;
}
NS_IMETHODIMP InsertTextTxn::Undo(void)
{
if (gNoisy) { printf("Undo Insert Text element = %p\n", mElement.get()); }
NS_ASSERTION(mElement && mPresShellWeak, "bad state");
if (!mElement || !mPresShellWeak) { return NS_ERROR_NOT_INITIALIZED; }
nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
if (!ps) return NS_ERROR_NOT_INITIALIZED;
NS_ASSERTION(mElement && mEditor, "bad state");
if (!mElement || !mEditor) { return NS_ERROR_NOT_INITIALIZED; }
nsresult result;
PRUint32 length = mStringToInsert.Length();
result = mElement->DeleteData(mOffset, length);
if (NS_SUCCEEDED(result))
{ // set the selection to the insertion point where the string was removed
nsCOMPtr<nsIDOMSelection> selection;
result = ps->GetSelection(SELECTION_NORMAL, getter_AddRefs(selection));
if (NS_FAILED(result)) return result;
if (!selection) return NS_ERROR_NULL_POINTER;
result = selection->Collapse(mElement, mOffset);
NS_ASSERTION((NS_SUCCEEDED(result)), "selection could not be collapsed after undo of insert.");
}
return result;
}