Land bug 72747 in pieces: Implement scrolling='yes' (and equivalents) on frames and iframes. b=72747 r+sr=roc

git-svn-id: svn://10.0.0.236/trunk@161771 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
dbaron%dbaron.org
2004-09-04 23:03:04 +00:00
parent 47104955d7
commit f9bdcbfb99
6 changed files with 138 additions and 64 deletions

View File

@@ -3836,8 +3836,6 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIPresShell* aPresShell,
// 2) nsIScrollable::Scrollbar_Auto = scrollbars appear if needed
// 3) nsIScrollable::Scrollbar_Always = scrollbars always
// Only need to create a scroll frame/view for cases 2 and 3.
// Currently Scrollbar_Always isn't honored, as
// scrollportview::SetScrollPref is not implemented.
PRBool isHTML = aDocElement->IsContentOfType(nsIContent::eHTML);
PRBool isXUL = PR_FALSE;
@@ -3856,6 +3854,11 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIPresShell* aPresShell,
isScrollable = PR_FALSE;
}
// Don't create a scrollframe when we're inside a frame or iframe with
// scrolling="no". This makes the frame hierarchy inconsistent and is
// unnecessary for correctness (since
// nsGfxScrollFrameInner::GetScrollbarStyles handles all the necessary
// cases), but it seems to be needed for performance.
if (isScrollable) {
nsresult rv;
if (aPresContext) {
@@ -3864,12 +3867,13 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIPresShell* aPresShell,
nsCOMPtr<nsIScrollable> scrollableContainer = do_QueryInterface(container, &rv);
if (NS_SUCCEEDED(rv) && scrollableContainer) {
PRInt32 scrolling = -1;
// XXX We should get prefs for X and Y and deal with these independently!
scrollableContainer->GetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_Y,&scrolling);
if (nsIScrollable::Scrollbar_Never == scrolling) {
isScrollable = PR_FALSE;
scrollableContainer->GetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X,&scrolling);
if (nsIScrollable::Scrollbar_Never == scrolling) {
isScrollable = PR_FALSE;
}
}
// XXX NS_STYLE_OVERFLOW_SCROLL should create 'always on' scrollbars
}
}
}

View File

@@ -67,10 +67,10 @@ public:
struct ScrollbarStyles {
// one of NS_STYLE_OVERFLOW_SCROLL, NS_STYLE_OVERFLOW_HIDDEN,
// NS_STYLE_OVERFLOW_VISIBLE, NS_STYLE_OVERFLOW_AUTO
PRInt32 mHorizontal;
PRInt32 mVertical;
ScrollbarStyles(PRInt32 h, PRInt32 v) : mHorizontal(h), mVertical(v) {}
// NS_STYLE_OVERFLOW_AUTO
PRUint8 mHorizontal, mVertical;
ScrollbarStyles(PRUint8 h, PRUint8 v) : mHorizontal(h), mVertical(v) {}
ScrollbarStyles() {}
};
virtual ScrollbarStyles GetScrollbarStyles() const = 0;

View File

@@ -45,6 +45,7 @@
#include "nsIServiceManager.h"
#include "nsIView.h"
#include "nsIScrollableView.h"
#include "nsIScrollable.h"
#include "nsIViewManager.h"
#include "nsHTMLContainerFrame.h"
#include "nsWidgetsCID.h"
@@ -1181,40 +1182,72 @@ NS_IMETHODIMP_(nsrefcnt) nsGfxScrollFrameInner::Release(void)
NS_IMPL_QUERY_INTERFACE1(nsGfxScrollFrameInner, nsIScrollPositionListener)
static void HandleScrollPref(nsIScrollable *aScrollable, PRInt32 aOrientation,
PRUint8& aValue)
{
PRInt32 pref;
aScrollable->GetDefaultScrollbarPreferences(aOrientation, &pref);
switch (pref) {
case nsIScrollable::Scrollbar_Auto:
// leave |aValue| untouched
break;
case nsIScrollable::Scrollbar_Never:
aValue = NS_STYLE_OVERFLOW_HIDDEN;
break;
case nsIScrollable::Scrollbar_Always:
aValue = NS_STYLE_OVERFLOW_SCROLL;
break;
}
}
static nsGfxScrollFrameInner::ScrollbarStyles
ConvertOverflow(PRUint8 aOverflow)
{
nsGfxScrollFrameInner::ScrollbarStyles result;
switch (aOverflow) {
case NS_STYLE_OVERFLOW_SCROLLBARS_VERTICAL:
result.mHorizontal = NS_STYLE_OVERFLOW_HIDDEN;
result.mVertical = NS_STYLE_OVERFLOW_SCROLL;
break;
case NS_STYLE_OVERFLOW_SCROLLBARS_HORIZONTAL:
result.mHorizontal = NS_STYLE_OVERFLOW_SCROLL;
result.mVertical = NS_STYLE_OVERFLOW_HIDDEN;
break;
default:
result.mHorizontal = aOverflow;
result.mVertical = aOverflow;
}
return result;
}
nsGfxScrollFrameInner::ScrollbarStyles
nsGfxScrollFrameInner::GetScrollbarStylesFromFrame() const
{
PRUint8 overflow;
ScrollbarStyles result;
nsIFrame* parent = mOuter->GetParent();
if (parent && parent->GetType() == nsLayoutAtoms::viewportFrame &&
// Make sure we're actually the root scrollframe
parent->GetFirstChild(nsnull) ==
NS_STATIC_CAST(const nsIFrame*, mOuter)) {
overflow = mOuter->GetPresContext()->GetViewportOverflowOverride();
nsPresContext *presContext = mOuter->GetPresContext();
result = ConvertOverflow(presContext->GetViewportOverflowOverride());
nsCOMPtr<nsISupports> container = presContext->GetContainer();
nsCOMPtr<nsIScrollable> scrollable = do_QueryInterface(container);
HandleScrollPref(scrollable, nsIScrollable::ScrollOrientation_X,
result.mHorizontal);
HandleScrollPref(scrollable, nsIScrollable::ScrollOrientation_Y,
result.mVertical);
} else {
overflow = mOuter->GetStyleDisplay()->mOverflow;
result = ConvertOverflow(mOuter->GetStyleDisplay()->mOverflow);
}
switch (overflow) {
case NS_STYLE_OVERFLOW_SCROLL:
case NS_STYLE_OVERFLOW_HIDDEN:
case NS_STYLE_OVERFLOW_VISIBLE: // should never happen
case NS_STYLE_OVERFLOW_AUTO:
return ScrollbarStyles(overflow, overflow);
case NS_STYLE_OVERFLOW_CLIP:
// This isn't quite right (although the value is deprecated and not
// very important). The scrollframe will still be scrollable using
// keys. This can happen when HTML or BODY has propagated the style
// to the viewport. (In other cases, there will be no scrollframe.)
return ScrollbarStyles(NS_STYLE_OVERFLOW_HIDDEN, NS_STYLE_OVERFLOW_HIDDEN);
case NS_STYLE_OVERFLOW_SCROLLBARS_VERTICAL:
return ScrollbarStyles(NS_STYLE_OVERFLOW_HIDDEN, NS_STYLE_OVERFLOW_SCROLL);
case NS_STYLE_OVERFLOW_SCROLLBARS_HORIZONTAL:
return ScrollbarStyles(NS_STYLE_OVERFLOW_SCROLL, NS_STYLE_OVERFLOW_HIDDEN);
default:
NS_NOTREACHED("invalid overflow value");
return ScrollbarStyles(NS_STYLE_OVERFLOW_HIDDEN, NS_STYLE_OVERFLOW_HIDDEN);
}
NS_ASSERTION(result.mHorizontal != NS_STYLE_OVERFLOW_VISIBLE &&
result.mHorizontal != NS_STYLE_OVERFLOW_CLIP &&
result.mVertical != NS_STYLE_OVERFLOW_VISIBLE &&
result.mVertical != NS_STYLE_OVERFLOW_CLIP,
"scrollbars should not have been created");
return result;
}
void

View File

@@ -67,10 +67,10 @@ public:
struct ScrollbarStyles {
// one of NS_STYLE_OVERFLOW_SCROLL, NS_STYLE_OVERFLOW_HIDDEN,
// NS_STYLE_OVERFLOW_VISIBLE, NS_STYLE_OVERFLOW_AUTO
PRInt32 mHorizontal;
PRInt32 mVertical;
ScrollbarStyles(PRInt32 h, PRInt32 v) : mHorizontal(h), mVertical(v) {}
// NS_STYLE_OVERFLOW_AUTO
PRUint8 mHorizontal, mVertical;
ScrollbarStyles(PRUint8 h, PRUint8 v) : mHorizontal(h), mVertical(v) {}
ScrollbarStyles() {}
};
virtual ScrollbarStyles GetScrollbarStyles() const = 0;

View File

@@ -45,6 +45,7 @@
#include "nsIServiceManager.h"
#include "nsIView.h"
#include "nsIScrollableView.h"
#include "nsIScrollable.h"
#include "nsIViewManager.h"
#include "nsHTMLContainerFrame.h"
#include "nsWidgetsCID.h"
@@ -1181,40 +1182,72 @@ NS_IMETHODIMP_(nsrefcnt) nsGfxScrollFrameInner::Release(void)
NS_IMPL_QUERY_INTERFACE1(nsGfxScrollFrameInner, nsIScrollPositionListener)
static void HandleScrollPref(nsIScrollable *aScrollable, PRInt32 aOrientation,
PRUint8& aValue)
{
PRInt32 pref;
aScrollable->GetDefaultScrollbarPreferences(aOrientation, &pref);
switch (pref) {
case nsIScrollable::Scrollbar_Auto:
// leave |aValue| untouched
break;
case nsIScrollable::Scrollbar_Never:
aValue = NS_STYLE_OVERFLOW_HIDDEN;
break;
case nsIScrollable::Scrollbar_Always:
aValue = NS_STYLE_OVERFLOW_SCROLL;
break;
}
}
static nsGfxScrollFrameInner::ScrollbarStyles
ConvertOverflow(PRUint8 aOverflow)
{
nsGfxScrollFrameInner::ScrollbarStyles result;
switch (aOverflow) {
case NS_STYLE_OVERFLOW_SCROLLBARS_VERTICAL:
result.mHorizontal = NS_STYLE_OVERFLOW_HIDDEN;
result.mVertical = NS_STYLE_OVERFLOW_SCROLL;
break;
case NS_STYLE_OVERFLOW_SCROLLBARS_HORIZONTAL:
result.mHorizontal = NS_STYLE_OVERFLOW_SCROLL;
result.mVertical = NS_STYLE_OVERFLOW_HIDDEN;
break;
default:
result.mHorizontal = aOverflow;
result.mVertical = aOverflow;
}
return result;
}
nsGfxScrollFrameInner::ScrollbarStyles
nsGfxScrollFrameInner::GetScrollbarStylesFromFrame() const
{
PRUint8 overflow;
ScrollbarStyles result;
nsIFrame* parent = mOuter->GetParent();
if (parent && parent->GetType() == nsLayoutAtoms::viewportFrame &&
// Make sure we're actually the root scrollframe
parent->GetFirstChild(nsnull) ==
NS_STATIC_CAST(const nsIFrame*, mOuter)) {
overflow = mOuter->GetPresContext()->GetViewportOverflowOverride();
nsPresContext *presContext = mOuter->GetPresContext();
result = ConvertOverflow(presContext->GetViewportOverflowOverride());
nsCOMPtr<nsISupports> container = presContext->GetContainer();
nsCOMPtr<nsIScrollable> scrollable = do_QueryInterface(container);
HandleScrollPref(scrollable, nsIScrollable::ScrollOrientation_X,
result.mHorizontal);
HandleScrollPref(scrollable, nsIScrollable::ScrollOrientation_Y,
result.mVertical);
} else {
overflow = mOuter->GetStyleDisplay()->mOverflow;
result = ConvertOverflow(mOuter->GetStyleDisplay()->mOverflow);
}
switch (overflow) {
case NS_STYLE_OVERFLOW_SCROLL:
case NS_STYLE_OVERFLOW_HIDDEN:
case NS_STYLE_OVERFLOW_VISIBLE: // should never happen
case NS_STYLE_OVERFLOW_AUTO:
return ScrollbarStyles(overflow, overflow);
case NS_STYLE_OVERFLOW_CLIP:
// This isn't quite right (although the value is deprecated and not
// very important). The scrollframe will still be scrollable using
// keys. This can happen when HTML or BODY has propagated the style
// to the viewport. (In other cases, there will be no scrollframe.)
return ScrollbarStyles(NS_STYLE_OVERFLOW_HIDDEN, NS_STYLE_OVERFLOW_HIDDEN);
case NS_STYLE_OVERFLOW_SCROLLBARS_VERTICAL:
return ScrollbarStyles(NS_STYLE_OVERFLOW_HIDDEN, NS_STYLE_OVERFLOW_SCROLL);
case NS_STYLE_OVERFLOW_SCROLLBARS_HORIZONTAL:
return ScrollbarStyles(NS_STYLE_OVERFLOW_SCROLL, NS_STYLE_OVERFLOW_HIDDEN);
default:
NS_NOTREACHED("invalid overflow value");
return ScrollbarStyles(NS_STYLE_OVERFLOW_HIDDEN, NS_STYLE_OVERFLOW_HIDDEN);
}
NS_ASSERTION(result.mHorizontal != NS_STYLE_OVERFLOW_VISIBLE &&
result.mHorizontal != NS_STYLE_OVERFLOW_CLIP &&
result.mVertical != NS_STYLE_OVERFLOW_VISIBLE &&
result.mVertical != NS_STYLE_OVERFLOW_CLIP,
"scrollbars should not have been created");
return result;
}
void

View File

@@ -3836,8 +3836,6 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIPresShell* aPresShell,
// 2) nsIScrollable::Scrollbar_Auto = scrollbars appear if needed
// 3) nsIScrollable::Scrollbar_Always = scrollbars always
// Only need to create a scroll frame/view for cases 2 and 3.
// Currently Scrollbar_Always isn't honored, as
// scrollportview::SetScrollPref is not implemented.
PRBool isHTML = aDocElement->IsContentOfType(nsIContent::eHTML);
PRBool isXUL = PR_FALSE;
@@ -3856,6 +3854,11 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIPresShell* aPresShell,
isScrollable = PR_FALSE;
}
// Don't create a scrollframe when we're inside a frame or iframe with
// scrolling="no". This makes the frame hierarchy inconsistent and is
// unnecessary for correctness (since
// nsGfxScrollFrameInner::GetScrollbarStyles handles all the necessary
// cases), but it seems to be needed for performance.
if (isScrollable) {
nsresult rv;
if (aPresContext) {
@@ -3864,12 +3867,13 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIPresShell* aPresShell,
nsCOMPtr<nsIScrollable> scrollableContainer = do_QueryInterface(container, &rv);
if (NS_SUCCEEDED(rv) && scrollableContainer) {
PRInt32 scrolling = -1;
// XXX We should get prefs for X and Y and deal with these independently!
scrollableContainer->GetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_Y,&scrolling);
if (nsIScrollable::Scrollbar_Never == scrolling) {
isScrollable = PR_FALSE;
scrollableContainer->GetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X,&scrolling);
if (nsIScrollable::Scrollbar_Never == scrolling) {
isScrollable = PR_FALSE;
}
}
// XXX NS_STYLE_OVERFLOW_SCROLL should create 'always on' scrollbars
}
}
}