Fix keyboard scrolling for elements using overflow:scroll by scrolling the nearest scrollable view from the caret. b=251986 r=roc sr=dbaron

This commit is contained in:
mats.palmgren%bredband.net 2004-08-06 15:55:17 +00:00
parent 8bcaa1a262
commit 2ec5e837c2
11 changed files with 203 additions and 231 deletions

View File

@ -74,6 +74,7 @@
#include "nsILineIterator.h"
#include "nsLayoutAtoms.h"
#include "nsIFrameTraversal.h"
#include "nsLayoutUtils.h"
#include "nsLayoutCID.h"
static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID);
@ -245,7 +246,6 @@ public:
nsresult ScrollPointIntoClipView(nsPresContext *aPresContext, nsIView *aView, nsPoint& aPoint, PRBool *aDidScroll);
nsresult ScrollPointIntoView(nsPresContext *aPresContext, nsIView *aView, nsPoint& aPoint, PRBool aScrollParentViews, PRBool *aDidScroll);
nsresult GetViewAncestorOffset(nsIView *aView, nsIView *aAncestorView, nscoord *aXOffset, nscoord *aYOffset);
nsresult GetClosestScrollableView(nsIView *aView, nsIScrollableView **aScrollableView);
SelectionType GetType(){return mType;}
void SetType(SelectionType aType){mType = aType;}
@ -5284,26 +5284,6 @@ nsTypedSelection::GetViewAncestorOffset(nsIView *aView, nsIView *aAncestorView,
return NS_OK;
}
nsresult
nsTypedSelection::GetClosestScrollableView(nsIView *aView, nsIScrollableView **aScrollableView)
{
if (!aView || !aScrollableView)
return NS_ERROR_FAILURE;
*aScrollableView = 0;
while (!*aScrollableView && aView)
{
CallQueryInterface(aView, aScrollableView);
if (!*aScrollableView)
{
aView = aView->GetParent();
}
}
return NS_OK;
}
nsresult
nsTypedSelection::ScrollPointIntoClipView(nsPresContext *aPresContext, nsIView *aView, nsPoint& aPoint, PRBool *aDidScroll)
{
@ -5318,12 +5298,7 @@ nsTypedSelection::ScrollPointIntoClipView(nsPresContext *aPresContext, nsIView *
// Get aView's scrollable view.
//
nsIScrollableView *scrollableView = 0;
result = GetClosestScrollableView(aView, &scrollableView);
if (NS_FAILED(result))
return result;
nsIScrollableView *scrollableView = nsLayoutUtils::GetNearestScrollingView(aView);
if (!scrollableView)
return NS_OK; // Nothing to do!
@ -5513,12 +5488,7 @@ nsTypedSelection::ScrollPointIntoView(nsPresContext *aPresContext, nsIView *aVie
// Find aView's parent scrollable view.
//
nsIScrollableView *scrollableView = 0;
result = GetClosestScrollableView(aView, &scrollableView);
if (NS_FAILED(result))
return result;
nsIScrollableView *scrollableView = nsLayoutUtils::GetNearestScrollingView(aView);
if (scrollableView)
{
@ -5542,10 +5512,7 @@ nsTypedSelection::ScrollPointIntoView(nsPresContext *aPresContext, nsIView *aVie
while (view)
{
result = GetClosestScrollableView(view, &scrollableView);
if (NS_FAILED(result))
return result;
scrollableView = nsLayoutUtils::GetNearestScrollingView(view);
if (!scrollableView)
break;
@ -7015,10 +6982,7 @@ nsTypedSelection::GetSelectionRegionRectAndScrollableView(SelectionRegion aRegio
nsIView* view = parentWithView->GetView();
result = GetClosestScrollableView(view, aScrollableView);
if (NS_FAILED(result))
return result;
*aScrollableView = nsLayoutUtils::GetNearestScrollingView(view);
if (!*aScrollableView)
return NS_OK;
@ -7265,12 +7229,7 @@ nsTypedSelection::ScrollRectIntoView(nsIScrollableView *aScrollableView,
if (view)
{
nsIScrollableView *parentSV = 0;
rv = GetClosestScrollableView(view, &parentSV);
if (NS_FAILED(rv))
return rv;
nsIScrollableView *parentSV = nsLayoutUtils::GetNearestScrollingView(view);
if (parentSV)
{

View File

@ -124,6 +124,8 @@ public:
// Method for moving the focus forward/back.
NS_IMETHOD ShiftFocus(PRBool aDirection, nsIContent* aStart)=0;
// Return the location of the caret
NS_IMETHOD GetDocSelectionLocation(nsIContent **startContent, nsIContent **endContent, nsIFrame **startFrame, PRUint32 *startOffset) = 0;
};
#define NS_EVENT_STATE_UNSPECIFIED 0x0000

View File

@ -114,6 +114,7 @@
#include "nsIFrameTraversal.h"
#include "nsLayoutAtoms.h"
#include "nsLayoutCID.h"
#include "nsLayoutUtils.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsUnicharUtils.h"
#include "nsContentUtils.h"
@ -1723,7 +1724,7 @@ nsEventStateManager::DoScrollText(nsPresContext* aPresContext,
if (!focusView)
return NS_ERROR_FAILURE;
sv = GetNearestScrollingView(focusView);
sv = nsLayoutUtils::GetNearestScrollingView(focusView);
}
PRBool passToParent;
@ -2132,7 +2133,7 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
case NS_VK_PAGE_DOWN:
case NS_VK_PAGE_UP:
if (!mCurrentFocus) {
nsIScrollableView* sv = GetNearestScrollingView(aView);
nsIScrollableView* sv = nsLayoutUtils::GetNearestScrollingView(aView);
if (sv) {
nsKeyEvent * keyEvent = (nsKeyEvent *)aEvent;
sv->ScrollByPages(0, (keyEvent->keyCode != NS_VK_PAGE_UP) ? 1 : -1);
@ -2142,7 +2143,7 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
case NS_VK_HOME:
case NS_VK_END:
if (!mCurrentFocus) {
nsIScrollableView* sv = GetNearestScrollingView(aView);
nsIScrollableView* sv = nsLayoutUtils::GetNearestScrollingView(aView);
if (sv) {
nsKeyEvent * keyEvent = (nsKeyEvent *)aEvent;
sv->ScrollByWhole((keyEvent->keyCode != NS_VK_HOME) ? PR_FALSE : PR_TRUE);
@ -2152,7 +2153,7 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
case NS_VK_DOWN:
case NS_VK_UP:
if (!mCurrentFocus) {
nsIScrollableView* sv = GetNearestScrollingView(aView);
nsIScrollableView* sv = nsLayoutUtils::GetNearestScrollingView(aView);
if (sv) {
nsKeyEvent * keyEvent = (nsKeyEvent *)aEvent;
sv->ScrollByLines(0, (keyEvent->keyCode == NS_VK_DOWN) ? 1 : -1);
@ -2171,7 +2172,7 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
case NS_VK_LEFT:
case NS_VK_RIGHT:
if (!mCurrentFocus) {
nsIScrollableView* sv = GetNearestScrollingView(aView);
nsIScrollableView* sv = nsLayoutUtils::GetNearestScrollingView(aView);
if (sv) {
nsKeyEvent * keyEvent = (nsKeyEvent *)aEvent;
sv->ScrollByLines((keyEvent->keyCode == NS_VK_RIGHT) ? 1 : -1, 0);
@ -2193,7 +2194,7 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
nsKeyEvent * keyEvent = (nsKeyEvent *)aEvent;
if (keyEvent->charCode == 0x20) {
if (!mCurrentFocus) {
nsIScrollableView* sv = GetNearestScrollingView(aView);
nsIScrollableView* sv = nsLayoutUtils::GetNearestScrollingView(aView);
if (sv) {
sv->ScrollByPages(0, 1);
}
@ -2327,24 +2328,6 @@ nsEventStateManager::ClearFrameRefs(nsIFrame* aFrame)
return NS_OK;
}
nsIScrollableView*
nsEventStateManager::GetNearestScrollingView(nsIView* aView)
{
nsIScrollableView* sv = nsnull;
CallQueryInterface(aView, &sv);
if (sv) {
return sv;
}
nsIView* parent = aView->GetParent();
if (parent) {
return GetNearestScrollingView(parent);
}
return nsnull;
}
PRBool
nsEventStateManager::CheckDisabled(nsIContent* aContent)
{

View File

@ -207,7 +207,6 @@ protected:
nsIDocShellTreeItem** aResult);
// These functions are for mousewheel scrolling
nsIScrollableView* GetNearestScrollingView(nsIView* aView);
nsresult GetParentScrollingView(nsInputEvent* aEvent,
nsPresContext* aPresContext,
nsIFrame* &targetOuterFrame,

View File

@ -44,6 +44,7 @@
#include "nsIAtom.h"
#include "nsCSSPseudoElements.h"
#include "nsIView.h"
#include "nsIScrollableView.h"
/**
* A namespace class for static layout utilities.
@ -332,3 +333,18 @@ nsLayoutUtils::FindSiblingViewFor(nsIView* aParentView, nsIFrame* aFrame) {
}
return nsnull;
}
// static
nsIScrollableView*
nsLayoutUtils::GetNearestScrollingView(nsIView* aView)
{
NS_ASSERTION(aView, "GetNearestScrollingView expects a non-null view");
nsIScrollableView* scrollableView = nsnull;
for (; aView; aView = aView->GetParent()) {
CallQueryInterface(aView, &scrollableView);
if (scrollableView) {
break;
}
}
return scrollableView;
}

View File

@ -43,6 +43,7 @@ class nsPresContext;
class nsIContent;
class nsIAtom;
class nsIView;
class nsIScrollableView;
#include "prtypes.h"
#include "nsStyleContext.h"
@ -163,6 +164,15 @@ public:
static PRBool IsProperAncestorFrame(nsIFrame* aAncestorFrame, nsIFrame* aFrame,
nsIFrame* aCommonAncestor = nsnull);
/**
* GetNearestScrollingView locates the first ancestor of aView (or
* aView itself) that is scrollable.
*
* @param aView the view we're looking at
* @return the nearest scrollable view or nsnull if not found
*/
static nsIScrollableView* GetNearestScrollingView(nsIView* aView);
/**
* HasPseudoStyle returns PR_TRUE if aContent (whose primary style
* context is aStyleContext) has the aPseudoElement pseudo-style

View File

@ -1357,9 +1357,12 @@ protected:
friend struct ReflowEvent;
// utility to determine if we're in the middle of a drag
// Utility to determine if we're in the middle of a drag.
PRBool IsDragInProgress ( ) const ;
// Utility to find which view to scroll.
nsIScrollableView* GetViewToScroll();
PRBool mCaretEnabled;
#ifdef IBMBIDI
PRUint8 mBidiLevel; // The Bidi level of the cursor
@ -3228,92 +3231,68 @@ PresShell::PageMove(PRBool aForward, PRBool aExtend)
NS_IMETHODIMP
PresShell::ScrollPage(PRBool aForward)
{
nsIViewManager* viewManager = GetViewManager();
nsresult result = NS_OK;
if (viewManager)
{
nsIScrollableView *scrollView;
result = viewManager->GetRootScrollableView(&scrollView);
if (NS_SUCCEEDED(result) && scrollView)
{
scrollView->ScrollByPages(0, aForward ? 1 : -1);
}
nsIScrollableView* scrollView = GetViewToScroll();
if (scrollView) {
scrollView->ScrollByPages(0, aForward ? 1 : -1);
}
return result;
return NS_OK;
}
NS_IMETHODIMP
PresShell::ScrollLine(PRBool aForward)
{
nsIViewManager* viewManager = GetViewManager();
nsresult result = NS_OK;
if (viewManager)
{
nsIScrollableView *scrollView;
result = viewManager->GetRootScrollableView(&scrollView);
if (NS_SUCCEEDED(result) && scrollView)
{
nsIScrollableView* scrollView = GetViewToScroll();
if (scrollView) {
#ifdef MOZ_WIDGET_COCOA
// Emulate the Mac IE behavior of scrolling a minimum of 2 lines
// rather than 1. This vastly improves scrolling speed.
scrollView->ScrollByLines(0, aForward ? 2 : -2);
// Emulate the Mac IE behavior of scrolling a minimum of 2 lines
// rather than 1. This vastly improves scrolling speed.
scrollView->ScrollByLines(0, aForward ? 2 : -2);
#else
scrollView->ScrollByLines(0, aForward ? 1 : -1);
scrollView->ScrollByLines(0, aForward ? 1 : -1);
#endif
//NEW FOR LINES
// force the update to happen now, otherwise multiple scrolls can
// occur before the update is processed. (bug #7354)
// force the update to happen now, otherwise multiple scrolls can
// occur before the update is processed. (bug #7354)
// I'd use Composite here, but it doesn't always work.
// vm->Composite();
// I'd use Composite here, but it doesn't always work.
// vm->Composite();
nsIViewManager* viewManager = GetViewManager();
if (viewManager) {
viewManager->ForceUpdate();
}
}
return result;
return NS_OK;
}
NS_IMETHODIMP
PresShell::ScrollHorizontal(PRBool aLeft)
{
nsIViewManager* viewManager = GetViewManager();
nsresult result = NS_OK;
if (viewManager)
{
nsIScrollableView *scrollView;
result = viewManager->GetRootScrollableView(&scrollView);
if (NS_SUCCEEDED(result) && scrollView)
{
scrollView->ScrollByLines(aLeft ? -1 : 1, 0);
nsIScrollableView* scrollView = GetViewToScroll();
if (scrollView) {
scrollView->ScrollByLines(aLeft ? -1 : 1, 0);
//NEW FOR LINES
// force the update to happen now, otherwise multiple scrolls can
// occur before the update is processed. (bug #7354)
// force the update to happen now, otherwise multiple scrolls can
// occur before the update is processed. (bug #7354)
// I'd use Composite here, but it doesn't always work.
// vm->Composite();
// I'd use Composite here, but it doesn't always work.
// vm->Composite();
nsIViewManager* viewManager = GetViewManager();
if (viewManager) {
viewManager->ForceUpdate();
}
}
return result;
return NS_OK;
}
NS_IMETHODIMP
PresShell::CompleteScroll(PRBool aForward)
{
nsIViewManager* viewManager = GetViewManager();
nsresult result = NS_OK;
if (viewManager)
{
nsIScrollableView *scrollView;
result = viewManager->GetRootScrollableView(&scrollView);
if (NS_SUCCEEDED(result) && scrollView)
{
scrollView->ScrollByWhole(!aForward);//TRUE = top, aForward TRUE=bottom
}
nsIScrollableView* scrollView = GetViewToScroll();
if (scrollView) {
scrollView->ScrollByWhole(!aForward);//TRUE = top, aForward TRUE=bottom
}
return result;
return NS_OK;
}
NS_IMETHODIMP
@ -3774,6 +3753,36 @@ PresShell :: IsDragInProgress ( ) const
} // IsDragInProgress
nsIScrollableView*
PresShell::GetViewToScroll()
{
nsCOMPtr<nsIEventStateManager> esm = mPresContext->EventStateManager();
nsIFrame* selectionFrame = nsnull;
nsIScrollableView* scrollView = nsnull;
nsCOMPtr<nsIContent> selectionContent, endSelectionContent; // NOT USED
PRUint32 selectionOffset; // NOT USED
esm->GetDocSelectionLocation(getter_AddRefs(selectionContent),
getter_AddRefs(endSelectionContent),
&selectionFrame,
&selectionOffset);
if (selectionFrame) {
nsCOMPtr<nsIScrollableViewProvider> svp = do_QueryInterface(selectionFrame);
if (svp) {
svp->GetScrollableView(mPresContext, &scrollView);
} else {
nsIView* selectionView = selectionFrame->GetClosestView();
if (selectionView)
scrollView = nsLayoutUtils::GetNearestScrollingView(selectionView);
}
}
if (!scrollView) {
nsIViewManager* viewManager = GetViewManager();
if (viewManager) {
viewManager->GetRootScrollableView(&scrollView);
}
}
return scrollView;
}
NS_IMETHODIMP
PresShell::CancelReflowCommandInternal(nsIFrame* aTargetFrame,

View File

@ -43,6 +43,7 @@ class nsPresContext;
class nsIContent;
class nsIAtom;
class nsIView;
class nsIScrollableView;
#include "prtypes.h"
#include "nsStyleContext.h"
@ -163,6 +164,15 @@ public:
static PRBool IsProperAncestorFrame(nsIFrame* aAncestorFrame, nsIFrame* aFrame,
nsIFrame* aCommonAncestor = nsnull);
/**
* GetNearestScrollingView locates the first ancestor of aView (or
* aView itself) that is scrollable.
*
* @param aView the view we're looking at
* @return the nearest scrollable view or nsnull if not found
*/
static nsIScrollableView* GetNearestScrollingView(nsIView* aView);
/**
* HasPseudoStyle returns PR_TRUE if aContent (whose primary style
* context is aStyleContext) has the aPseudoElement pseudo-style

View File

@ -44,6 +44,7 @@
#include "nsIAtom.h"
#include "nsCSSPseudoElements.h"
#include "nsIView.h"
#include "nsIScrollableView.h"
/**
* A namespace class for static layout utilities.
@ -332,3 +333,18 @@ nsLayoutUtils::FindSiblingViewFor(nsIView* aParentView, nsIFrame* aFrame) {
}
return nsnull;
}
// static
nsIScrollableView*
nsLayoutUtils::GetNearestScrollingView(nsIView* aView)
{
NS_ASSERTION(aView, "GetNearestScrollingView expects a non-null view");
nsIScrollableView* scrollableView = nsnull;
for (; aView; aView = aView->GetParent()) {
CallQueryInterface(aView, &scrollableView);
if (scrollableView) {
break;
}
}
return scrollableView;
}

View File

@ -74,6 +74,7 @@
#include "nsILineIterator.h"
#include "nsLayoutAtoms.h"
#include "nsIFrameTraversal.h"
#include "nsLayoutUtils.h"
#include "nsLayoutCID.h"
static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID);
@ -245,7 +246,6 @@ public:
nsresult ScrollPointIntoClipView(nsPresContext *aPresContext, nsIView *aView, nsPoint& aPoint, PRBool *aDidScroll);
nsresult ScrollPointIntoView(nsPresContext *aPresContext, nsIView *aView, nsPoint& aPoint, PRBool aScrollParentViews, PRBool *aDidScroll);
nsresult GetViewAncestorOffset(nsIView *aView, nsIView *aAncestorView, nscoord *aXOffset, nscoord *aYOffset);
nsresult GetClosestScrollableView(nsIView *aView, nsIScrollableView **aScrollableView);
SelectionType GetType(){return mType;}
void SetType(SelectionType aType){mType = aType;}
@ -5284,26 +5284,6 @@ nsTypedSelection::GetViewAncestorOffset(nsIView *aView, nsIView *aAncestorView,
return NS_OK;
}
nsresult
nsTypedSelection::GetClosestScrollableView(nsIView *aView, nsIScrollableView **aScrollableView)
{
if (!aView || !aScrollableView)
return NS_ERROR_FAILURE;
*aScrollableView = 0;
while (!*aScrollableView && aView)
{
CallQueryInterface(aView, aScrollableView);
if (!*aScrollableView)
{
aView = aView->GetParent();
}
}
return NS_OK;
}
nsresult
nsTypedSelection::ScrollPointIntoClipView(nsPresContext *aPresContext, nsIView *aView, nsPoint& aPoint, PRBool *aDidScroll)
{
@ -5318,12 +5298,7 @@ nsTypedSelection::ScrollPointIntoClipView(nsPresContext *aPresContext, nsIView *
// Get aView's scrollable view.
//
nsIScrollableView *scrollableView = 0;
result = GetClosestScrollableView(aView, &scrollableView);
if (NS_FAILED(result))
return result;
nsIScrollableView *scrollableView = nsLayoutUtils::GetNearestScrollingView(aView);
if (!scrollableView)
return NS_OK; // Nothing to do!
@ -5513,12 +5488,7 @@ nsTypedSelection::ScrollPointIntoView(nsPresContext *aPresContext, nsIView *aVie
// Find aView's parent scrollable view.
//
nsIScrollableView *scrollableView = 0;
result = GetClosestScrollableView(aView, &scrollableView);
if (NS_FAILED(result))
return result;
nsIScrollableView *scrollableView = nsLayoutUtils::GetNearestScrollingView(aView);
if (scrollableView)
{
@ -5542,10 +5512,7 @@ nsTypedSelection::ScrollPointIntoView(nsPresContext *aPresContext, nsIView *aVie
while (view)
{
result = GetClosestScrollableView(view, &scrollableView);
if (NS_FAILED(result))
return result;
scrollableView = nsLayoutUtils::GetNearestScrollingView(view);
if (!scrollableView)
break;
@ -7015,10 +6982,7 @@ nsTypedSelection::GetSelectionRegionRectAndScrollableView(SelectionRegion aRegio
nsIView* view = parentWithView->GetView();
result = GetClosestScrollableView(view, aScrollableView);
if (NS_FAILED(result))
return result;
*aScrollableView = nsLayoutUtils::GetNearestScrollingView(view);
if (!*aScrollableView)
return NS_OK;
@ -7265,12 +7229,7 @@ nsTypedSelection::ScrollRectIntoView(nsIScrollableView *aScrollableView,
if (view)
{
nsIScrollableView *parentSV = 0;
rv = GetClosestScrollableView(view, &parentSV);
if (NS_FAILED(rv))
return rv;
nsIScrollableView *parentSV = nsLayoutUtils::GetNearestScrollingView(view);
if (parentSV)
{

View File

@ -1357,9 +1357,12 @@ protected:
friend struct ReflowEvent;
// utility to determine if we're in the middle of a drag
// Utility to determine if we're in the middle of a drag.
PRBool IsDragInProgress ( ) const ;
// Utility to find which view to scroll.
nsIScrollableView* GetViewToScroll();
PRBool mCaretEnabled;
#ifdef IBMBIDI
PRUint8 mBidiLevel; // The Bidi level of the cursor
@ -3228,92 +3231,68 @@ PresShell::PageMove(PRBool aForward, PRBool aExtend)
NS_IMETHODIMP
PresShell::ScrollPage(PRBool aForward)
{
nsIViewManager* viewManager = GetViewManager();
nsresult result = NS_OK;
if (viewManager)
{
nsIScrollableView *scrollView;
result = viewManager->GetRootScrollableView(&scrollView);
if (NS_SUCCEEDED(result) && scrollView)
{
scrollView->ScrollByPages(0, aForward ? 1 : -1);
}
nsIScrollableView* scrollView = GetViewToScroll();
if (scrollView) {
scrollView->ScrollByPages(0, aForward ? 1 : -1);
}
return result;
return NS_OK;
}
NS_IMETHODIMP
PresShell::ScrollLine(PRBool aForward)
{
nsIViewManager* viewManager = GetViewManager();
nsresult result = NS_OK;
if (viewManager)
{
nsIScrollableView *scrollView;
result = viewManager->GetRootScrollableView(&scrollView);
if (NS_SUCCEEDED(result) && scrollView)
{
nsIScrollableView* scrollView = GetViewToScroll();
if (scrollView) {
#ifdef MOZ_WIDGET_COCOA
// Emulate the Mac IE behavior of scrolling a minimum of 2 lines
// rather than 1. This vastly improves scrolling speed.
scrollView->ScrollByLines(0, aForward ? 2 : -2);
// Emulate the Mac IE behavior of scrolling a minimum of 2 lines
// rather than 1. This vastly improves scrolling speed.
scrollView->ScrollByLines(0, aForward ? 2 : -2);
#else
scrollView->ScrollByLines(0, aForward ? 1 : -1);
scrollView->ScrollByLines(0, aForward ? 1 : -1);
#endif
//NEW FOR LINES
// force the update to happen now, otherwise multiple scrolls can
// occur before the update is processed. (bug #7354)
// force the update to happen now, otherwise multiple scrolls can
// occur before the update is processed. (bug #7354)
// I'd use Composite here, but it doesn't always work.
// vm->Composite();
// I'd use Composite here, but it doesn't always work.
// vm->Composite();
nsIViewManager* viewManager = GetViewManager();
if (viewManager) {
viewManager->ForceUpdate();
}
}
return result;
return NS_OK;
}
NS_IMETHODIMP
PresShell::ScrollHorizontal(PRBool aLeft)
{
nsIViewManager* viewManager = GetViewManager();
nsresult result = NS_OK;
if (viewManager)
{
nsIScrollableView *scrollView;
result = viewManager->GetRootScrollableView(&scrollView);
if (NS_SUCCEEDED(result) && scrollView)
{
scrollView->ScrollByLines(aLeft ? -1 : 1, 0);
nsIScrollableView* scrollView = GetViewToScroll();
if (scrollView) {
scrollView->ScrollByLines(aLeft ? -1 : 1, 0);
//NEW FOR LINES
// force the update to happen now, otherwise multiple scrolls can
// occur before the update is processed. (bug #7354)
// force the update to happen now, otherwise multiple scrolls can
// occur before the update is processed. (bug #7354)
// I'd use Composite here, but it doesn't always work.
// vm->Composite();
// I'd use Composite here, but it doesn't always work.
// vm->Composite();
nsIViewManager* viewManager = GetViewManager();
if (viewManager) {
viewManager->ForceUpdate();
}
}
return result;
return NS_OK;
}
NS_IMETHODIMP
PresShell::CompleteScroll(PRBool aForward)
{
nsIViewManager* viewManager = GetViewManager();
nsresult result = NS_OK;
if (viewManager)
{
nsIScrollableView *scrollView;
result = viewManager->GetRootScrollableView(&scrollView);
if (NS_SUCCEEDED(result) && scrollView)
{
scrollView->ScrollByWhole(!aForward);//TRUE = top, aForward TRUE=bottom
}
nsIScrollableView* scrollView = GetViewToScroll();
if (scrollView) {
scrollView->ScrollByWhole(!aForward);//TRUE = top, aForward TRUE=bottom
}
return result;
return NS_OK;
}
NS_IMETHODIMP
@ -3774,6 +3753,36 @@ PresShell :: IsDragInProgress ( ) const
} // IsDragInProgress
nsIScrollableView*
PresShell::GetViewToScroll()
{
nsCOMPtr<nsIEventStateManager> esm = mPresContext->EventStateManager();
nsIFrame* selectionFrame = nsnull;
nsIScrollableView* scrollView = nsnull;
nsCOMPtr<nsIContent> selectionContent, endSelectionContent; // NOT USED
PRUint32 selectionOffset; // NOT USED
esm->GetDocSelectionLocation(getter_AddRefs(selectionContent),
getter_AddRefs(endSelectionContent),
&selectionFrame,
&selectionOffset);
if (selectionFrame) {
nsCOMPtr<nsIScrollableViewProvider> svp = do_QueryInterface(selectionFrame);
if (svp) {
svp->GetScrollableView(mPresContext, &scrollView);
} else {
nsIView* selectionView = selectionFrame->GetClosestView();
if (selectionView)
scrollView = nsLayoutUtils::GetNearestScrollingView(selectionView);
}
}
if (!scrollView) {
nsIViewManager* viewManager = GetViewManager();
if (viewManager) {
viewManager->GetRootScrollableView(&scrollView);
}
}
return scrollView;
}
NS_IMETHODIMP
PresShell::CancelReflowCommandInternal(nsIFrame* aTargetFrame,