Change ScrollFrameIntoView so that scrolling to an inline frame scrolls to the top of the line containing the inline frame rather than the frame itself. This makes scrolling to empty inline anchors or anchors around images work better. b=38280 r=buster@netscape.com sr=waterson@netscape.com

This commit is contained in:
dbaron%fas.harvard.edu 2001-01-10 02:43:00 +00:00
parent 2fbefad3f4
commit 618b924650
2 changed files with 78 additions and 0 deletions

View File

@ -93,6 +93,7 @@
#include "nsILayoutHistoryState.h"
#include "nsIScrollPositionListener.h"
#include "nsICompositeListener.h"
#include "nsILineIterator.h" // for ScrollFrameIntoView
#include "nsTimer.h"
#include "nsWeakPtr.h"
#include "plarena.h"
@ -3418,6 +3419,44 @@ PresShell::ScrollFrameIntoView(nsIFrame *aFrame,
scrollingView->GetScrolledView(scrolledView);
aFrame->GetOffsetFromView(mPresContext, offset, &closestView);
// If this is an inline frame, we need to change the top of the
// offset to include the whole line.
nsCOMPtr<nsIAtom> frameType;
nsIFrame *prevFrame = aFrame;
nsIFrame *frame = aFrame;
while (frame && (frame->GetFrameType(getter_AddRefs(frameType)),
frameType.get() == nsLayoutAtoms::inlineFrame)) {
prevFrame = frame;
prevFrame->GetParent(&frame);
}
if (frame != aFrame &&
frame &&
frameType.get() == nsLayoutAtoms::blockFrame) {
// find the line containing aFrame and increase the top of |offset|.
nsCOMPtr<nsILineIterator> lines( do_QueryInterface(frame) );
if (lines) {
PRInt32 index = -1;
lines->FindLineContaining(prevFrame, &index);
if (index >= 0) {
nsIFrame *trash1;
PRInt32 trash2;
nsRect lineBounds;
PRUint32 trash3;
if (NS_SUCCEEDED(lines->GetLine(index, &trash1, &trash2,
lineBounds, &trash3))) {
nsPoint blockOffset;
nsIView* blockView;
frame->GetOffsetFromView(mPresContext, blockOffset, &blockView);
if (blockView == closestView) {
// XXX If views not equal, this is hard. Do we want to bother?
nscoord newoffset = lineBounds.y + blockOffset.y;
if (newoffset < offset.y) offset.y = newoffset;
}
}
}
}
}
// XXX Deal with the case where there is a scrolled element, e.g., a
// DIV in the middle...
while ((closestView != nsnull) && (closestView != scrolledView)) {

View File

@ -93,6 +93,7 @@
#include "nsILayoutHistoryState.h"
#include "nsIScrollPositionListener.h"
#include "nsICompositeListener.h"
#include "nsILineIterator.h" // for ScrollFrameIntoView
#include "nsTimer.h"
#include "nsWeakPtr.h"
#include "plarena.h"
@ -3418,6 +3419,44 @@ PresShell::ScrollFrameIntoView(nsIFrame *aFrame,
scrollingView->GetScrolledView(scrolledView);
aFrame->GetOffsetFromView(mPresContext, offset, &closestView);
// If this is an inline frame, we need to change the top of the
// offset to include the whole line.
nsCOMPtr<nsIAtom> frameType;
nsIFrame *prevFrame = aFrame;
nsIFrame *frame = aFrame;
while (frame && (frame->GetFrameType(getter_AddRefs(frameType)),
frameType.get() == nsLayoutAtoms::inlineFrame)) {
prevFrame = frame;
prevFrame->GetParent(&frame);
}
if (frame != aFrame &&
frame &&
frameType.get() == nsLayoutAtoms::blockFrame) {
// find the line containing aFrame and increase the top of |offset|.
nsCOMPtr<nsILineIterator> lines( do_QueryInterface(frame) );
if (lines) {
PRInt32 index = -1;
lines->FindLineContaining(prevFrame, &index);
if (index >= 0) {
nsIFrame *trash1;
PRInt32 trash2;
nsRect lineBounds;
PRUint32 trash3;
if (NS_SUCCEEDED(lines->GetLine(index, &trash1, &trash2,
lineBounds, &trash3))) {
nsPoint blockOffset;
nsIView* blockView;
frame->GetOffsetFromView(mPresContext, blockOffset, &blockView);
if (blockView == closestView) {
// XXX If views not equal, this is hard. Do we want to bother?
nscoord newoffset = lineBounds.y + blockOffset.y;
if (newoffset < offset.y) offset.y = newoffset;
}
}
}
}
}
// XXX Deal with the case where there is a scrolled element, e.g., a
// DIV in the middle...
while ((closestView != nsnull) && (closestView != scrolledView)) {