fix for 48297: ome edit operations not scroling selection into view; r=fm

This commit is contained in:
jfrancis%netscape.com 2000-08-14 02:39:37 +00:00
parent b64ba64c82
commit d25d7bd494
10 changed files with 108 additions and 68 deletions

View File

@ -786,6 +786,8 @@ nsEditor::nsEditor()
, mEditorObservers(nsnull)
, mDocDirtyState(-1)
, mDocWeak(nsnull)
, mAction(nsnull)
, mDirection(eNone)
{
//initialize member variables here
NS_INIT_REFCNT();
@ -1096,8 +1098,6 @@ nsEditor::Undo(PRUint32 aCount)
nsAutoRules beginRulesSniffing(this, kOpUndo, nsIEditor::eNone);
BeginUpdateViewBatch();
if ((nsITransactionManager *)nsnull!=mTxnMgr.get())
{
PRUint32 i=0;
@ -1113,7 +1113,6 @@ nsEditor::Undo(PRUint32 aCount)
}
}
EndUpdateViewBatch();
NotifyEditorObservers();
return result;
}
@ -1142,7 +1141,6 @@ nsEditor::Redo(PRUint32 aCount)
nsresult result = NS_OK;
nsAutoRules beginRulesSniffing(this, kOpRedo, nsIEditor::eNone);
BeginUpdateViewBatch();
if ((nsITransactionManager *)nsnull!=mTxnMgr.get())
{
@ -1159,7 +1157,6 @@ nsEditor::Redo(PRUint32 aCount)
}
}
EndUpdateViewBatch();
NotifyEditorObservers();
return result;
}
@ -1244,6 +1241,11 @@ nsEditor::EndPlaceHolderTransaction()
{
// time to turn off the batch
EndUpdateViewBatch();
// make sure selection is in view
nsCOMPtr<nsISelectionController> selCon;
if (NS_SUCCEEDED(GetSelectionController(getter_AddRefs(selCon))) && selCon)
selCon->ScrollSelectionIntoView(nsISelectionController::SELECTION_NORMAL, nsISelectionController::SELECTION_FOCUS_REGION);
if (mSelState)
{
// we saved the selection state, but never got to hand it to placeholder
@ -2537,15 +2539,19 @@ nsEditor::GetRootElement(nsIDOMElement **aBodyElement)
NS_IMETHODIMP
nsEditor::StartOperation(PRInt32 opID, nsIEditor::EDirection aDirection)
{
mAction = opID;
mDirection = aDirection;
return NS_OK;
}
/** All editor operations which alter the doc should be followed
* with a call to EndOperation, naming the action and direction */
* with a call to EndOperation */
NS_IMETHODIMP
nsEditor::EndOperation(PRInt32 opID, nsIEditor::EDirection aDirection)
nsEditor::EndOperation()
{
mAction = nsnull;
mDirection = eNone;
return NS_OK;
}
@ -5248,7 +5254,7 @@ nsEditor::SetShouldTxnSetSelection(PRBool aShould)
NS_IMETHODIMP
nsEditor::DeleteSelectionImpl(EDirection aAction)
nsEditor::DeleteSelectionImpl(nsIEditor::EDirection aAction)
{
nsresult res;

View File

@ -480,8 +480,8 @@ public:
NS_IMETHOD StartOperation(PRInt32 opID, nsIEditor::EDirection aDirection);
/** All editor operations which alter the doc should be followed
* with a call to EndOperation, naming the action and direction */
NS_IMETHOD EndOperation(PRInt32 opID, nsIEditor::EDirection aDirection);
* with a call to EndOperation */
NS_IMETHOD EndOperation();
/** return the string that represents text nodes in the content tree */
static nsresult GetTextNodeTag(nsString& aOutString);
@ -755,15 +755,17 @@ protected:
nsSelectionState *mSavedSel; // cached selection for nsAutoSelectionReset
PRBool mShouldTxnSetSelection; // turn off for conservative selection adjustment by txns
nsCOMPtr<nsIDOMElement> mBodyElement; // cached body node
//
PRInt32 mAction; // the current editor action
EDirection mDirection; // the current direction of editor action
// data necessary to build IME transactions
//
PRBool mInIMEMode; // are we inside an IME composition?
nsIPrivateTextRangeList* mIMETextRangeList; // IME special selection ranges
nsCOMPtr<nsIDOMCharacterData> mIMETextNode; // current IME text node
PRUint32 mIMETextOffset; // offset in text node where IME comp string begins
PRUint32 mIMEBufferLength; // current length of IME comp string
// various listeners
nsVoidArray* mActionListeners; // listens to all low level actions on the doc
nsVoidArray* mEditorObservers; // just notify once per high level change
nsCOMPtr<nsISupportsArray> mDocStateListeners;// listen to overall doc state (dirty or not, just created, etc)
@ -777,6 +779,7 @@ protected:
friend PRBool NSCanUnload(nsISupports* serviceMgr);
friend class nsAutoTxnsConserveSelection;
friend class nsAutoSelectionReset;
friend class nsAutoRules;
};

View File

@ -87,14 +87,25 @@ class nsAutoRules
public:
nsAutoRules(nsEditor *ed, PRInt32 action, nsIEditor::EDirection aDirection) :
mEd(ed), mAction(action), mDirection(aDirection)
{if (mEd) mEd->StartOperation(mAction, mDirection);}
~nsAutoRules() {if (mEd) mEd->EndOperation(mAction, mDirection);}
mEd(ed), mDoNothing(PR_FALSE)
{
if (mEd && !mEd->mAction) // mAction will already be set if this is nested call
{
mEd->StartOperation(action, aDirection);
}
else mDoNothing = PR_TRUE; // nested calls will end up here
}
~nsAutoRules()
{
if (mEd && !mDoNothing)
{
mEd->EndOperation();
}
}
protected:
nsEditor *mEd;
PRInt32 mAction;
nsIEditor::EDirection mDirection;
PRBool mDoNothing;
};

View File

@ -4503,7 +4503,7 @@ nsHTMLEditor::Undo(PRUint32 aCount)
ForceCompositionEnd();
nsresult result = NS_OK;
BeginUpdateViewBatch();
nsAutoRules beginRulesSniffing(this, kOpUndo, nsIEditor::eNone);
nsTextRulesInfo ruleInfo(nsTextEditRules::kUndo);
nsCOMPtr<nsIDOMSelection> selection;
@ -4517,8 +4517,6 @@ nsHTMLEditor::Undo(PRUint32 aCount)
result = mRules->DidDoAction(selection, &ruleInfo, result);
}
EndUpdateViewBatch();
return result;
}
@ -4528,7 +4526,7 @@ nsHTMLEditor::Redo(PRUint32 aCount)
{
nsresult result = NS_OK;
BeginUpdateViewBatch();
nsAutoRules beginRulesSniffing(this, kOpRedo, nsIEditor::eNone);
nsTextRulesInfo ruleInfo(nsTextEditRules::kRedo);
nsCOMPtr<nsIDOMSelection> selection;
@ -4542,8 +4540,6 @@ nsHTMLEditor::Redo(PRUint32 aCount)
result = mRules->DidDoAction(selection, &ruleInfo, result);
}
EndUpdateViewBatch();
return result;
}
@ -5906,23 +5902,27 @@ void nsHTMLEditor::ApplyStyleSheetToPresShellDocument(nsICSSStyleSheet* aSheet,
NS_IMETHODIMP
nsHTMLEditor::StartOperation(PRInt32 opID, nsIEditor::EDirection aDirection)
{
if (! ((opID==kOpInsertText) || (opID==kOpInsertIMEText)) )
nsEditor::StartOperation(opID, aDirection); // will set mAction, mDirection
if (! ((mAction==kOpInsertText) || (mAction==kOpInsertIMEText)) )
ClearInlineStylesCache();
if (mRules) return mRules->BeforeEdit(opID, aDirection);
if (mRules) return mRules->BeforeEdit(mAction, mDirection);
return NS_OK;
}
/** All editor operations which alter the doc should be followed
* with a call to EndOperation, naming the action and direction */
* with a call to EndOperation */
NS_IMETHODIMP
nsHTMLEditor::EndOperation(PRInt32 opID, nsIEditor::EDirection aDirection)
nsHTMLEditor::EndOperation()
{
if (! ((opID==kOpInsertText) || (opID==kOpInsertIMEText)) )
// post processing
if (! ((mAction==kOpInsertText) || (mAction==kOpInsertIMEText) || (mAction==kOpIgnore)) )
ClearInlineStylesCache();
if (mRules) return mRules->AfterEdit(opID, aDirection);
return NS_OK;
}
nsresult res = NS_OK;
if (mRules) res = mRules->AfterEdit(mAction, mDirection);
nsEditor::EndOperation(); // will clear mAction, mDirection
return res;
}
PRBool

View File

@ -288,8 +288,8 @@ public:
NS_IMETHOD StartOperation(PRInt32 opID, nsIEditor::EDirection aDirection);
/** All editor operations which alter the doc should be followed
* with a call to EndOperation, naming the action and direction */
NS_IMETHOD EndOperation(PRInt32 opID, nsIEditor::EDirection aDirection);
* with a call to EndOperation */
NS_IMETHOD EndOperation();
/** returns PR_TRUE if aParentTag can contain a child of type aChildTag */
virtual PRBool TagCanContainTag(const nsString &aParentTag, const nsString &aChildTag);
@ -496,7 +496,7 @@ protected:
/* small utility routine to test the eEditorReadonly bit */
PRBool IsModifiable();
/* helpers for block transformations */
nsresult MakeDefinitionItem(const nsString& aItemType);
nsresult InsertBasicBlock(const nsString& aBlockType);

View File

@ -786,6 +786,8 @@ nsEditor::nsEditor()
, mEditorObservers(nsnull)
, mDocDirtyState(-1)
, mDocWeak(nsnull)
, mAction(nsnull)
, mDirection(eNone)
{
//initialize member variables here
NS_INIT_REFCNT();
@ -1096,8 +1098,6 @@ nsEditor::Undo(PRUint32 aCount)
nsAutoRules beginRulesSniffing(this, kOpUndo, nsIEditor::eNone);
BeginUpdateViewBatch();
if ((nsITransactionManager *)nsnull!=mTxnMgr.get())
{
PRUint32 i=0;
@ -1113,7 +1113,6 @@ nsEditor::Undo(PRUint32 aCount)
}
}
EndUpdateViewBatch();
NotifyEditorObservers();
return result;
}
@ -1142,7 +1141,6 @@ nsEditor::Redo(PRUint32 aCount)
nsresult result = NS_OK;
nsAutoRules beginRulesSniffing(this, kOpRedo, nsIEditor::eNone);
BeginUpdateViewBatch();
if ((nsITransactionManager *)nsnull!=mTxnMgr.get())
{
@ -1159,7 +1157,6 @@ nsEditor::Redo(PRUint32 aCount)
}
}
EndUpdateViewBatch();
NotifyEditorObservers();
return result;
}
@ -1244,6 +1241,11 @@ nsEditor::EndPlaceHolderTransaction()
{
// time to turn off the batch
EndUpdateViewBatch();
// make sure selection is in view
nsCOMPtr<nsISelectionController> selCon;
if (NS_SUCCEEDED(GetSelectionController(getter_AddRefs(selCon))) && selCon)
selCon->ScrollSelectionIntoView(nsISelectionController::SELECTION_NORMAL, nsISelectionController::SELECTION_FOCUS_REGION);
if (mSelState)
{
// we saved the selection state, but never got to hand it to placeholder
@ -2537,15 +2539,19 @@ nsEditor::GetRootElement(nsIDOMElement **aBodyElement)
NS_IMETHODIMP
nsEditor::StartOperation(PRInt32 opID, nsIEditor::EDirection aDirection)
{
mAction = opID;
mDirection = aDirection;
return NS_OK;
}
/** All editor operations which alter the doc should be followed
* with a call to EndOperation, naming the action and direction */
* with a call to EndOperation */
NS_IMETHODIMP
nsEditor::EndOperation(PRInt32 opID, nsIEditor::EDirection aDirection)
nsEditor::EndOperation()
{
mAction = nsnull;
mDirection = eNone;
return NS_OK;
}
@ -5248,7 +5254,7 @@ nsEditor::SetShouldTxnSetSelection(PRBool aShould)
NS_IMETHODIMP
nsEditor::DeleteSelectionImpl(EDirection aAction)
nsEditor::DeleteSelectionImpl(nsIEditor::EDirection aAction)
{
nsresult res;

View File

@ -480,8 +480,8 @@ public:
NS_IMETHOD StartOperation(PRInt32 opID, nsIEditor::EDirection aDirection);
/** All editor operations which alter the doc should be followed
* with a call to EndOperation, naming the action and direction */
NS_IMETHOD EndOperation(PRInt32 opID, nsIEditor::EDirection aDirection);
* with a call to EndOperation */
NS_IMETHOD EndOperation();
/** return the string that represents text nodes in the content tree */
static nsresult GetTextNodeTag(nsString& aOutString);
@ -755,15 +755,17 @@ protected:
nsSelectionState *mSavedSel; // cached selection for nsAutoSelectionReset
PRBool mShouldTxnSetSelection; // turn off for conservative selection adjustment by txns
nsCOMPtr<nsIDOMElement> mBodyElement; // cached body node
//
PRInt32 mAction; // the current editor action
EDirection mDirection; // the current direction of editor action
// data necessary to build IME transactions
//
PRBool mInIMEMode; // are we inside an IME composition?
nsIPrivateTextRangeList* mIMETextRangeList; // IME special selection ranges
nsCOMPtr<nsIDOMCharacterData> mIMETextNode; // current IME text node
PRUint32 mIMETextOffset; // offset in text node where IME comp string begins
PRUint32 mIMEBufferLength; // current length of IME comp string
// various listeners
nsVoidArray* mActionListeners; // listens to all low level actions on the doc
nsVoidArray* mEditorObservers; // just notify once per high level change
nsCOMPtr<nsISupportsArray> mDocStateListeners;// listen to overall doc state (dirty or not, just created, etc)
@ -777,6 +779,7 @@ protected:
friend PRBool NSCanUnload(nsISupports* serviceMgr);
friend class nsAutoTxnsConserveSelection;
friend class nsAutoSelectionReset;
friend class nsAutoRules;
};

View File

@ -87,14 +87,25 @@ class nsAutoRules
public:
nsAutoRules(nsEditor *ed, PRInt32 action, nsIEditor::EDirection aDirection) :
mEd(ed), mAction(action), mDirection(aDirection)
{if (mEd) mEd->StartOperation(mAction, mDirection);}
~nsAutoRules() {if (mEd) mEd->EndOperation(mAction, mDirection);}
mEd(ed), mDoNothing(PR_FALSE)
{
if (mEd && !mEd->mAction) // mAction will already be set if this is nested call
{
mEd->StartOperation(action, aDirection);
}
else mDoNothing = PR_TRUE; // nested calls will end up here
}
~nsAutoRules()
{
if (mEd && !mDoNothing)
{
mEd->EndOperation();
}
}
protected:
nsEditor *mEd;
PRInt32 mAction;
nsIEditor::EDirection mDirection;
PRBool mDoNothing;
};

View File

@ -4503,7 +4503,7 @@ nsHTMLEditor::Undo(PRUint32 aCount)
ForceCompositionEnd();
nsresult result = NS_OK;
BeginUpdateViewBatch();
nsAutoRules beginRulesSniffing(this, kOpUndo, nsIEditor::eNone);
nsTextRulesInfo ruleInfo(nsTextEditRules::kUndo);
nsCOMPtr<nsIDOMSelection> selection;
@ -4517,8 +4517,6 @@ nsHTMLEditor::Undo(PRUint32 aCount)
result = mRules->DidDoAction(selection, &ruleInfo, result);
}
EndUpdateViewBatch();
return result;
}
@ -4528,7 +4526,7 @@ nsHTMLEditor::Redo(PRUint32 aCount)
{
nsresult result = NS_OK;
BeginUpdateViewBatch();
nsAutoRules beginRulesSniffing(this, kOpRedo, nsIEditor::eNone);
nsTextRulesInfo ruleInfo(nsTextEditRules::kRedo);
nsCOMPtr<nsIDOMSelection> selection;
@ -4542,8 +4540,6 @@ nsHTMLEditor::Redo(PRUint32 aCount)
result = mRules->DidDoAction(selection, &ruleInfo, result);
}
EndUpdateViewBatch();
return result;
}
@ -5906,23 +5902,27 @@ void nsHTMLEditor::ApplyStyleSheetToPresShellDocument(nsICSSStyleSheet* aSheet,
NS_IMETHODIMP
nsHTMLEditor::StartOperation(PRInt32 opID, nsIEditor::EDirection aDirection)
{
if (! ((opID==kOpInsertText) || (opID==kOpInsertIMEText)) )
nsEditor::StartOperation(opID, aDirection); // will set mAction, mDirection
if (! ((mAction==kOpInsertText) || (mAction==kOpInsertIMEText)) )
ClearInlineStylesCache();
if (mRules) return mRules->BeforeEdit(opID, aDirection);
if (mRules) return mRules->BeforeEdit(mAction, mDirection);
return NS_OK;
}
/** All editor operations which alter the doc should be followed
* with a call to EndOperation, naming the action and direction */
* with a call to EndOperation */
NS_IMETHODIMP
nsHTMLEditor::EndOperation(PRInt32 opID, nsIEditor::EDirection aDirection)
nsHTMLEditor::EndOperation()
{
if (! ((opID==kOpInsertText) || (opID==kOpInsertIMEText)) )
// post processing
if (! ((mAction==kOpInsertText) || (mAction==kOpInsertIMEText) || (mAction==kOpIgnore)) )
ClearInlineStylesCache();
if (mRules) return mRules->AfterEdit(opID, aDirection);
return NS_OK;
}
nsresult res = NS_OK;
if (mRules) res = mRules->AfterEdit(mAction, mDirection);
nsEditor::EndOperation(); // will clear mAction, mDirection
return res;
}
PRBool

View File

@ -288,8 +288,8 @@ public:
NS_IMETHOD StartOperation(PRInt32 opID, nsIEditor::EDirection aDirection);
/** All editor operations which alter the doc should be followed
* with a call to EndOperation, naming the action and direction */
NS_IMETHOD EndOperation(PRInt32 opID, nsIEditor::EDirection aDirection);
* with a call to EndOperation */
NS_IMETHOD EndOperation();
/** returns PR_TRUE if aParentTag can contain a child of type aChildTag */
virtual PRBool TagCanContainTag(const nsString &aParentTag, const nsString &aChildTag);
@ -496,7 +496,7 @@ protected:
/* small utility routine to test the eEditorReadonly bit */
PRBool IsModifiable();
/* helpers for block transformations */
nsresult MakeDefinitionItem(const nsString& aItemType);
nsresult InsertBasicBlock(const nsString& aBlockType);