зеркало из https://github.com/mozilla/gecko-dev.git
Bug 726817 - Add nsIFrameLoaderOwner.clampScrollPosition. r=roc
Add an attribute to nsIFrameLoaderOwner that allows the clamping of set scroll positions to be toggled.
This commit is contained in:
Родитель
6765c25533
Коммит
468bb3d933
|
@ -67,7 +67,7 @@ typedef unsigned long long nsContentViewId;
|
||||||
* These APIs are designed to be used with nsIDOMWindowUtils
|
* These APIs are designed to be used with nsIDOMWindowUtils
|
||||||
* setDisplayPort() and setResolution().
|
* setDisplayPort() and setResolution().
|
||||||
*/
|
*/
|
||||||
[scriptable, uuid(fbd25468-d2cf-487b-bc58-a0e105398b47)]
|
[scriptable, uuid(c04c5c40-fa2a-4e9c-94f5-b362a10a86cb)]
|
||||||
interface nsIContentView : nsISupports
|
interface nsIContentView : nsISupports
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -265,6 +265,13 @@ interface nsIFrameLoader : nsISupports
|
||||||
* Defaults to true.
|
* Defaults to true.
|
||||||
*/
|
*/
|
||||||
attribute boolean clipSubdocument;
|
attribute boolean clipSubdocument;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If false, then the subdocument's scroll coordinates will not be clamped
|
||||||
|
* to their scroll boundaries.
|
||||||
|
* Defaults to true.
|
||||||
|
*/
|
||||||
|
attribute boolean clampScrollPosition;
|
||||||
};
|
};
|
||||||
|
|
||||||
native alreadyAddRefed_nsFrameLoader(already_AddRefed<nsFrameLoader>);
|
native alreadyAddRefed_nsFrameLoader(already_AddRefed<nsFrameLoader>);
|
||||||
|
|
|
@ -76,6 +76,7 @@
|
||||||
#include "nsFrameLoader.h"
|
#include "nsFrameLoader.h"
|
||||||
#include "nsIDOMEventTarget.h"
|
#include "nsIDOMEventTarget.h"
|
||||||
#include "nsIFrame.h"
|
#include "nsIFrame.h"
|
||||||
|
#include "nsIScrollableFrame.h"
|
||||||
#include "nsSubDocumentFrame.h"
|
#include "nsSubDocumentFrame.h"
|
||||||
#include "nsDOMError.h"
|
#include "nsDOMError.h"
|
||||||
#include "nsGUIEvent.h"
|
#include "nsGUIEvent.h"
|
||||||
|
@ -330,6 +331,7 @@ nsFrameLoader::nsFrameLoader(Element* aOwner, bool aNetworkCreated)
|
||||||
, mRemoteBrowserShown(false)
|
, mRemoteBrowserShown(false)
|
||||||
, mRemoteFrame(false)
|
, mRemoteFrame(false)
|
||||||
, mClipSubdocument(true)
|
, mClipSubdocument(true)
|
||||||
|
, mClampScrollPosition(true)
|
||||||
, mCurrentRemoteFrame(nsnull)
|
, mCurrentRemoteFrame(nsnull)
|
||||||
, mRemoteBrowser(nsnull)
|
, mRemoteBrowser(nsnull)
|
||||||
, mRenderMode(RENDER_MODE_DEFAULT)
|
, mRenderMode(RENDER_MODE_DEFAULT)
|
||||||
|
@ -1755,6 +1757,38 @@ nsFrameLoader::SetClipSubdocument(bool aClip)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsFrameLoader::GetClampScrollPosition(bool* aResult)
|
||||||
|
{
|
||||||
|
*aResult = mClampScrollPosition;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsFrameLoader::SetClampScrollPosition(bool aClamp)
|
||||||
|
{
|
||||||
|
mClampScrollPosition = aClamp;
|
||||||
|
|
||||||
|
// When turning clamping on, make sure the current position is clamped.
|
||||||
|
if (aClamp) {
|
||||||
|
nsIFrame* frame = GetPrimaryFrameOfOwningContent();
|
||||||
|
if (frame) {
|
||||||
|
nsSubDocumentFrame* subdocFrame = do_QueryFrame(frame);
|
||||||
|
if (subdocFrame) {
|
||||||
|
nsIFrame* subdocRootFrame = subdocFrame->GetSubdocumentRootFrame();
|
||||||
|
if (subdocRootFrame) {
|
||||||
|
nsIScrollableFrame* subdocRootScrollFrame = subdocRootFrame->PresContext()->PresShell()->
|
||||||
|
GetRootScrollFrameAsScrollable();
|
||||||
|
if (subdocRootScrollFrame) {
|
||||||
|
subdocRootScrollFrame->ScrollTo(subdocRootScrollFrame->GetScrollPosition(), nsIScrollableFrame::INSTANT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
nsIntSize
|
nsIntSize
|
||||||
nsFrameLoader::GetSubDocumentSize(const nsIFrame *aIFrame)
|
nsFrameLoader::GetSubDocumentSize(const nsIFrame *aIFrame)
|
||||||
{
|
{
|
||||||
|
|
|
@ -289,6 +289,8 @@ public:
|
||||||
|
|
||||||
bool ShouldClipSubdocument() { return mClipSubdocument; }
|
bool ShouldClipSubdocument() { return mClipSubdocument; }
|
||||||
|
|
||||||
|
bool ShouldClampScrollPosition() { return mClampScrollPosition; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool ShouldUseRemoteProcess();
|
bool ShouldUseRemoteProcess();
|
||||||
|
@ -342,6 +344,7 @@ private:
|
||||||
bool mRemoteBrowserShown : 1;
|
bool mRemoteBrowserShown : 1;
|
||||||
bool mRemoteFrame : 1;
|
bool mRemoteFrame : 1;
|
||||||
bool mClipSubdocument : 1;
|
bool mClipSubdocument : 1;
|
||||||
|
bool mClampScrollPosition : 1;
|
||||||
|
|
||||||
// XXX leaking
|
// XXX leaking
|
||||||
nsCOMPtr<nsIObserver> mChildHost;
|
nsCOMPtr<nsIObserver> mChildHost;
|
||||||
|
|
|
@ -1550,7 +1550,11 @@ void
|
||||||
nsGfxScrollFrameInner::ScrollTo(nsPoint aScrollPosition,
|
nsGfxScrollFrameInner::ScrollTo(nsPoint aScrollPosition,
|
||||||
nsIScrollableFrame::ScrollMode aMode)
|
nsIScrollableFrame::ScrollMode aMode)
|
||||||
{
|
{
|
||||||
|
if (ShouldClampScrollPosition()) {
|
||||||
mDestination = ClampScrollPosition(aScrollPosition);
|
mDestination = ClampScrollPosition(aScrollPosition);
|
||||||
|
} else {
|
||||||
|
mDestination = aScrollPosition;
|
||||||
|
}
|
||||||
|
|
||||||
if (aMode == nsIScrollableFrame::INSTANT) {
|
if (aMode == nsIScrollableFrame::INSTANT) {
|
||||||
// Asynchronous scrolling is not allowed, so we'll kill any existing
|
// Asynchronous scrolling is not allowed, so we'll kill any existing
|
||||||
|
@ -1713,6 +1717,15 @@ bool nsGfxScrollFrameInner::IsIgnoringViewportClipping() const
|
||||||
return subdocFrame && !subdocFrame->ShouldClipSubdocument();
|
return subdocFrame && !subdocFrame->ShouldClipSubdocument();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool nsGfxScrollFrameInner::ShouldClampScrollPosition() const
|
||||||
|
{
|
||||||
|
if (!mIsRoot)
|
||||||
|
return true;
|
||||||
|
nsSubDocumentFrame* subdocFrame = static_cast<nsSubDocumentFrame*>
|
||||||
|
(nsLayoutUtils::GetCrossDocParentFrame(mOuter->PresContext()->PresShell()->GetRootFrame()));
|
||||||
|
return !subdocFrame || subdocFrame->ShouldClampScrollPosition();
|
||||||
|
}
|
||||||
|
|
||||||
bool nsGfxScrollFrameInner::IsAlwaysActive() const
|
bool nsGfxScrollFrameInner::IsAlwaysActive() const
|
||||||
{
|
{
|
||||||
// The root scrollframe for a non-chrome document which is the direct
|
// The root scrollframe for a non-chrome document which is the direct
|
||||||
|
@ -1812,17 +1825,23 @@ ClampInt(nscoord aLower, nscoord aVal, nscoord aUpper, nscoord aAppUnitsPerPixel
|
||||||
}
|
}
|
||||||
|
|
||||||
nsPoint
|
nsPoint
|
||||||
nsGfxScrollFrameInner::ClampAndRestrictToDevPixels(const nsPoint& aPt,
|
nsGfxScrollFrameInner::RestrictToDevPixels(const nsPoint& aPt,
|
||||||
nsIntPoint* aPtDevPx) const
|
nsIntPoint* aPtDevPx,
|
||||||
|
bool aShouldClamp) const
|
||||||
{
|
{
|
||||||
nsPresContext* presContext = mOuter->PresContext();
|
nsPresContext* presContext = mOuter->PresContext();
|
||||||
nscoord appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
|
nscoord appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
|
||||||
// Convert to device pixels so we scroll to an integer offset of device
|
// Convert to device pixels so we scroll to an integer offset of device
|
||||||
// pixels. But we also need to make sure that our position remains
|
// pixels. But we also need to make sure that our position remains
|
||||||
// inside the allowed region.
|
// inside the allowed region.
|
||||||
|
if (aShouldClamp) {
|
||||||
nsRect scrollRange = GetScrollRange();
|
nsRect scrollRange = GetScrollRange();
|
||||||
*aPtDevPx = nsIntPoint(ClampInt(scrollRange.x, aPt.x, scrollRange.XMost(), appUnitsPerDevPixel),
|
*aPtDevPx = nsIntPoint(ClampInt(scrollRange.x, aPt.x, scrollRange.XMost(), appUnitsPerDevPixel),
|
||||||
ClampInt(scrollRange.y, aPt.y, scrollRange.YMost(), appUnitsPerDevPixel));
|
ClampInt(scrollRange.y, aPt.y, scrollRange.YMost(), appUnitsPerDevPixel));
|
||||||
|
} else {
|
||||||
|
*aPtDevPx = nsIntPoint(NSAppUnitsToIntPixels(aPt.x, appUnitsPerDevPixel),
|
||||||
|
NSAppUnitsToIntPixels(aPt.y, appUnitsPerDevPixel));
|
||||||
|
}
|
||||||
return nsPoint(NSIntPixelsToAppUnits(aPtDevPx->x, appUnitsPerDevPixel),
|
return nsPoint(NSIntPixelsToAppUnits(aPtDevPx->x, appUnitsPerDevPixel),
|
||||||
NSIntPixelsToAppUnits(aPtDevPx->y, appUnitsPerDevPixel));
|
NSIntPixelsToAppUnits(aPtDevPx->y, appUnitsPerDevPixel));
|
||||||
}
|
}
|
||||||
|
@ -1858,7 +1877,8 @@ nsGfxScrollFrameInner::ScrollToImpl(nsPoint aPt)
|
||||||
nsPresContext* presContext = mOuter->PresContext();
|
nsPresContext* presContext = mOuter->PresContext();
|
||||||
nscoord appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
|
nscoord appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
|
||||||
nsIntPoint ptDevPx;
|
nsIntPoint ptDevPx;
|
||||||
nsPoint pt = ClampAndRestrictToDevPixels(aPt, &ptDevPx);
|
|
||||||
|
nsPoint pt = RestrictToDevPixels(aPt, &ptDevPx, ShouldClampScrollPosition());
|
||||||
|
|
||||||
nsPoint curPos = GetScrollPosition();
|
nsPoint curPos = GetScrollPosition();
|
||||||
if (pt == curPos) {
|
if (pt == curPos) {
|
||||||
|
|
|
@ -177,7 +177,7 @@ public:
|
||||||
}
|
}
|
||||||
nsRect GetScrollRange() const;
|
nsRect GetScrollRange() const;
|
||||||
|
|
||||||
nsPoint ClampAndRestrictToDevPixels(const nsPoint& aPt, nsIntPoint* aPtDevPx) const;
|
nsPoint RestrictToDevPixels(const nsPoint& aPt, nsIntPoint* aPtDevPx, bool aShouldClamp) const;
|
||||||
nsPoint ClampScrollPosition(const nsPoint& aPt) const;
|
nsPoint ClampScrollPosition(const nsPoint& aPt) const;
|
||||||
static void AsyncScrollCallback(nsITimer *aTimer, void* anInstance);
|
static void AsyncScrollCallback(nsITimer *aTimer, void* anInstance);
|
||||||
void ScrollTo(nsPoint aScrollPosition, nsIScrollableFrame::ScrollMode aMode);
|
void ScrollTo(nsPoint aScrollPosition, nsIScrollableFrame::ScrollMode aMode);
|
||||||
|
@ -261,6 +261,8 @@ public:
|
||||||
|
|
||||||
bool IsIgnoringViewportClipping() const;
|
bool IsIgnoringViewportClipping() const;
|
||||||
|
|
||||||
|
bool ShouldClampScrollPosition() const;
|
||||||
|
|
||||||
bool IsAlwaysActive() const;
|
bool IsAlwaysActive() const;
|
||||||
void MarkActive();
|
void MarkActive();
|
||||||
void MarkInactive();
|
void MarkInactive();
|
||||||
|
|
|
@ -130,6 +130,12 @@ public:
|
||||||
return !frameLoader || frameLoader->ShouldClipSubdocument();
|
return !frameLoader || frameLoader->ShouldClipSubdocument();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ShouldClampScrollPosition()
|
||||||
|
{
|
||||||
|
nsFrameLoader* frameLoader = FrameLoader();
|
||||||
|
return !frameLoader || frameLoader->ShouldClampScrollPosition();
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class AsyncFrameInit;
|
friend class AsyncFrameInit;
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче