editor/base/nsEditorEventListeners.cpp
editor/base/nsEditorEventListeners.h

  - Added code to scroll the selection into view
    after processing key events.
  - Commented out the hack that redraws the entire
    view when the focus is gained and lost. Replaced
    the hack code with calls to RepaintSelection().

layout/base/public/nsIFrameSelection.h
layout/base/public/nsIPresShell.h
layout/html/base/src/nsPresShell.cpp
   - Added ScrollSelectionIntoView() and RepaintSelection() methods.

layout/base/src/nsRangeList.cpp
   - Added implementation for ScrollSelectionIntoView() and
     RepaintSelection().
   - Check for NULL primary frame in GetFocusNodeRect()
     to fix bug #12793.
This commit is contained in:
kin%netscape.com 1999-08-30 21:54:40 +00:00
parent c3917762df
commit bfd4c1f102
11 changed files with 260 additions and 17 deletions

View File

@ -151,6 +151,7 @@ nsTextEditorKeyListener::KeyDown(nsIDOMEvent* aKeyEvent)
case nsIDOMUIEvent::VK_DELETE:
mEditor->DeleteSelection(nsIEditor::eDeleteNext);
ScrollSelectionIntoView();
break;
// case nsIDOMUIEvent::VK_RETURN:
@ -200,6 +201,7 @@ nsTextEditorKeyListener::KeyDown(nsIDOMEvent* aKeyEvent)
nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(mEditor);
if (htmlEditor)
htmlEditor->InsertText(key);
ScrollSelectionIntoView();
return NS_ERROR_BASE; // this means "I handled the event, don't do default processing"
}
else {
@ -267,7 +269,8 @@ nsTextEditorKeyListener::KeyPress(nsIDOMEvent* aKeyEvent)
if (nsIDOMUIEvent::VK_BACK==keyCode)
{
mEditor->DeleteSelection(nsIEditor::eDeletePrevious);
return NS_ERROR_BASE; // consumed
ScrollSelectionIntoView();
return NS_ERROR_BASE; // consumed
}
if (nsIDOMUIEvent::VK_RETURN==keyCode)
{
@ -275,6 +278,7 @@ nsTextEditorKeyListener::KeyPress(nsIDOMEvent* aKeyEvent)
if (!(flags & nsIHTMLEditor::eEditorSingleLineMask))
{
htmlEditor->InsertBreak();
ScrollSelectionIntoView();
return NS_ERROR_BASE; // consumed
}
else
@ -293,8 +297,11 @@ nsTextEditorKeyListener::KeyPress(nsIDOMEvent* aKeyEvent)
}
key += character;
htmlEditor->InsertText(key);
ScrollSelectionIntoView();
}
}
else
ScrollSelectionIntoView();
return NS_ERROR_BASE; // consumed
@ -587,7 +594,6 @@ nsTextEditorKeyListener::ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aPr
else {
htmlEditor->RemoveInlineProperty(nsIEditProperty::u, nsnull);
}
}
}
break;
@ -833,7 +839,21 @@ nsTextEditorKeyListener::ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aPr
return NS_OK;
}
nsresult
nsTextEditorKeyListener::ScrollSelectionIntoView()
{
nsCOMPtr<nsIPresShell> presShell;
nsresult result = mEditor->GetPresShell(getter_AddRefs(presShell));
if (NS_FAILED(result))
return result;
if (!presShell)
return NS_ERROR_NULL_POINTER;
return presShell->ScrollSelectionIntoView(SELECTION_NORMAL, SELECTION_FOCUS_REGION);
}
/*
* nsTextEditorMouseListener implementation
@ -1653,6 +1673,7 @@ nsTextEditorFocusListener::Focus(nsIDOMEvent* aEvent)
doc->SetDisplaySelection(PR_TRUE);
}
}
#ifdef USE_HACK_REPAINT
// begin hack repaint
nsCOMPtr<nsIViewManager> viewmgr;
ps->GetViewManager(getter_AddRefs(viewmgr));
@ -1662,8 +1683,11 @@ nsTextEditorFocusListener::Focus(nsIDOMEvent* aEvent)
if (view) {
viewmgr->UpdateView(view,nsnull,NS_VMREFRESH_IMMEDIATE);
}
// end hack repaint
}
// end hack repaint
#else
ps->RepaintSelection(SELECTION_NORMAL);
#endif
}
}
}
@ -1696,6 +1720,7 @@ nsTextEditorFocusListener::Blur(nsIDOMEvent* aEvent)
doc->SetDisplaySelection(PR_FALSE);
}
}
#ifdef USE_HACK_REPAINT
// begin hack repaint
nsCOMPtr<nsIViewManager> viewmgr;
ps->GetViewManager(getter_AddRefs(viewmgr));
@ -1708,6 +1733,9 @@ nsTextEditorFocusListener::Blur(nsIDOMEvent* aEvent)
}
}
// end hack repaint
#else
ps->RepaintSelection(SELECTION_NORMAL);
#endif
}
}
}

View File

@ -65,6 +65,7 @@ public:
protected:
virtual nsresult ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aProcessed);
virtual nsresult ScrollSelectionIntoView();
protected:
nsIEditor* mEditor; // weak reference

View File

@ -151,6 +151,7 @@ nsTextEditorKeyListener::KeyDown(nsIDOMEvent* aKeyEvent)
case nsIDOMUIEvent::VK_DELETE:
mEditor->DeleteSelection(nsIEditor::eDeleteNext);
ScrollSelectionIntoView();
break;
// case nsIDOMUIEvent::VK_RETURN:
@ -200,6 +201,7 @@ nsTextEditorKeyListener::KeyDown(nsIDOMEvent* aKeyEvent)
nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(mEditor);
if (htmlEditor)
htmlEditor->InsertText(key);
ScrollSelectionIntoView();
return NS_ERROR_BASE; // this means "I handled the event, don't do default processing"
}
else {
@ -267,7 +269,8 @@ nsTextEditorKeyListener::KeyPress(nsIDOMEvent* aKeyEvent)
if (nsIDOMUIEvent::VK_BACK==keyCode)
{
mEditor->DeleteSelection(nsIEditor::eDeletePrevious);
return NS_ERROR_BASE; // consumed
ScrollSelectionIntoView();
return NS_ERROR_BASE; // consumed
}
if (nsIDOMUIEvent::VK_RETURN==keyCode)
{
@ -275,6 +278,7 @@ nsTextEditorKeyListener::KeyPress(nsIDOMEvent* aKeyEvent)
if (!(flags & nsIHTMLEditor::eEditorSingleLineMask))
{
htmlEditor->InsertBreak();
ScrollSelectionIntoView();
return NS_ERROR_BASE; // consumed
}
else
@ -293,8 +297,11 @@ nsTextEditorKeyListener::KeyPress(nsIDOMEvent* aKeyEvent)
}
key += character;
htmlEditor->InsertText(key);
ScrollSelectionIntoView();
}
}
else
ScrollSelectionIntoView();
return NS_ERROR_BASE; // consumed
@ -587,7 +594,6 @@ nsTextEditorKeyListener::ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aPr
else {
htmlEditor->RemoveInlineProperty(nsIEditProperty::u, nsnull);
}
}
}
break;
@ -833,7 +839,21 @@ nsTextEditorKeyListener::ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aPr
return NS_OK;
}
nsresult
nsTextEditorKeyListener::ScrollSelectionIntoView()
{
nsCOMPtr<nsIPresShell> presShell;
nsresult result = mEditor->GetPresShell(getter_AddRefs(presShell));
if (NS_FAILED(result))
return result;
if (!presShell)
return NS_ERROR_NULL_POINTER;
return presShell->ScrollSelectionIntoView(SELECTION_NORMAL, SELECTION_FOCUS_REGION);
}
/*
* nsTextEditorMouseListener implementation
@ -1653,6 +1673,7 @@ nsTextEditorFocusListener::Focus(nsIDOMEvent* aEvent)
doc->SetDisplaySelection(PR_TRUE);
}
}
#ifdef USE_HACK_REPAINT
// begin hack repaint
nsCOMPtr<nsIViewManager> viewmgr;
ps->GetViewManager(getter_AddRefs(viewmgr));
@ -1662,8 +1683,11 @@ nsTextEditorFocusListener::Focus(nsIDOMEvent* aEvent)
if (view) {
viewmgr->UpdateView(view,nsnull,NS_VMREFRESH_IMMEDIATE);
}
// end hack repaint
}
// end hack repaint
#else
ps->RepaintSelection(SELECTION_NORMAL);
#endif
}
}
}
@ -1696,6 +1720,7 @@ nsTextEditorFocusListener::Blur(nsIDOMEvent* aEvent)
doc->SetDisplaySelection(PR_FALSE);
}
}
#ifdef USE_HACK_REPAINT
// begin hack repaint
nsCOMPtr<nsIViewManager> viewmgr;
ps->GetViewManager(getter_AddRefs(viewmgr));
@ -1708,6 +1733,9 @@ nsTextEditorFocusListener::Blur(nsIDOMEvent* aEvent)
}
}
// end hack repaint
#else
ps->RepaintSelection(SELECTION_NORMAL);
#endif
}
}
}

View File

@ -65,6 +65,7 @@ public:
protected:
virtual nsresult ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aProcessed);
virtual nsresult ScrollSelectionIntoView();
protected:
nsIEditor* mEditor; // weak reference

View File

@ -130,6 +130,20 @@ public:
*/
NS_IMETHOD GetSelection(SelectionType aSelectionType, nsIDOMSelection **aDomSelection)=0;
/**
* ScrollSelectionIntoView scrolls a region of the selection,
* so that it is visible in the scrolled view.
*
* @param aType the selection to scroll into view.
* @param aRegion the region inside the selection to scroll into view.
*/
NS_IMETHOD ScrollSelectionIntoView(SelectionType aSelectionType, SelectionRegion aRegion)=0;
/** RepaintSelection repaints the selected frames that are inside the selection
* specified by aSelectionType.
* @param aSelectionType enum value defined in nsIDOMSelection for the domseleciton you want.
*/
NS_IMETHOD RepaintSelection(SelectionType aSelectionType)=0;
};

View File

@ -54,10 +54,14 @@ class nsIFrameManager;
#define NS_PRESSHELL_SCROLL_ANYWHERE -1
typedef enum SelectionType{SELECTION_NORMAL = 0,
SELECTION_SPELLCHECK,
SELECTION_IME_SOLID,
SELECTION_IME_DASHED,
NUM_SELECTIONTYPES} SelectionType;
SELECTION_SPELLCHECK,
SELECTION_IME_SOLID,
SELECTION_IME_DASHED,
NUM_SELECTIONTYPES} SelectionType;
typedef enum SelectionRegion{SELECTION_ANCHOR_REGION = 0,
SELECTION_FOCUS_REGION,
NUM_SELECTION_REGIONS} SelectionRegion;
/**
@ -106,6 +110,22 @@ public:
*/
NS_IMETHOD GetSelection(SelectionType aType, nsIDOMSelection** aSelection) = 0;
/**
* ScrollSelectionIntoView scrolls a region of the selection,
* so that it is visible in the scrolled view.
*
* @param aType the selection to scroll into view.
* @param aRegion the region inside the selection to scroll into view.
*/
NS_IMETHOD ScrollSelectionIntoView(SelectionType aType, SelectionRegion aRegion) = 0;
/**
* RepaintSelection repaints the selection specified by aType.
*
* @param aType specifies the selection to repaint.
*/
NS_IMETHOD RepaintSelection(SelectionType aType) = 0;
/**
* GetFrameSelection will return the Frame based selection API you
* cannot go back and forth anymore with QI with nsIDOM sel and nsIFrame sel.

View File

@ -134,6 +134,8 @@ public:
NS_IMETHOD SelectAlternateStyleSheet(const nsString& aSheetTitle);
NS_IMETHOD ListAlternateStyleSheets(nsStringArray& aTitleList);
NS_IMETHOD GetSelection(SelectionType aType, nsIDOMSelection** aSelection);
NS_IMETHOD ScrollSelectionIntoView(SelectionType aType, SelectionRegion aRegion);
NS_IMETHOD RepaintSelection(SelectionType aType);
NS_IMETHOD GetFrameSelection(nsIFrameSelection** aSelection);
NS_IMETHOD EnterReflowLock();
@ -716,6 +718,24 @@ PresShell::GetSelection(SelectionType aType, nsIDOMSelection **aSelection)
return mSelection->GetSelection(aType, aSelection);
}
NS_IMETHODIMP
PresShell::ScrollSelectionIntoView(SelectionType aType, SelectionRegion aRegion)
{
if (!mSelection)
return NS_ERROR_NULL_POINTER;
return mSelection->ScrollSelectionIntoView(aType, aRegion);
}
NS_IMETHODIMP
PresShell::RepaintSelection(SelectionType aType)
{
if (!mSelection)
return NS_ERROR_NULL_POINTER;
return mSelection->RepaintSelection(aType);
}
NS_IMETHODIMP
PresShell::GetFrameSelection(nsIFrameSelection** aSelection)
{

View File

@ -130,6 +130,20 @@ public:
*/
NS_IMETHOD GetSelection(SelectionType aSelectionType, nsIDOMSelection **aDomSelection)=0;
/**
* ScrollSelectionIntoView scrolls a region of the selection,
* so that it is visible in the scrolled view.
*
* @param aType the selection to scroll into view.
* @param aRegion the region inside the selection to scroll into view.
*/
NS_IMETHOD ScrollSelectionIntoView(SelectionType aSelectionType, SelectionRegion aRegion)=0;
/** RepaintSelection repaints the selected frames that are inside the selection
* specified by aSelectionType.
* @param aSelectionType enum value defined in nsIDOMSelection for the domseleciton you want.
*/
NS_IMETHOD RepaintSelection(SelectionType aSelectionType)=0;
};

View File

@ -54,10 +54,14 @@ class nsIFrameManager;
#define NS_PRESSHELL_SCROLL_ANYWHERE -1
typedef enum SelectionType{SELECTION_NORMAL = 0,
SELECTION_SPELLCHECK,
SELECTION_IME_SOLID,
SELECTION_IME_DASHED,
NUM_SELECTIONTYPES} SelectionType;
SELECTION_SPELLCHECK,
SELECTION_IME_SOLID,
SELECTION_IME_DASHED,
NUM_SELECTIONTYPES} SelectionType;
typedef enum SelectionRegion{SELECTION_ANCHOR_REGION = 0,
SELECTION_FOCUS_REGION,
NUM_SELECTION_REGIONS} SelectionRegion;
/**
@ -106,6 +110,22 @@ public:
*/
NS_IMETHOD GetSelection(SelectionType aType, nsIDOMSelection** aSelection) = 0;
/**
* ScrollSelectionIntoView scrolls a region of the selection,
* so that it is visible in the scrolled view.
*
* @param aType the selection to scroll into view.
* @param aRegion the region inside the selection to scroll into view.
*/
NS_IMETHOD ScrollSelectionIntoView(SelectionType aType, SelectionRegion aRegion) = 0;
/**
* RepaintSelection repaints the selection specified by aType.
*
* @param aType specifies the selection to repaint.
*/
NS_IMETHOD RepaintSelection(SelectionType aType) = 0;
/**
* GetFrameSelection will return the Frame based selection API you
* cannot go back and forth anymore with QI with nsIDOM sel and nsIFrame sel.

View File

@ -121,7 +121,7 @@ public:
nsresult GetFocusNodeRect(nsRect *aRect);
nsresult ScrollRectIntoView(nsRect& aRect, PRIntn aVPercent, PRIntn aHPercent);
NS_IMETHOD ScrollIntoView();
NS_IMETHOD ScrollIntoView(SelectionRegion aRegion=SELECTION_FOCUS_REGION);
nsresult AddItem(nsIDOMRange *aRange);
nsresult RemoveItem(nsIDOMRange *aRange);
@ -148,6 +148,7 @@ public:
NS_IMETHOD GetOriginalAnchorPoint(nsIDOMNode **aNode, PRInt32 *aOffset);
NS_IMETHOD LookUpSelection(nsIContent *aContent, PRInt32 aContentOffset, PRInt32 aContentLength,
SelectionDetails **aReturnDetails, SelectionType aType);
NS_IMETHOD Repaint();
private:
friend class nsRangeListIterator;
@ -195,6 +196,8 @@ public:
NS_IMETHOD SetMouseDownState(PRBool aState);
NS_IMETHOD GetMouseDownState(PRBool *aState);
NS_IMETHOD GetSelection(SelectionType aType, nsIDOMSelection **aDomSelection);
NS_IMETHOD ScrollSelectionIntoView(SelectionType aType, SelectionRegion aRegion);
NS_IMETHOD RepaintSelection(SelectionType aType);
/*END nsIFrameSelection interfacse*/
@ -992,7 +995,7 @@ nsRangeList::GetMouseDownState(PRBool *aState)
NS_IMETHODIMP
nsRangeList::GetSelection(SelectionType aType, nsIDOMSelection **aDomSelection)
{
if (aType < SELECTION_NORMAL || aType > NUM_SELECTIONTYPES)
if (aType < SELECTION_NORMAL || aType >= NUM_SELECTIONTYPES)
return NS_ERROR_FAILURE;
if (!aDomSelection)
return NS_ERROR_NULL_POINTER;
@ -1001,6 +1004,30 @@ nsRangeList::GetSelection(SelectionType aType, nsIDOMSelection **aDomSelection)
return NS_OK;
}
NS_IMETHODIMP
nsRangeList::ScrollSelectionIntoView(SelectionType aType, SelectionRegion aRegion)
{
if (aType < SELECTION_NORMAL || aType >= NUM_SELECTIONTYPES)
return NS_ERROR_FAILURE;
if (!mDomSelections[aType])
return NS_ERROR_NULL_POINTER;
return mDomSelections[aType]->ScrollIntoView(aRegion);
}
NS_IMETHODIMP
nsRangeList::RepaintSelection(SelectionType aType)
{
if (aType < SELECTION_NORMAL || aType >= NUM_SELECTIONTYPES)
return NS_ERROR_FAILURE;
if (!mDomSelections[aType])
return NS_ERROR_NULL_POINTER;
return mDomSelections[aType]->Repaint();
}
//////////END FRAMESELECTION
NS_METHOD
nsRangeList::AddSelectionListener(nsIDOMSelectionListener* inNewListener)
@ -1172,6 +1199,7 @@ nsDOMSelection::nsDOMSelection(nsRangeList *aList)
{
mRangeList = aList;
mFixupState = PR_FALSE;
mDirection = eDirNext;
NS_NewISupportsArray(getter_AddRefs(mRangeArray));
mScriptObject = nsnull;
NS_INIT_REFCNT();
@ -1741,7 +1769,50 @@ nsDOMSelection::LookUpSelection(nsIContent *aContent, PRInt32 aContentOffset, PR
return NS_OK;
}
NS_IMETHODIMP
nsDOMSelection::Repaint()
{
PRUint32 arrCount = 0;
if (!mRangeArray)
return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsISupports> isupp;
nsCOMPtr<nsIDOMRange> range;
nsresult result = mRangeArray->Count(&arrCount);
if (NS_FAILED(result))
return result;
if (arrCount < 1)
return NS_OK;
PRUint32 i;
for (i = 0; i < arrCount; i++)
{
result = mRangeArray->GetElementAt(i, getter_AddRefs(isupp));
if (NS_FAILED(result))
return result;
if (!isupp)
return NS_ERROR_NULL_POINTER;
range = do_QueryInterface(isupp);
if (!range)
return NS_ERROR_NULL_POINTER;
result = selectFrames(range, PR_TRUE);
if (NS_FAILED(result))
return result;
}
return NS_OK;
}
NS_IMETHODIMP
nsDOMSelection::GetEnumerator(nsIEnumerator **aIterator)
@ -2793,6 +2864,9 @@ nsDOMSelection::GetFocusNodeRect(nsRect *aRect)
if (NS_FAILED(result))
return result;
if (!frame)
return NS_ERROR_NULL_POINTER;
if (focusNodeType == nsIDOMNode::TEXT_NODE)
{
nsIFrame *childFrame = 0;
@ -2987,10 +3061,13 @@ nsDOMSelection::ScrollRectIntoView(nsRect& aRect,
}
NS_IMETHODIMP
nsDOMSelection::ScrollIntoView()
nsDOMSelection::ScrollIntoView(SelectionRegion aRegion)
{
nsresult result;
if (mRangeList->GetBatching())
return NS_OK;
//
// Shut the caret off before scrolling to avoid
// leaving caret turds on the screen!

View File

@ -134,6 +134,8 @@ public:
NS_IMETHOD SelectAlternateStyleSheet(const nsString& aSheetTitle);
NS_IMETHOD ListAlternateStyleSheets(nsStringArray& aTitleList);
NS_IMETHOD GetSelection(SelectionType aType, nsIDOMSelection** aSelection);
NS_IMETHOD ScrollSelectionIntoView(SelectionType aType, SelectionRegion aRegion);
NS_IMETHOD RepaintSelection(SelectionType aType);
NS_IMETHOD GetFrameSelection(nsIFrameSelection** aSelection);
NS_IMETHOD EnterReflowLock();
@ -716,6 +718,24 @@ PresShell::GetSelection(SelectionType aType, nsIDOMSelection **aSelection)
return mSelection->GetSelection(aType, aSelection);
}
NS_IMETHODIMP
PresShell::ScrollSelectionIntoView(SelectionType aType, SelectionRegion aRegion)
{
if (!mSelection)
return NS_ERROR_NULL_POINTER;
return mSelection->ScrollSelectionIntoView(aType, aRegion);
}
NS_IMETHODIMP
PresShell::RepaintSelection(SelectionType aType)
{
if (!mSelection)
return NS_ERROR_NULL_POINTER;
return mSelection->RepaintSelection(aType);
}
NS_IMETHODIMP
PresShell::GetFrameSelection(nsIFrameSelection** aSelection)
{