Bug 716403 - Add nsIDOMWindowUtils.setContentDocumentFixedPositionMargins. r=roc,dholbert

Add a function to set margins on the viewport that are respected by its
absolute containing block. This has the effect of being able to add margins to
fixed position content, which will be used on mobile to stop temporarily
visible chrome from obscuring content.
This commit is contained in:
Chris Lord 2013-03-06 16:56:00 +00:00
parent 3666e38db8
commit a33dfc4946
5 changed files with 95 additions and 14 deletions

View File

@ -2937,6 +2937,32 @@ nsDOMWindowUtils::SetScrollPositionClampingScrollPortSize(float aWidth, float aH
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::SetContentDocumentFixedPositionMargins(float aTop, float aRight,
float aBottom, float aLeft)
{
if (!nsContentUtils::IsCallerChrome()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
if (!(aTop >= 0.0f && aRight >= 0.0f && aBottom >= 0.0f && aLeft >= 0.0f)) {
return NS_ERROR_ILLEGAL_VALUE;
}
nsIPresShell* presShell = GetPresShell();
if (!presShell) {
return NS_ERROR_FAILURE;
}
nsMargin margins(nsPresContext::CSSPixelsToAppUnits(aTop),
nsPresContext::CSSPixelsToAppUnits(aRight),
nsPresContext::CSSPixelsToAppUnits(aBottom),
nsPresContext::CSSPixelsToAppUnits(aLeft));
presShell->SetContentDocumentFixedPositionMargins(margins);
return NS_OK;
}
nsresult
nsDOMWindowUtils::RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement,
const nsAString& aNewOrigin)

View File

@ -41,7 +41,7 @@ interface nsIDOMClientRect;
interface nsIURI;
interface nsIDOMEventTarget;
[scriptable, uuid(9ab64e24-7f8d-11e2-9a5f-a24379957a39)]
[scriptable, uuid(69b7d908-c8e4-4416-94cf-4fdbe7a80441)]
interface nsIDOMWindowUtils : nsISupports {
/**
@ -1288,6 +1288,19 @@ interface nsIDOMWindowUtils : nsISupports {
*/
void setScrollPositionClampingScrollPortSize(in float aWidth, in float aHeight);
/**
* Set margins for the layout of fixed position elements in the content
* document. These are used on mobile, where the viewable area can be
* temporarily obscured by the browser chrome. In this situation, we're ok
* with scrollable page content being obscured, but fixed position content
* cannot be revealed without removing the obscuring chrome, so we use these
* margins so that it can remain visible.
*
* The caller of this method must have chrome privileges.
*/
void setContentDocumentFixedPositionMargins(in float aTop, in float aRight,
in float aBottom, in float aLeft);
/**
* Prevent this window (and any child windows) from displaying any further
* dialogs (e.g. window.alert()).

View File

@ -121,10 +121,10 @@ typedef struct CapturingContentInfo {
nsIContent* mContent;
} CapturingContentInfo;
// 835b3946-1a4f-4132-b3ce-2e2e8be377c8
// bf539e0a-c314-4ea7-ba7c-ebd34e8a4065
#define NS_IPRESSHELL_IID \
{ 0x835b3946, 0x1a4f, 0x4132, \
{ 0xb3, 0xce, 0x2e, 0x2e, 0x8b, 0xe3, 0x77, 0xc8 } }
{ 0xbf539e0a, 0xc314, 0x4ea7, \
{ 0xba, 0x7c, 0xeb, 0xd3, 0x4e, 0x8a, 0x40, 0x65 } }
// debug VerifyReflow flags
#define VERIFY_REFLOW_ON 0x01
@ -498,6 +498,11 @@ public:
IntrinsicDirty aIntrinsicDirty,
nsFrameState aBitToAdd) = 0;
/**
* Calls FrameNeedsReflow on all fixed position children of the root frame.
*/
virtual void MarkFixedFramesForReflow(IntrinsicDirty aIntrinsicDirty);
/**
* Tell the presshell that the given frame's reflow was interrupted. This
* will mark as having dirty children a path from the given frame (inclusive)
@ -1381,6 +1386,11 @@ public:
return mScrollPositionClampingScrollPortSize;
}
void SetContentDocumentFixedPositionMargins(const nsMargin& aMargins);
const nsMargin& GetContentDocumentFixedPositionMargins() {
return mContentDocumentFixedPositionMargins;
}
virtual void WindowSizeMoveDone() = 0;
virtual void SysColorChanged() = 0;
virtual void ThemeChanged() = 0;
@ -1428,6 +1438,12 @@ protected:
nsSize mScrollPositionClampingScrollPortSize;
// This margin is intended to be used when laying out fixed position children
// on this PresShell's viewport frame. See the documentation of
// nsIDOMWindowUtils.setContentDocumentFixedPositionMargins for details of
// their use.
nsMargin mContentDocumentFixedPositionMargins;
// A list of weak frames. This is a pointer to the last item in the list.
nsWeakFrame* mWeakFrames;

View File

@ -9440,6 +9440,18 @@ PresShell::SizeOfTextRuns(nsMallocSizeOfFun aMallocSizeOf) const
/* clear = */false);
}
void
nsIPresShell::MarkFixedFramesForReflow(IntrinsicDirty aIntrinsicDirty)
{
nsIFrame* rootFrame = mFrameConstructor->GetRootFrame();
if (rootFrame) {
const nsFrameList& childList = rootFrame->GetChildList(nsIFrame::kFixedList);
for (nsFrameList::Enumerator e(childList); !e.AtEnd(); e.Next()) {
FrameNeedsReflow(e.get(), aIntrinsicDirty, NS_FRAME_IS_DIRTY);
}
}
}
void
nsIPresShell::SetScrollPositionClampingScrollPortSize(nscoord aWidth, nscoord aHeight)
{
@ -9450,18 +9462,22 @@ nsIPresShell::SetScrollPositionClampingScrollPortSize(nscoord aWidth, nscoord aH
mScrollPositionClampingScrollPortSize.width = aWidth;
mScrollPositionClampingScrollPortSize.height = aHeight;
// Reflow fixed position children.
nsIFrame* rootFrame = mFrameConstructor->GetRootFrame();
if (rootFrame) {
const nsFrameList& childList = rootFrame->GetChildList(nsIFrame::kFixedList);
for (nsIFrame* child = childList.FirstChild(); child;
child = child->GetNextSibling()) {
FrameNeedsReflow(child, eResize, NS_FRAME_IS_DIRTY);
}
}
MarkFixedFramesForReflow(eResize);
}
}
void
nsIPresShell::SetContentDocumentFixedPositionMargins(const nsMargin& aMargins)
{
if (mContentDocumentFixedPositionMargins == aMargins) {
return;
}
mContentDocumentFixedPositionMargins = aMargins;
MarkFixedFramesForReflow(eResize);
}
void
PresShell::SetupFontInflation()
{

View File

@ -366,7 +366,17 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat
nsresult rv;
// Get the border values
const nsMargin& border = aReflowState.mStyleBorder->GetComputedBorder();
nsMargin border = aReflowState.mStyleBorder->GetComputedBorder();
// Respect fixed position margins.
if (aDelegatingFrame->GetAbsoluteListID() == nsIFrame::kFixedList) {
const nsMargin& fixedMargins = aPresContext->PresShell()->
GetContentDocumentFixedPositionMargins();
border += fixedMargins;
aContainingBlockWidth -= fixedMargins.left + fixedMargins.right;
aContainingBlockHeight -= fixedMargins.top + fixedMargins.bottom;
}
nscoord availWidth = aContainingBlockWidth;
if (availWidth == -1) {