Bug 526394. Part 8: Fix nsNSElementTearoff to use new APIs, and also fix it to check for root element and body properly. r=jst

This commit is contained in:
Robert O'Callahan
2009-09-03 15:57:36 +12:00
parent 6c2ba214ae
commit 8266c3e27c
4 changed files with 164 additions and 151 deletions

View File

@@ -132,8 +132,6 @@
#include "nsIView.h"
#include "nsIViewManager.h"
#include "nsIScrollableFrame.h"
#include "nsIScrollableView.h"
#include "nsIScrollableViewProvider.h"
#include "nsXBLInsertionPoint.h"
#include "nsICSSStyleRule.h" /* For nsCSSSelectorList */
#include "nsCSSRuleProcessor.h"
@@ -1189,72 +1187,48 @@ nsGenericElement::GetOffsetRect(nsRect& aRect, nsIContent** aOffsetParent)
aRect.height = nsPresContext::AppUnitsToIntCSSPixels(rcFrame.height);
}
void
nsNSElementTearoff::GetScrollInfo(nsIScrollableView **aScrollableView,
nsIFrame **aFrame)
nsIScrollableFrame*
nsNSElementTearoff::GetScrollFrame(nsIFrame **aStyledFrame)
{
*aScrollableView = nsnull;
// it isn't clear what to return for SVG nodes, so just return nothing
if (mContent->IsSVG()) {
if (aFrame)
*aFrame = nsnull;
return;
if (aStyledFrame) {
*aStyledFrame = nsnull;
}
return nsnull;
}
nsIFrame* frame =
(static_cast<nsGenericElement*>(mContent))->GetStyledFrame();
if (aFrame) {
*aFrame = frame;
if (aStyledFrame) {
*aStyledFrame = frame;
}
if (!frame) {
return;
return nsnull;
}
// Get the scrollable frame
nsIScrollableFrame *scrollFrame = do_QueryFrame(frame);
if (!scrollFrame) {
nsIScrollableViewProvider *scrollProvider = do_QueryFrame(frame);
// menu frames implement nsIScrollableViewProvider but we don't want
// to use it here.
if (scrollProvider && frame->GetType() != nsGkAtoms::menuFrame) {
*aScrollableView = scrollProvider->GetScrollableView();
if (*aScrollableView) {
return;
}
}
nsIDocument* doc = mContent->GetCurrentDoc();
PRBool quirksMode = doc &&
doc->GetCompatibilityMode() == eCompatibility_NavQuirks;
if ((quirksMode && mContent->NodeInfo()->Equals(nsGkAtoms::body)) ||
(!quirksMode && mContent->NodeInfo()->Equals(nsGkAtoms::html))) {
// In quirks mode, the scroll info for the body element should map to the
// scroll info for the nearest scrollable frame above the body element
// (i.e. the root scrollable frame). This is what IE6 does in quirks
// mode. In strict mode the root scrollable frame corresponds to the
// html element in IE6, so we map the scroll info for the html element to
// the root scrollable frame.
do {
frame = frame->GetParent();
if (!frame) {
break;
}
scrollFrame = do_QueryFrame(frame);
} while (!scrollFrame);
}
if (!scrollFrame) {
return;
}
// menu frames implement GetScrollTargetFrame but we don't want
// to use it here.
if (frame->GetType() != nsGkAtoms::menuFrame) {
nsIScrollableFrame *scrollFrame = frame->GetScrollTargetFrame();
if (scrollFrame)
return scrollFrame;
}
// Get the scrollable view
*aScrollableView = scrollFrame->GetScrollableView();
nsIDocument* doc = mContent->GetOwnerDoc();
PRBool quirksMode = doc->GetCompatibilityMode() == eCompatibility_NavQuirks;
nsIContent* elementWithRootScrollInfo =
quirksMode ? doc->GetBodyContent() : doc->GetRootContent();
if (mContent == elementWithRootScrollInfo) {
// In quirks mode, the scroll info for the body element should map to the
// root scrollable frame.
// In strict mode, the scroll info for the root element should map to the
// the root scrollable frame.
return frame->PresContext()->PresShell()->GetRootScrollFrameAsScrollable();
}
return nsnull;
}
nsresult
@@ -1263,41 +1237,26 @@ nsNSElementTearoff::GetScrollTop(PRInt32* aScrollTop)
NS_ENSURE_ARG_POINTER(aScrollTop);
*aScrollTop = 0;
nsIScrollableView *view;
nsresult rv = NS_OK;
GetScrollInfo(&view);
if (view) {
nscoord xPos, yPos;
rv = view->GetScrollPosition(xPos, yPos);
*aScrollTop = nsPresContext::AppUnitsToIntCSSPixels(yPos);
nsIScrollableFrame* sf = GetScrollFrame();
if (sf) {
nscoord y = sf->GetScrollPosition().y;
*aScrollTop = nsPresContext::AppUnitsToIntCSSPixels(y);
}
return rv;
return NS_OK;
}
nsresult
nsNSElementTearoff::SetScrollTop(PRInt32 aScrollTop)
{
nsIScrollableView *view;
nsresult rv = NS_OK;
GetScrollInfo(&view);
if (view) {
nscoord xPos, yPos;
rv = view->GetScrollPosition(xPos, yPos);
if (NS_SUCCEEDED(rv)) {
rv = view->ScrollTo(xPos, nsPresContext::CSSPixelsToAppUnits(aScrollTop),
0);
}
nsIScrollableFrame* sf = GetScrollFrame();
if (sf) {
nsPoint pt = sf->GetScrollPosition();
pt.y = nsPresContext::CSSPixelsToAppUnits(aScrollTop);
sf->ScrollTo(pt, nsIScrollableFrame::INSTANT);
}
return rv;
return NS_OK;
}
nsresult
@@ -1306,40 +1265,26 @@ nsNSElementTearoff::GetScrollLeft(PRInt32* aScrollLeft)
NS_ENSURE_ARG_POINTER(aScrollLeft);
*aScrollLeft = 0;
nsIScrollableView *view;
nsresult rv = NS_OK;
GetScrollInfo(&view);
if (view) {
nscoord xPos, yPos;
rv = view->GetScrollPosition(xPos, yPos);
*aScrollLeft = nsPresContext::AppUnitsToIntCSSPixels(xPos);
nsIScrollableFrame* sf = GetScrollFrame();
if (sf) {
nscoord x = sf->GetScrollPosition().x;
*aScrollLeft = nsPresContext::AppUnitsToIntCSSPixels(x);
}
return rv;
return NS_OK;
}
nsresult
nsNSElementTearoff::SetScrollLeft(PRInt32 aScrollLeft)
{
nsIScrollableView *view;
nsresult rv = NS_OK;
GetScrollInfo(&view);
if (view) {
nscoord xPos, yPos;
rv = view->GetScrollPosition(xPos, yPos);
if (NS_SUCCEEDED(rv)) {
rv = view->ScrollTo(nsPresContext::CSSPixelsToAppUnits(aScrollLeft),
yPos, 0);
}
nsIScrollableFrame* sf = GetScrollFrame();
if (sf) {
nsPoint pt = sf->GetScrollPosition();
pt.x = nsPresContext::CSSPixelsToAppUnits(aScrollLeft);
sf->ScrollTo(pt, nsIScrollableFrame::INSTANT);
}
return rv;
return NS_OK;
}
nsresult
@@ -1351,12 +1296,8 @@ nsNSElementTearoff::GetScrollHeight(PRInt32* aScrollHeight)
if (mContent->IsSVG())
return NS_OK;
nsIScrollableView *scrollView;
nsresult rv = NS_OK;
GetScrollInfo(&scrollView);
if (!scrollView) {
nsIScrollableFrame* sf = GetScrollFrame();
if (!sf) {
nsRect rcFrame;
nsCOMPtr<nsIContent> parent;
(static_cast<nsGenericElement *>(mContent))->GetOffsetRect(rcFrame, getter_AddRefs(parent));
@@ -1364,13 +1305,9 @@ nsNSElementTearoff::GetScrollHeight(PRInt32* aScrollHeight)
return NS_OK;
}
// xMax and yMax is the total length of our container
nscoord xMax, yMax;
rv = scrollView->GetContainerSize(&xMax, &yMax);
*aScrollHeight = nsPresContext::AppUnitsToIntCSSPixels(yMax);
return rv;
nscoord height = sf->GetScrollRange().height + sf->GetScrollPortRect().height;
*aScrollHeight = nsPresContext::AppUnitsToIntCSSPixels(height);
return NS_OK;
}
nsresult
@@ -1382,12 +1319,8 @@ nsNSElementTearoff::GetScrollWidth(PRInt32* aScrollWidth)
if (mContent->IsSVG())
return NS_OK;
nsIScrollableView *scrollView;
nsresult rv = NS_OK;
GetScrollInfo(&scrollView);
if (!scrollView) {
nsIScrollableFrame* sf = GetScrollFrame();
if (!sf) {
nsRect rcFrame;
nsCOMPtr<nsIContent> parent;
(static_cast<nsGenericElement *>(mContent))->GetOffsetRect(rcFrame, getter_AddRefs(parent));
@@ -1395,38 +1328,30 @@ nsNSElementTearoff::GetScrollWidth(PRInt32* aScrollWidth)
return NS_OK;
}
nscoord xMax, yMax;
rv = scrollView->GetContainerSize(&xMax, &yMax);
*aScrollWidth = nsPresContext::AppUnitsToIntCSSPixels(xMax);
return rv;
nscoord width = sf->GetScrollRange().width + sf->GetScrollPortRect().width;
*aScrollWidth = nsPresContext::AppUnitsToIntCSSPixels(width);
return NS_OK;
}
nsRect
nsNSElementTearoff::GetClientAreaRect()
{
nsIScrollableView *scrollView;
nsIFrame *frame;
nsIFrame* styledFrame;
nsIScrollableFrame* sf = GetScrollFrame(&styledFrame);
// it isn't clear what to return for SVG nodes, so just return 0
if (mContent->IsSVG())
return nsRect(0, 0, 0, 0);
GetScrollInfo(&scrollView, &frame);
if (scrollView) {
return scrollView->View()->GetBounds();
if (sf) {
return sf->GetScrollPortRect();
}
if (frame &&
(frame->GetStyleDisplay()->mDisplay != NS_STYLE_DISPLAY_INLINE ||
frame->IsFrameOfType(nsIFrame::eReplaced))) {
if (styledFrame &&
(styledFrame->GetStyleDisplay()->mDisplay != NS_STYLE_DISPLAY_INLINE ||
styledFrame->IsFrameOfType(nsIFrame::eReplaced))) {
// Special case code to make client area work even when there isn't
// a scroll view, see bug 180552, bug 227567.
return frame->GetPaddingRect() - frame->GetPositionIgnoringScrolling();
return styledFrame->GetPaddingRect() - styledFrame->GetPositionIgnoringScrolling();
}
// SVG nodes reach here and just return 0
return nsRect(0, 0, 0, 0);
}