зеркало из https://github.com/mozilla/gecko-dev.git
Don't allow the user to scroll things that are 'overflow: hidden'. b=259615 r+sr=roc
This commit is contained in:
Родитель
88acc07ddd
Коммит
feb3d9aee8
|
@ -5243,7 +5243,8 @@ nsTypedSelection::ScrollPointIntoClipView(nsPresContext *aPresContext, nsIView *
|
|||
// Get aView's scrollable view.
|
||||
//
|
||||
|
||||
nsIScrollableView *scrollableView = nsLayoutUtils::GetNearestScrollingView(aView);
|
||||
nsIScrollableView *scrollableView =
|
||||
nsLayoutUtils::GetNearestScrollingView(aView, nsLayoutUtils::eEither);
|
||||
|
||||
if (!scrollableView)
|
||||
return NS_OK; // Nothing to do!
|
||||
|
@ -5287,25 +5288,33 @@ nsTypedSelection::ScrollPointIntoClipView(nsPresContext *aPresContext, nsIView *
|
|||
//
|
||||
|
||||
nscoord dx = 0, dy = 0;
|
||||
nsPoint ePoint = aPoint;
|
||||
|
||||
ePoint.x += viewOffset.x;
|
||||
ePoint.y += viewOffset.y;
|
||||
nsPresContext::ScrollbarStyles ss =
|
||||
nsLayoutUtils::ScrollbarStylesOfView(scrollableView);
|
||||
|
||||
if (ss.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN) {
|
||||
nscoord e = aPoint.x + viewOffset.x;
|
||||
|
||||
nscoord x1 = bounds.x;
|
||||
nscoord x2 = bounds.x + bounds.width;
|
||||
nscoord y1 = bounds.y;
|
||||
nscoord y2 = bounds.y + bounds.height;
|
||||
nscoord x1 = bounds.x;
|
||||
nscoord x2 = bounds.x + bounds.width;
|
||||
|
||||
if (ePoint.x < x1)
|
||||
dx = ePoint.x - x1;
|
||||
else if (ePoint.x > x2)
|
||||
dx = ePoint.x - x2;
|
||||
|
||||
if (ePoint.y < y1)
|
||||
dy = ePoint.y - y1;
|
||||
else if (ePoint.y > y2)
|
||||
dy = ePoint.y - y2;
|
||||
if (e < x1)
|
||||
dx = e - x1;
|
||||
else if (e > x2)
|
||||
dx = e - x2;
|
||||
}
|
||||
|
||||
if (ss.mVertical != NS_STYLE_OVERFLOW_HIDDEN) {
|
||||
nscoord e = aPoint.y + viewOffset.y;
|
||||
|
||||
nscoord y1 = bounds.y;
|
||||
nscoord y2 = bounds.y + bounds.height;
|
||||
|
||||
if (e < y1)
|
||||
dy = e - y1;
|
||||
else if (e > y2)
|
||||
dy = e - y2;
|
||||
}
|
||||
|
||||
//
|
||||
// Now clip the scroll amounts so that we don't scroll
|
||||
|
@ -5326,7 +5335,7 @@ nsTypedSelection::ScrollPointIntoClipView(nsPresContext *aPresContext, nsIView *
|
|||
dx = 0;
|
||||
else if (dx > 0)
|
||||
{
|
||||
x1 = scrollX + dx + bounds.width;
|
||||
nscoord x1 = scrollX + dx + bounds.width;
|
||||
|
||||
if (x1 > docWidth)
|
||||
dx -= x1 - docWidth;
|
||||
|
@ -5337,7 +5346,7 @@ nsTypedSelection::ScrollPointIntoClipView(nsPresContext *aPresContext, nsIView *
|
|||
dy = 0;
|
||||
else if (dy > 0)
|
||||
{
|
||||
y1 = scrollY + dy + bounds.height;
|
||||
nscoord y1 = scrollY + dy + bounds.height;
|
||||
|
||||
if (y1 > docHeight)
|
||||
dy -= y1 - docHeight;
|
||||
|
@ -5420,7 +5429,8 @@ nsTypedSelection::ScrollPointIntoView(nsPresContext *aPresContext, nsIView *aVie
|
|||
// Find aView's parent scrollable view.
|
||||
//
|
||||
|
||||
nsIScrollableView *scrollableView = nsLayoutUtils::GetNearestScrollingView(aView);
|
||||
nsIScrollableView *scrollableView =
|
||||
nsLayoutUtils::GetNearestScrollingView(aView, nsLayoutUtils::eEither);
|
||||
|
||||
if (scrollableView)
|
||||
{
|
||||
|
@ -5442,7 +5452,9 @@ nsTypedSelection::ScrollPointIntoView(nsPresContext *aPresContext, nsIView *aVie
|
|||
|
||||
while (view)
|
||||
{
|
||||
scrollableView = nsLayoutUtils::GetNearestScrollingView(view);
|
||||
scrollableView =
|
||||
nsLayoutUtils::GetNearestScrollingView(view,
|
||||
nsLayoutUtils::eEither);
|
||||
|
||||
if (!scrollableView)
|
||||
break;
|
||||
|
@ -6886,7 +6898,8 @@ nsTypedSelection::GetSelectionRegionRectAndScrollableView(SelectionRegion aRegio
|
|||
|
||||
nsIView* view = parentWithView->GetView();
|
||||
|
||||
*aScrollableView = nsLayoutUtils::GetNearestScrollingView(view);
|
||||
*aScrollableView =
|
||||
nsLayoutUtils::GetNearestScrollingView(view, nsLayoutUtils::eEither);
|
||||
|
||||
if (!*aScrollableView)
|
||||
return NS_OK;
|
||||
|
@ -7049,47 +7062,54 @@ nsTypedSelection::ScrollRectIntoView(nsIScrollableView *aScrollableView,
|
|||
nscoord scrollOffsetX = visibleRect.x;
|
||||
nscoord scrollOffsetY = visibleRect.y;
|
||||
|
||||
nsPresContext::ScrollbarStyles ss =
|
||||
nsLayoutUtils::ScrollbarStylesOfView(aScrollableView);
|
||||
|
||||
// See how aRect should be positioned vertically
|
||||
if (NS_PRESSHELL_SCROLL_ANYWHERE == aVPercent) {
|
||||
// The caller doesn't care where aRect is positioned vertically,
|
||||
// so long as it's fully visible
|
||||
if (aRect.y < visibleRect.y) {
|
||||
// Scroll up so aRect's top edge is visible
|
||||
scrollOffsetY = aRect.y;
|
||||
} else if (aRect.YMost() > visibleRect.YMost()) {
|
||||
// Scroll down so aRect's bottom edge is visible. Make sure
|
||||
// aRect's top edge is still visible
|
||||
scrollOffsetY += aRect.YMost() - visibleRect.YMost();
|
||||
if (scrollOffsetY > aRect.y) {
|
||||
if (ss.mVertical != NS_STYLE_OVERFLOW_HIDDEN) {
|
||||
if (NS_PRESSHELL_SCROLL_ANYWHERE == aVPercent) {
|
||||
// The caller doesn't care where aRect is positioned vertically,
|
||||
// so long as it's fully visible
|
||||
if (aRect.y < visibleRect.y) {
|
||||
// Scroll up so aRect's top edge is visible
|
||||
scrollOffsetY = aRect.y;
|
||||
} else if (aRect.YMost() > visibleRect.YMost()) {
|
||||
// Scroll down so aRect's bottom edge is visible. Make sure
|
||||
// aRect's top edge is still visible
|
||||
scrollOffsetY += aRect.YMost() - visibleRect.YMost();
|
||||
if (scrollOffsetY > aRect.y) {
|
||||
scrollOffsetY = aRect.y;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Align the aRect edge according to the specified percentage
|
||||
nscoord frameAlignY = aRect.y + (aRect.height * aVPercent) / 100;
|
||||
scrollOffsetY = frameAlignY - (visibleRect.height * aVPercent) / 100;
|
||||
}
|
||||
} else {
|
||||
// Align the aRect edge according to the specified percentage
|
||||
nscoord frameAlignY = aRect.y + (aRect.height * aVPercent) / 100;
|
||||
scrollOffsetY = frameAlignY - (visibleRect.height * aVPercent) / 100;
|
||||
}
|
||||
|
||||
// See how the aRect should be positioned horizontally
|
||||
if (NS_PRESSHELL_SCROLL_ANYWHERE == aHPercent) {
|
||||
// The caller doesn't care where the aRect is positioned horizontally,
|
||||
// so long as it's fully visible
|
||||
if (aRect.x < visibleRect.x) {
|
||||
// Scroll left so the aRect's left edge is visible
|
||||
scrollOffsetX = aRect.x;
|
||||
} else if (aRect.XMost() > visibleRect.XMost()) {
|
||||
// Scroll right so the aRect's right edge is visible. Make sure the
|
||||
// aRect's left edge is still visible
|
||||
scrollOffsetX += aRect.XMost() - visibleRect.XMost();
|
||||
if (scrollOffsetX > aRect.x) {
|
||||
if (ss.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN) {
|
||||
if (NS_PRESSHELL_SCROLL_ANYWHERE == aHPercent) {
|
||||
// The caller doesn't care where the aRect is positioned horizontally,
|
||||
// so long as it's fully visible
|
||||
if (aRect.x < visibleRect.x) {
|
||||
// Scroll left so the aRect's left edge is visible
|
||||
scrollOffsetX = aRect.x;
|
||||
} else if (aRect.XMost() > visibleRect.XMost()) {
|
||||
// Scroll right so the aRect's right edge is visible. Make sure the
|
||||
// aRect's left edge is still visible
|
||||
scrollOffsetX += aRect.XMost() - visibleRect.XMost();
|
||||
if (scrollOffsetX > aRect.x) {
|
||||
scrollOffsetX = aRect.x;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// Align the aRect edge according to the specified percentage
|
||||
nscoord frameAlignX = aRect.x + (aRect.width * aHPercent) / 100;
|
||||
scrollOffsetX = frameAlignX - (visibleRect.width * aHPercent) / 100;
|
||||
}
|
||||
|
||||
} else {
|
||||
// Align the aRect edge according to the specified percentage
|
||||
nscoord frameAlignX = aRect.x + (aRect.width * aHPercent) / 100;
|
||||
scrollOffsetX = frameAlignX - (visibleRect.width * aHPercent) / 100;
|
||||
}
|
||||
|
||||
aScrollableView->ScrollTo(scrollOffsetX, scrollOffsetY, NS_VMREFRESH_IMMEDIATE);
|
||||
|
@ -7118,7 +7138,8 @@ nsTypedSelection::ScrollRectIntoView(nsIScrollableView *aScrollableView,
|
|||
|
||||
if (view)
|
||||
{
|
||||
nsIScrollableView *parentSV = nsLayoutUtils::GetNearestScrollingView(view);
|
||||
nsIScrollableView *parentSV =
|
||||
nsLayoutUtils::GetNearestScrollingView(view, nsLayoutUtils::eEither);
|
||||
|
||||
if (parentSV)
|
||||
{
|
||||
|
|
|
@ -2083,7 +2083,7 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
|||
case NS_VK_PAGE_DOWN:
|
||||
case NS_VK_PAGE_UP:
|
||||
if (!mCurrentFocus) {
|
||||
nsIScrollableView* sv = nsLayoutUtils::GetNearestScrollingView(aView);
|
||||
nsIScrollableView* sv = nsLayoutUtils::GetNearestScrollingView(aView, nsLayoutUtils::eVertical);
|
||||
if (sv) {
|
||||
nsKeyEvent * keyEvent = (nsKeyEvent *)aEvent;
|
||||
sv->ScrollByPages(0, (keyEvent->keyCode != NS_VK_PAGE_UP) ? 1 : -1);
|
||||
|
@ -2093,7 +2093,7 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
|||
case NS_VK_HOME:
|
||||
case NS_VK_END:
|
||||
if (!mCurrentFocus) {
|
||||
nsIScrollableView* sv = nsLayoutUtils::GetNearestScrollingView(aView);
|
||||
nsIScrollableView* sv = nsLayoutUtils::GetNearestScrollingView(aView, nsLayoutUtils::eVertical);
|
||||
if (sv) {
|
||||
nsKeyEvent * keyEvent = (nsKeyEvent *)aEvent;
|
||||
sv->ScrollByWhole((keyEvent->keyCode != NS_VK_HOME) ? PR_FALSE : PR_TRUE);
|
||||
|
@ -2103,7 +2103,7 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
|||
case NS_VK_DOWN:
|
||||
case NS_VK_UP:
|
||||
if (!mCurrentFocus) {
|
||||
nsIScrollableView* sv = nsLayoutUtils::GetNearestScrollingView(aView);
|
||||
nsIScrollableView* sv = nsLayoutUtils::GetNearestScrollingView(aView, nsLayoutUtils::eVertical);
|
||||
if (sv) {
|
||||
nsKeyEvent * keyEvent = (nsKeyEvent *)aEvent;
|
||||
sv->ScrollByLines(0, (keyEvent->keyCode == NS_VK_DOWN) ? 1 : -1);
|
||||
|
@ -2122,7 +2122,7 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
|||
case NS_VK_LEFT:
|
||||
case NS_VK_RIGHT:
|
||||
if (!mCurrentFocus) {
|
||||
nsIScrollableView* sv = nsLayoutUtils::GetNearestScrollingView(aView);
|
||||
nsIScrollableView* sv = nsLayoutUtils::GetNearestScrollingView(aView, nsLayoutUtils::eHorizontal);
|
||||
if (sv) {
|
||||
nsKeyEvent * keyEvent = (nsKeyEvent *)aEvent;
|
||||
sv->ScrollByLines((keyEvent->keyCode == NS_VK_RIGHT) ? 1 : -1, 0);
|
||||
|
@ -2144,7 +2144,7 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
|||
nsKeyEvent * keyEvent = (nsKeyEvent *)aEvent;
|
||||
if (keyEvent->charCode == 0x20) {
|
||||
if (!mCurrentFocus) {
|
||||
nsIScrollableView* sv = nsLayoutUtils::GetNearestScrollingView(aView);
|
||||
nsIScrollableView* sv = nsLayoutUtils::GetNearestScrollingView(aView, nsLayoutUtils::eVertical);
|
||||
if (sv) {
|
||||
sv->ScrollByPages(0, 1);
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "nsIView.h"
|
||||
#include "nsIScrollableView.h"
|
||||
#include "nsPlaceholderFrame.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
|
||||
/**
|
||||
* A namespace class for static layout utilities.
|
||||
|
@ -348,16 +349,43 @@ nsLayoutUtils::FindSiblingViewFor(nsIView* aParentView, nsIFrame* aFrame) {
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
//static
|
||||
nsPresContext::ScrollbarStyles
|
||||
nsLayoutUtils::ScrollbarStylesOfView(nsIScrollableView *aScrollableView)
|
||||
{
|
||||
nsIView *view;
|
||||
CallQueryInterface(aScrollableView, &view);
|
||||
nsIFrame *frame = NS_STATIC_CAST(nsIFrame*, view->GetClientData());
|
||||
if (frame && ((frame = frame->GetParent()))) {
|
||||
nsIScrollableFrame *sf;
|
||||
CallQueryInterface(frame, &sf);
|
||||
if (sf)
|
||||
return sf->GetScrollbarStyles();
|
||||
}
|
||||
return nsPresContext::ScrollbarStyles(NS_STYLE_OVERFLOW_HIDDEN,
|
||||
NS_STYLE_OVERFLOW_HIDDEN);
|
||||
}
|
||||
|
||||
// static
|
||||
nsIScrollableView*
|
||||
nsLayoutUtils::GetNearestScrollingView(nsIView* aView)
|
||||
nsLayoutUtils::GetNearestScrollingView(nsIView* aView, Direction aDirection)
|
||||
{
|
||||
// Find the first view that has a scrollable frame whose
|
||||
// ScrollbarStyles is not NS_STYLE_OVERFLOW_HIDDEN in aDirection.
|
||||
NS_ASSERTION(aView, "GetNearestScrollingView expects a non-null view");
|
||||
nsIScrollableView* scrollableView = nsnull;
|
||||
for (; aView; aView = aView->GetParent()) {
|
||||
CallQueryInterface(aView, &scrollableView);
|
||||
if (scrollableView) {
|
||||
break;
|
||||
nsPresContext::ScrollbarStyles ss =
|
||||
nsLayoutUtils::ScrollbarStylesOfView(scrollableView);
|
||||
// aDirection can be eHorizontal, eVertical, or eEither
|
||||
if (aDirection != eHorizontal &&
|
||||
ss.mVertical != NS_STYLE_OVERFLOW_HIDDEN)
|
||||
break;
|
||||
if (aDirection != eVertical &&
|
||||
ss.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return scrollableView;
|
||||
|
|
|
@ -164,14 +164,23 @@ public:
|
|||
static PRBool IsProperAncestorFrame(nsIFrame* aAncestorFrame, nsIFrame* aFrame,
|
||||
nsIFrame* aCommonAncestor = nsnull);
|
||||
|
||||
static nsPresContext::ScrollbarStyles
|
||||
ScrollbarStylesOfView(nsIScrollableView *aScrollableView);
|
||||
|
||||
/**
|
||||
* GetNearestScrollingView locates the first ancestor of aView (or
|
||||
* aView itself) that is scrollable.
|
||||
* aView itself) that is scrollable. It does *not* count an
|
||||
* 'overflow' style of 'hidden' as scrollable, even though a scrolling
|
||||
* view is present. Thus, the direction of the scroll is needed as
|
||||
* an argument.
|
||||
*
|
||||
* @param aView the view we're looking at
|
||||
* @param aDirection Whether it's for horizontal or vertical scrolling.
|
||||
* @return the nearest scrollable view or nsnull if not found
|
||||
*/
|
||||
static nsIScrollableView* GetNearestScrollingView(nsIView* aView);
|
||||
enum Direction { eHorizontal, eVertical, eEither };
|
||||
static nsIScrollableView* GetNearestScrollingView(nsIView* aView,
|
||||
Direction aDirection);
|
||||
|
||||
/**
|
||||
* HasPseudoStyle returns PR_TRUE if aContent (whose primary style
|
||||
|
|
|
@ -1351,7 +1351,7 @@ protected:
|
|||
PRBool IsDragInProgress ( ) const ;
|
||||
|
||||
// Utility to find which view to scroll.
|
||||
nsIScrollableView* GetViewToScroll();
|
||||
nsIScrollableView* GetViewToScroll(nsLayoutUtils::Direction aDirection);
|
||||
|
||||
PRBool mCaretEnabled;
|
||||
#ifdef IBMBIDI
|
||||
|
@ -3138,7 +3138,7 @@ PresShell::PageMove(PRBool aForward, PRBool aExtend)
|
|||
NS_IMETHODIMP
|
||||
PresShell::ScrollPage(PRBool aForward)
|
||||
{
|
||||
nsIScrollableView* scrollView = GetViewToScroll();
|
||||
nsIScrollableView* scrollView = GetViewToScroll(nsLayoutUtils::eVertical);
|
||||
if (scrollView) {
|
||||
scrollView->ScrollByPages(0, aForward ? 1 : -1);
|
||||
}
|
||||
|
@ -3148,7 +3148,7 @@ PresShell::ScrollPage(PRBool aForward)
|
|||
NS_IMETHODIMP
|
||||
PresShell::ScrollLine(PRBool aForward)
|
||||
{
|
||||
nsIScrollableView* scrollView = GetViewToScroll();
|
||||
nsIScrollableView* scrollView = GetViewToScroll(nsLayoutUtils::eVertical);
|
||||
if (scrollView) {
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
// Emulate the Mac IE behavior of scrolling a minimum of 2 lines
|
||||
|
@ -3175,7 +3175,7 @@ PresShell::ScrollLine(PRBool aForward)
|
|||
NS_IMETHODIMP
|
||||
PresShell::ScrollHorizontal(PRBool aLeft)
|
||||
{
|
||||
nsIScrollableView* scrollView = GetViewToScroll();
|
||||
nsIScrollableView* scrollView = GetViewToScroll(nsLayoutUtils::eHorizontal);
|
||||
if (scrollView) {
|
||||
scrollView->ScrollByLines(aLeft ? -1 : 1, 0);
|
||||
//NEW FOR LINES
|
||||
|
@ -3195,7 +3195,7 @@ PresShell::ScrollHorizontal(PRBool aLeft)
|
|||
NS_IMETHODIMP
|
||||
PresShell::CompleteScroll(PRBool aForward)
|
||||
{
|
||||
nsIScrollableView* scrollView = GetViewToScroll();
|
||||
nsIScrollableView* scrollView = GetViewToScroll(nsLayoutUtils::eVertical);
|
||||
if (scrollView) {
|
||||
scrollView->ScrollByWhole(!aForward);//TRUE = top, aForward TRUE=bottom
|
||||
}
|
||||
|
@ -3654,7 +3654,7 @@ PresShell :: IsDragInProgress ( ) const
|
|||
} // IsDragInProgress
|
||||
|
||||
nsIScrollableView*
|
||||
PresShell::GetViewToScroll()
|
||||
PresShell::GetViewToScroll(nsLayoutUtils::Direction aDirection)
|
||||
{
|
||||
nsCOMPtr<nsIEventStateManager> esm = mPresContext->EventStateManager();
|
||||
nsIScrollableView* scrollView = nsnull;
|
||||
|
@ -3670,7 +3670,8 @@ PresShell::GetViewToScroll()
|
|||
} else {
|
||||
nsIView* startView = startFrame->GetClosestView();
|
||||
if (startView)
|
||||
scrollView = nsLayoutUtils::GetNearestScrollingView(startView);
|
||||
scrollView =
|
||||
nsLayoutUtils::GetNearestScrollingView(startView, aDirection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -164,14 +164,23 @@ public:
|
|||
static PRBool IsProperAncestorFrame(nsIFrame* aAncestorFrame, nsIFrame* aFrame,
|
||||
nsIFrame* aCommonAncestor = nsnull);
|
||||
|
||||
static nsPresContext::ScrollbarStyles
|
||||
ScrollbarStylesOfView(nsIScrollableView *aScrollableView);
|
||||
|
||||
/**
|
||||
* GetNearestScrollingView locates the first ancestor of aView (or
|
||||
* aView itself) that is scrollable.
|
||||
* aView itself) that is scrollable. It does *not* count an
|
||||
* 'overflow' style of 'hidden' as scrollable, even though a scrolling
|
||||
* view is present. Thus, the direction of the scroll is needed as
|
||||
* an argument.
|
||||
*
|
||||
* @param aView the view we're looking at
|
||||
* @param aDirection Whether it's for horizontal or vertical scrolling.
|
||||
* @return the nearest scrollable view or nsnull if not found
|
||||
*/
|
||||
static nsIScrollableView* GetNearestScrollingView(nsIView* aView);
|
||||
enum Direction { eHorizontal, eVertical, eEither };
|
||||
static nsIScrollableView* GetNearestScrollingView(nsIView* aView,
|
||||
Direction aDirection);
|
||||
|
||||
/**
|
||||
* HasPseudoStyle returns PR_TRUE if aContent (whose primary style
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "nsIView.h"
|
||||
#include "nsIScrollableView.h"
|
||||
#include "nsPlaceholderFrame.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
|
||||
/**
|
||||
* A namespace class for static layout utilities.
|
||||
|
@ -348,16 +349,43 @@ nsLayoutUtils::FindSiblingViewFor(nsIView* aParentView, nsIFrame* aFrame) {
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
//static
|
||||
nsPresContext::ScrollbarStyles
|
||||
nsLayoutUtils::ScrollbarStylesOfView(nsIScrollableView *aScrollableView)
|
||||
{
|
||||
nsIView *view;
|
||||
CallQueryInterface(aScrollableView, &view);
|
||||
nsIFrame *frame = NS_STATIC_CAST(nsIFrame*, view->GetClientData());
|
||||
if (frame && ((frame = frame->GetParent()))) {
|
||||
nsIScrollableFrame *sf;
|
||||
CallQueryInterface(frame, &sf);
|
||||
if (sf)
|
||||
return sf->GetScrollbarStyles();
|
||||
}
|
||||
return nsPresContext::ScrollbarStyles(NS_STYLE_OVERFLOW_HIDDEN,
|
||||
NS_STYLE_OVERFLOW_HIDDEN);
|
||||
}
|
||||
|
||||
// static
|
||||
nsIScrollableView*
|
||||
nsLayoutUtils::GetNearestScrollingView(nsIView* aView)
|
||||
nsLayoutUtils::GetNearestScrollingView(nsIView* aView, Direction aDirection)
|
||||
{
|
||||
// Find the first view that has a scrollable frame whose
|
||||
// ScrollbarStyles is not NS_STYLE_OVERFLOW_HIDDEN in aDirection.
|
||||
NS_ASSERTION(aView, "GetNearestScrollingView expects a non-null view");
|
||||
nsIScrollableView* scrollableView = nsnull;
|
||||
for (; aView; aView = aView->GetParent()) {
|
||||
CallQueryInterface(aView, &scrollableView);
|
||||
if (scrollableView) {
|
||||
break;
|
||||
nsPresContext::ScrollbarStyles ss =
|
||||
nsLayoutUtils::ScrollbarStylesOfView(scrollableView);
|
||||
// aDirection can be eHorizontal, eVertical, or eEither
|
||||
if (aDirection != eHorizontal &&
|
||||
ss.mVertical != NS_STYLE_OVERFLOW_HIDDEN)
|
||||
break;
|
||||
if (aDirection != eVertical &&
|
||||
ss.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return scrollableView;
|
||||
|
|
|
@ -5243,7 +5243,8 @@ nsTypedSelection::ScrollPointIntoClipView(nsPresContext *aPresContext, nsIView *
|
|||
// Get aView's scrollable view.
|
||||
//
|
||||
|
||||
nsIScrollableView *scrollableView = nsLayoutUtils::GetNearestScrollingView(aView);
|
||||
nsIScrollableView *scrollableView =
|
||||
nsLayoutUtils::GetNearestScrollingView(aView, nsLayoutUtils::eEither);
|
||||
|
||||
if (!scrollableView)
|
||||
return NS_OK; // Nothing to do!
|
||||
|
@ -5287,25 +5288,33 @@ nsTypedSelection::ScrollPointIntoClipView(nsPresContext *aPresContext, nsIView *
|
|||
//
|
||||
|
||||
nscoord dx = 0, dy = 0;
|
||||
nsPoint ePoint = aPoint;
|
||||
|
||||
ePoint.x += viewOffset.x;
|
||||
ePoint.y += viewOffset.y;
|
||||
nsPresContext::ScrollbarStyles ss =
|
||||
nsLayoutUtils::ScrollbarStylesOfView(scrollableView);
|
||||
|
||||
if (ss.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN) {
|
||||
nscoord e = aPoint.x + viewOffset.x;
|
||||
|
||||
nscoord x1 = bounds.x;
|
||||
nscoord x2 = bounds.x + bounds.width;
|
||||
nscoord y1 = bounds.y;
|
||||
nscoord y2 = bounds.y + bounds.height;
|
||||
nscoord x1 = bounds.x;
|
||||
nscoord x2 = bounds.x + bounds.width;
|
||||
|
||||
if (ePoint.x < x1)
|
||||
dx = ePoint.x - x1;
|
||||
else if (ePoint.x > x2)
|
||||
dx = ePoint.x - x2;
|
||||
|
||||
if (ePoint.y < y1)
|
||||
dy = ePoint.y - y1;
|
||||
else if (ePoint.y > y2)
|
||||
dy = ePoint.y - y2;
|
||||
if (e < x1)
|
||||
dx = e - x1;
|
||||
else if (e > x2)
|
||||
dx = e - x2;
|
||||
}
|
||||
|
||||
if (ss.mVertical != NS_STYLE_OVERFLOW_HIDDEN) {
|
||||
nscoord e = aPoint.y + viewOffset.y;
|
||||
|
||||
nscoord y1 = bounds.y;
|
||||
nscoord y2 = bounds.y + bounds.height;
|
||||
|
||||
if (e < y1)
|
||||
dy = e - y1;
|
||||
else if (e > y2)
|
||||
dy = e - y2;
|
||||
}
|
||||
|
||||
//
|
||||
// Now clip the scroll amounts so that we don't scroll
|
||||
|
@ -5326,7 +5335,7 @@ nsTypedSelection::ScrollPointIntoClipView(nsPresContext *aPresContext, nsIView *
|
|||
dx = 0;
|
||||
else if (dx > 0)
|
||||
{
|
||||
x1 = scrollX + dx + bounds.width;
|
||||
nscoord x1 = scrollX + dx + bounds.width;
|
||||
|
||||
if (x1 > docWidth)
|
||||
dx -= x1 - docWidth;
|
||||
|
@ -5337,7 +5346,7 @@ nsTypedSelection::ScrollPointIntoClipView(nsPresContext *aPresContext, nsIView *
|
|||
dy = 0;
|
||||
else if (dy > 0)
|
||||
{
|
||||
y1 = scrollY + dy + bounds.height;
|
||||
nscoord y1 = scrollY + dy + bounds.height;
|
||||
|
||||
if (y1 > docHeight)
|
||||
dy -= y1 - docHeight;
|
||||
|
@ -5420,7 +5429,8 @@ nsTypedSelection::ScrollPointIntoView(nsPresContext *aPresContext, nsIView *aVie
|
|||
// Find aView's parent scrollable view.
|
||||
//
|
||||
|
||||
nsIScrollableView *scrollableView = nsLayoutUtils::GetNearestScrollingView(aView);
|
||||
nsIScrollableView *scrollableView =
|
||||
nsLayoutUtils::GetNearestScrollingView(aView, nsLayoutUtils::eEither);
|
||||
|
||||
if (scrollableView)
|
||||
{
|
||||
|
@ -5442,7 +5452,9 @@ nsTypedSelection::ScrollPointIntoView(nsPresContext *aPresContext, nsIView *aVie
|
|||
|
||||
while (view)
|
||||
{
|
||||
scrollableView = nsLayoutUtils::GetNearestScrollingView(view);
|
||||
scrollableView =
|
||||
nsLayoutUtils::GetNearestScrollingView(view,
|
||||
nsLayoutUtils::eEither);
|
||||
|
||||
if (!scrollableView)
|
||||
break;
|
||||
|
@ -6886,7 +6898,8 @@ nsTypedSelection::GetSelectionRegionRectAndScrollableView(SelectionRegion aRegio
|
|||
|
||||
nsIView* view = parentWithView->GetView();
|
||||
|
||||
*aScrollableView = nsLayoutUtils::GetNearestScrollingView(view);
|
||||
*aScrollableView =
|
||||
nsLayoutUtils::GetNearestScrollingView(view, nsLayoutUtils::eEither);
|
||||
|
||||
if (!*aScrollableView)
|
||||
return NS_OK;
|
||||
|
@ -7049,47 +7062,54 @@ nsTypedSelection::ScrollRectIntoView(nsIScrollableView *aScrollableView,
|
|||
nscoord scrollOffsetX = visibleRect.x;
|
||||
nscoord scrollOffsetY = visibleRect.y;
|
||||
|
||||
nsPresContext::ScrollbarStyles ss =
|
||||
nsLayoutUtils::ScrollbarStylesOfView(aScrollableView);
|
||||
|
||||
// See how aRect should be positioned vertically
|
||||
if (NS_PRESSHELL_SCROLL_ANYWHERE == aVPercent) {
|
||||
// The caller doesn't care where aRect is positioned vertically,
|
||||
// so long as it's fully visible
|
||||
if (aRect.y < visibleRect.y) {
|
||||
// Scroll up so aRect's top edge is visible
|
||||
scrollOffsetY = aRect.y;
|
||||
} else if (aRect.YMost() > visibleRect.YMost()) {
|
||||
// Scroll down so aRect's bottom edge is visible. Make sure
|
||||
// aRect's top edge is still visible
|
||||
scrollOffsetY += aRect.YMost() - visibleRect.YMost();
|
||||
if (scrollOffsetY > aRect.y) {
|
||||
if (ss.mVertical != NS_STYLE_OVERFLOW_HIDDEN) {
|
||||
if (NS_PRESSHELL_SCROLL_ANYWHERE == aVPercent) {
|
||||
// The caller doesn't care where aRect is positioned vertically,
|
||||
// so long as it's fully visible
|
||||
if (aRect.y < visibleRect.y) {
|
||||
// Scroll up so aRect's top edge is visible
|
||||
scrollOffsetY = aRect.y;
|
||||
} else if (aRect.YMost() > visibleRect.YMost()) {
|
||||
// Scroll down so aRect's bottom edge is visible. Make sure
|
||||
// aRect's top edge is still visible
|
||||
scrollOffsetY += aRect.YMost() - visibleRect.YMost();
|
||||
if (scrollOffsetY > aRect.y) {
|
||||
scrollOffsetY = aRect.y;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Align the aRect edge according to the specified percentage
|
||||
nscoord frameAlignY = aRect.y + (aRect.height * aVPercent) / 100;
|
||||
scrollOffsetY = frameAlignY - (visibleRect.height * aVPercent) / 100;
|
||||
}
|
||||
} else {
|
||||
// Align the aRect edge according to the specified percentage
|
||||
nscoord frameAlignY = aRect.y + (aRect.height * aVPercent) / 100;
|
||||
scrollOffsetY = frameAlignY - (visibleRect.height * aVPercent) / 100;
|
||||
}
|
||||
|
||||
// See how the aRect should be positioned horizontally
|
||||
if (NS_PRESSHELL_SCROLL_ANYWHERE == aHPercent) {
|
||||
// The caller doesn't care where the aRect is positioned horizontally,
|
||||
// so long as it's fully visible
|
||||
if (aRect.x < visibleRect.x) {
|
||||
// Scroll left so the aRect's left edge is visible
|
||||
scrollOffsetX = aRect.x;
|
||||
} else if (aRect.XMost() > visibleRect.XMost()) {
|
||||
// Scroll right so the aRect's right edge is visible. Make sure the
|
||||
// aRect's left edge is still visible
|
||||
scrollOffsetX += aRect.XMost() - visibleRect.XMost();
|
||||
if (scrollOffsetX > aRect.x) {
|
||||
if (ss.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN) {
|
||||
if (NS_PRESSHELL_SCROLL_ANYWHERE == aHPercent) {
|
||||
// The caller doesn't care where the aRect is positioned horizontally,
|
||||
// so long as it's fully visible
|
||||
if (aRect.x < visibleRect.x) {
|
||||
// Scroll left so the aRect's left edge is visible
|
||||
scrollOffsetX = aRect.x;
|
||||
} else if (aRect.XMost() > visibleRect.XMost()) {
|
||||
// Scroll right so the aRect's right edge is visible. Make sure the
|
||||
// aRect's left edge is still visible
|
||||
scrollOffsetX += aRect.XMost() - visibleRect.XMost();
|
||||
if (scrollOffsetX > aRect.x) {
|
||||
scrollOffsetX = aRect.x;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// Align the aRect edge according to the specified percentage
|
||||
nscoord frameAlignX = aRect.x + (aRect.width * aHPercent) / 100;
|
||||
scrollOffsetX = frameAlignX - (visibleRect.width * aHPercent) / 100;
|
||||
}
|
||||
|
||||
} else {
|
||||
// Align the aRect edge according to the specified percentage
|
||||
nscoord frameAlignX = aRect.x + (aRect.width * aHPercent) / 100;
|
||||
scrollOffsetX = frameAlignX - (visibleRect.width * aHPercent) / 100;
|
||||
}
|
||||
|
||||
aScrollableView->ScrollTo(scrollOffsetX, scrollOffsetY, NS_VMREFRESH_IMMEDIATE);
|
||||
|
@ -7118,7 +7138,8 @@ nsTypedSelection::ScrollRectIntoView(nsIScrollableView *aScrollableView,
|
|||
|
||||
if (view)
|
||||
{
|
||||
nsIScrollableView *parentSV = nsLayoutUtils::GetNearestScrollingView(view);
|
||||
nsIScrollableView *parentSV =
|
||||
nsLayoutUtils::GetNearestScrollingView(view, nsLayoutUtils::eEither);
|
||||
|
||||
if (parentSV)
|
||||
{
|
||||
|
|
|
@ -1351,7 +1351,7 @@ protected:
|
|||
PRBool IsDragInProgress ( ) const ;
|
||||
|
||||
// Utility to find which view to scroll.
|
||||
nsIScrollableView* GetViewToScroll();
|
||||
nsIScrollableView* GetViewToScroll(nsLayoutUtils::Direction aDirection);
|
||||
|
||||
PRBool mCaretEnabled;
|
||||
#ifdef IBMBIDI
|
||||
|
@ -3138,7 +3138,7 @@ PresShell::PageMove(PRBool aForward, PRBool aExtend)
|
|||
NS_IMETHODIMP
|
||||
PresShell::ScrollPage(PRBool aForward)
|
||||
{
|
||||
nsIScrollableView* scrollView = GetViewToScroll();
|
||||
nsIScrollableView* scrollView = GetViewToScroll(nsLayoutUtils::eVertical);
|
||||
if (scrollView) {
|
||||
scrollView->ScrollByPages(0, aForward ? 1 : -1);
|
||||
}
|
||||
|
@ -3148,7 +3148,7 @@ PresShell::ScrollPage(PRBool aForward)
|
|||
NS_IMETHODIMP
|
||||
PresShell::ScrollLine(PRBool aForward)
|
||||
{
|
||||
nsIScrollableView* scrollView = GetViewToScroll();
|
||||
nsIScrollableView* scrollView = GetViewToScroll(nsLayoutUtils::eVertical);
|
||||
if (scrollView) {
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
// Emulate the Mac IE behavior of scrolling a minimum of 2 lines
|
||||
|
@ -3175,7 +3175,7 @@ PresShell::ScrollLine(PRBool aForward)
|
|||
NS_IMETHODIMP
|
||||
PresShell::ScrollHorizontal(PRBool aLeft)
|
||||
{
|
||||
nsIScrollableView* scrollView = GetViewToScroll();
|
||||
nsIScrollableView* scrollView = GetViewToScroll(nsLayoutUtils::eHorizontal);
|
||||
if (scrollView) {
|
||||
scrollView->ScrollByLines(aLeft ? -1 : 1, 0);
|
||||
//NEW FOR LINES
|
||||
|
@ -3195,7 +3195,7 @@ PresShell::ScrollHorizontal(PRBool aLeft)
|
|||
NS_IMETHODIMP
|
||||
PresShell::CompleteScroll(PRBool aForward)
|
||||
{
|
||||
nsIScrollableView* scrollView = GetViewToScroll();
|
||||
nsIScrollableView* scrollView = GetViewToScroll(nsLayoutUtils::eVertical);
|
||||
if (scrollView) {
|
||||
scrollView->ScrollByWhole(!aForward);//TRUE = top, aForward TRUE=bottom
|
||||
}
|
||||
|
@ -3654,7 +3654,7 @@ PresShell :: IsDragInProgress ( ) const
|
|||
} // IsDragInProgress
|
||||
|
||||
nsIScrollableView*
|
||||
PresShell::GetViewToScroll()
|
||||
PresShell::GetViewToScroll(nsLayoutUtils::Direction aDirection)
|
||||
{
|
||||
nsCOMPtr<nsIEventStateManager> esm = mPresContext->EventStateManager();
|
||||
nsIScrollableView* scrollView = nsnull;
|
||||
|
@ -3670,7 +3670,8 @@ PresShell::GetViewToScroll()
|
|||
} else {
|
||||
nsIView* startView = startFrame->GetClosestView();
|
||||
if (startView)
|
||||
scrollView = nsLayoutUtils::GetNearestScrollingView(startView);
|
||||
scrollView =
|
||||
nsLayoutUtils::GetNearestScrollingView(startView, aDirection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче