Fix mouse-wheel scrolling for overflow:scroll elements. b=97283 r=roc sr=dbaron

This commit is contained in:
mats.palmgren%bredband.net 2004-08-07 14:30:30 +00:00
Родитель 7082bf7898
Коммит 410a676e29
2 изменённых файлов: 73 добавлений и 89 удалений

Просмотреть файл

@ -51,6 +51,7 @@
#include "nsHTMLAtoms.h"
#include "nsIEditorDocShell.h"
#include "nsIFormControl.h"
#include "nsIComboboxControlFrame.h"
#include "nsIDOMHTMLAnchorElement.h"
#include "nsIDOMHTMLInputElement.h"
#include "nsIDOMNSHTMLInputElement.h"
@ -77,7 +78,6 @@
#include "nsPIDOMWindow.h"
#include "nsIDOMEventTarget.h"
#include "nsIEnumerator.h"
#include "nsFrameTraversal.h"
#include "nsIDocShellTreeItem.h"
#include "nsIDocShellTreeNode.h"
#include "nsIWebNavigation.h"
@ -1632,15 +1632,13 @@ nsEventStateManager::DoScrollTextsize(nsIFrame *aTargetFrame,
}
}
//
nsresult
nsEventStateManager::DoScrollText(nsPresContext* aPresContext,
nsIFrame* aTargetFrame,
nsInputEvent* aEvent,
PRInt32 aNumLines,
PRBool aScrollHorizontal,
PRBool aScrollPage,
PRBool aUseTargetFrame)
PRBool aScrollPage)
{
nsCOMPtr<nsIContent> targetContent = aTargetFrame->GetContent();
if (!targetContent)
@ -1684,106 +1682,93 @@ nsEventStateManager::DoScrollText(nsPresContext* aPresContext,
}
}
nsIView* focusView = nsnull;
nsIScrollableView* sv = nsnull;
nsIFrame* focusFrame = nsnull;
nsIFrame* scrollFrame = aTargetFrame;
nsIScrollableView* scrollView = nsnull;
PRBool passToParent = PR_TRUE;
nsIPresShell *presShell = aPresContext->PresShell();
// Otherwise, check for a focused content element
nsCOMPtr<nsIContent> focusContent;
if (mCurrentFocus) {
GetFocusedFrame(&focusFrame);
}
else {
// If there is no focused content, get the document content
EnsureDocument(presShell);
focusContent = mDocument->GetRootContent();
if (!focusContent)
return NS_ERROR_FAILURE;
}
if (aUseTargetFrame)
focusFrame = aTargetFrame;
else if (!focusFrame)
presShell->GetPrimaryFrameFor(focusContent, &focusFrame);
if (!focusFrame)
return NS_ERROR_FAILURE;
// Now check whether this frame wants to provide us with an
// nsIScrollableView to use for scrolling.
nsCOMPtr<nsIScrollableViewProvider> svp = do_QueryInterface(focusFrame);
if (svp) {
svp->GetScrollableView(aPresContext, &sv);
if (sv)
CallQueryInterface(sv, &focusView);
} else {
focusView = focusFrame->GetClosestView();
if (!focusView)
return NS_ERROR_FAILURE;
sv = nsLayoutUtils::GetNearestScrollingView(focusView);
}
PRBool passToParent;
if (sv) {
// If we're already at the scroll limit for this view, scroll the
// parent view instead.
// If the view has a 0 line height, it will not scroll.
while (scrollFrame && passToParent) {
// Check whether the frame wants to provide us with a scrollable view.
scrollView = nsnull;
nsCOMPtr<nsIScrollableViewProvider> svp = do_QueryInterface(scrollFrame);
if (svp) {
svp->GetScrollableView(aPresContext, &scrollView);
}
if (!scrollView) {
scrollFrame = scrollFrame->GetParent();
continue;
}
// Check if the scrollable view can be scrolled any further.
nscoord lineHeight;
sv->GetLineHeight(&lineHeight);
scrollView->GetLineHeight(&lineHeight);
if (lineHeight == 0) {
passToParent = PR_TRUE;
} else {
if (lineHeight != 0) {
nscoord xPos, yPos;
sv->GetScrollPosition(xPos, yPos);
scrollView->GetScrollPosition(xPos, yPos);
if (aNumLines < 0) {
passToParent = aScrollHorizontal ? (xPos <= 0) : (yPos <= 0);
} else {
nsSize scrolledSize;
sv->GetContainerSize(&scrolledSize.width, &scrolledSize.height);
scrollView->GetContainerSize(&scrolledSize.width, &scrolledSize.height);
nsIView* portView = nsnull;
CallQueryInterface(sv, &portView);
if (!portView)
return NS_ERROR_FAILURE;
nsRect portRect = portView->GetBounds();
CallQueryInterface(scrollView, &portView);
if (portView) {
nsRect portRect = portView->GetBounds();
passToParent = (aScrollHorizontal ?
(xPos + portRect.width >= scrolledSize.width) :
(yPos + portRect.height >= scrolledSize.height));
passToParent = (aScrollHorizontal ?
(xPos + portRect.width >= scrolledSize.width) :
(yPos + portRect.height >= scrolledSize.height));
} else {
NS_WARNING("failed to get view from scrollview");
}
}
// Comboboxes need special care.
nsIComboboxControlFrame* comboBox = nsnull;
CallQueryInterface(scrollFrame, &comboBox);
if (comboBox) {
PRBool isDroppedDown = PR_FALSE;
comboBox->IsDroppedDown(&isDroppedDown);
if (isDroppedDown) {
// Don't propagate to parent when drop down menu is active.
if (passToParent) {
passToParent = PR_FALSE;
scrollView = nsnull;
}
} else {
// Always propagate when not dropped down (even if focused).
passToParent = PR_TRUE;
}
}
}
if (!passToParent) {
PRInt32 scrollX = 0;
PRInt32 scrollY = aNumLines;
scrollFrame = scrollFrame->GetParent();
}
if (aScrollPage)
scrollY = (scrollY > 0) ? 1 : -1;
if (!passToParent && scrollView) {
PRInt32 scrollX = 0;
PRInt32 scrollY = aNumLines;
if (aScrollHorizontal)
{
scrollX = scrollY;
scrollY = 0;
}
if (aScrollPage)
sv->ScrollByPages(scrollX, scrollY);
else
sv->ScrollByLines(scrollX, scrollY);
if (focusView)
ForceViewUpdate(focusView);
if (aScrollPage)
scrollY = (scrollY > 0) ? 1 : -1;
if (aScrollHorizontal) {
scrollX = scrollY;
scrollY = 0;
}
} else
passToParent = PR_TRUE;
if (aScrollPage)
scrollView->ScrollByPages(scrollX, scrollY);
else
scrollView->ScrollByLines(scrollX, scrollY);
nsIView* updateView = nsnull;
CallQueryInterface(scrollView, &updateView);
if (updateView)
ForceViewUpdate(updateView);
}
if (passToParent) {
nsresult rv;
nsIFrame* newFrame = nsnull;
@ -1793,7 +1778,7 @@ nsEventStateManager::DoScrollText(nsPresContext* aPresContext,
*getter_AddRefs(newPresContext));
if (NS_SUCCEEDED(rv) && newFrame)
return DoScrollText(newPresContext, newFrame, aEvent, aNumLines,
aScrollHorizontal, aScrollPage, PR_TRUE);
aScrollHorizontal, aScrollPage);
else
return NS_ERROR_FAILURE;
}
@ -2062,7 +2047,7 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
{
DoScrollText(aPresContext, aTargetFrame, msEvent, numLines,
(msEvent->scrollFlags & nsMouseScrollEvent::kIsHorizontal),
(action == MOUSE_SCROLL_PAGE), PR_FALSE);
(action == MOUSE_SCROLL_PAGE));
}
break;

Просмотреть файл

@ -216,8 +216,7 @@ protected:
nsInputEvent* aEvent,
PRInt32 aNumLines,
PRBool aScrollHorizontal,
PRBool aScrollPage,
PRBool aUseTargetFrame);
PRBool aScrollPage);
void ForceViewUpdate(nsIView* aView);
void DoScrollHistory(PRInt32 direction);
void DoScrollTextsize(nsIFrame *aTargetFrame, PRInt32 adjustment);