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:
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user