Index: mozilla/layout/base/nsLayoutUtils.cpp =================================================================== RCS file: /cvsroot/mozilla/layout/base/nsLayoutUtils.cpp,v retrieving revision 3.61 diff -tpU5 -r3.61 mozilla/layout/base/nsLayoutUtils.cpp --- mozilla/layout/base/nsLayoutUtils.cpp +++ mozilla/layout/base/nsLayoutUtils.cpp @@ -47,10 +47,11 @@ #include "nsCSSPseudoElements.h" #include "nsIView.h" #include "nsIScrollableView.h" #include "nsPlaceholderFrame.h" #include "nsIScrollableFrame.h" +#include "nsIFrameFrame.h" #include "nsCSSFrameConstructor.h" #include "nsIPrivateDOMEvent.h" #include "nsIDOMEvent.h" #include "nsGUIEvent.h" #include "nsDisplayList.h" @@ -396,10 +397,31 @@ nsLayoutUtils::FindSiblingViewFor(nsIVie } return nsnull; } //static +nsIFrameFrame* +nsLayoutUtils::GetSubDocumentFrameFor(nsPresContext* aPresContext) { + nsIView* rootView; + aPresContext->GetViewManager()->GetRootView(rootView); + // Look up two in the view chain because subdoc frames have an outer view + // and an inner view + nsIView* view = rootView->GetParent(); + if (!view) + return nsnull; + view = view->GetParent(); + if (!view) + return nsnull; + nsIFrame* f = nsLayoutUtils::GetFrameFor(view); + if (!f) + return nsnull; + nsIFrameFrame* result; + CallQueryInterface(f, &result); + return result; +} + +//static nsIScrollableFrame* nsLayoutUtils::GetScrollableFrameFor(nsIFrame *aScrolledFrame) { nsIFrame *frame = aScrolledFrame->GetParent(); if (!frame) { Index: mozilla/layout/base/nsLayoutUtils.h =================================================================== RCS file: /cvsroot/mozilla/layout/base/nsLayoutUtils.h,v retrieving revision 3.35 diff -tpU5 -r3.35 mozilla/layout/base/nsLayoutUtils.h --- mozilla/layout/base/nsLayoutUtils.h +++ mozilla/layout/base/nsLayoutUtils.h @@ -43,10 +43,11 @@ class nsIFormControlFrame; class nsPresContext; class nsIContent; class nsIAtom; class nsIScrollableView; class nsIScrollableFrame; +class nsIFrameFrame; class nsIDOMEvent; class nsRegion; class nsDisplayListBuilder; #include "prtypes.h" @@ -187,10 +188,17 @@ public: */ static nsIFrame* GetFrameFor(nsIView *aView) { return NS_STATIC_CAST(nsIFrame*, aView->GetClientData()); } /** + * @return the subdocument frame for which this document is the + * subdocument, or nsnull if this document is the root of a + * hooked-up viewmanager hierarchy. + */ + static nsIFrameFrame* GetSubDocumentFrameFor(nsPresContext* aPresContext); + + /** * GetScrollableFrameFor returns the scrollable frame for a scrollable view * @param aScrollableView is the scrollable view to return the * scrollable frame for. * @return the scrollable frame for the scrollable view */ Index: mozilla/layout/base/nsPresShell.cpp =================================================================== RCS file: /cvsroot/mozilla/layout/base/nsPresShell.cpp,v retrieving revision 3.920 diff -tpU5 -r3.920 mozilla/layout/base/nsPresShell.cpp --- mozilla/layout/base/nsPresShell.cpp +++ mozilla/layout/base/nsPresShell.cpp @@ -129,10 +129,11 @@ #include "plarena.h" #include "pldhash.h" #include "nsIObserverService.h" #include "nsIObserver.h" #include "nsIDocShell.h" // for reflow observation +#include "nsIFrameFrame.h" #include "nsIBaseWindow.h" #include "nsLayoutErrors.h" #include "nsLayoutUtils.h" #include "nsCSSRendering.h" #ifdef NS_DEBUG @@ -6525,12 +6526,24 @@ PresShell::DidDoReflow() HandlePostedDOMEvents(); HandlePostedAttributeChanges(); HandlePostedReflowCallbacks(); // Null-check mViewManager in case this happens during Destroy. See // bugs 244435 and 238546. - if (!mPaintingSuppressed && mViewManager) - mViewManager->SynthesizeMouseMove(PR_FALSE); + if (mViewManager) { + if (!mPaintingSuppressed) { + mViewManager->SynthesizeMouseMove(PR_FALSE); + } + + // See if we belong to an IFRAME that might want to intrinsically + // size itself. + nsIFrameFrame* subdocFrame = nsLayoutUtils::GetSubDocumentFrameFor(mPresContext); + if (subdocFrame) { + // Tell the IFRAME that we reflowed, so it should check to see if + // it needs to reflow itself. + subdocFrame->NotifySubdocumentReflowed(); + } + } if (mCaret) mCaret->InvalidateOutsideCaret(); } nsresult Index: mozilla/layout/generic/nsBlockFrame.cpp =================================================================== RCS file: /cvsroot/mozilla/layout/generic/nsBlockFrame.cpp,v retrieving revision 3.780 diff -tpU5 -r3.780 mozilla/layout/generic/nsBlockFrame.cpp --- mozilla/layout/generic/nsBlockFrame.cpp +++ mozilla/layout/generic/nsBlockFrame.cpp @@ -1441,11 +1441,11 @@ nsBlockFrame::ComputeFinalSize(const nsH } // Don't carry out a bottom margin when our height is fixed. aMetrics.mCarriedOutBottomMargin.Zero(); } - else { + nscoord autoHeight = aState.mY + nonCarriedOutVerticalMargin; // Shrink wrap our height around our contents. if (aState.GetFlag(BRS_ISBOTTOMMARGINROOT)) { // When we are a bottom-margin root make sure that our last @@ -1474,13 +1474,18 @@ nsBlockFrame::ComputeFinalSize(const nsH if (autoHeight != oldAutoHeight) { // Our min-height or max-height made our height change. Don't carry out // our kids' bottom margins. aMetrics.mCarriedOutBottomMargin.Zero(); } + autoHeight += borderPadding.top + borderPadding.bottom; + + if (NS_UNCONSTRAINEDSIZE == aReflowState.mComputedHeight) { + aMetrics.height = autoHeight; } + aMetrics.mAutoHeight = autoHeight; // XXXbernd this should be revised when inline-blocks are implemented if (GetFirstChild(nsnull)) aMetrics.ascent = mAscent; else Index: mozilla/layout/generic/nsFrame.cpp =================================================================== RCS file: /cvsroot/mozilla/layout/generic/nsFrame.cpp,v retrieving revision 3.656 diff -tpU5 -r3.656 mozilla/layout/generic/nsFrame.cpp --- mozilla/layout/generic/nsFrame.cpp +++ mozilla/layout/generic/nsFrame.cpp @@ -5454,10 +5454,16 @@ nsFrame::DoLayout(nsBoxLayoutState& aSta } rv = BoxReflow(aState, presContext, desiredSize, *reflowState, status, ourRect.x, ourRect.y, ourRect.width, ourRect.height); + // If this is a scrolled frame then record the auto height if known + nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetScrollableFrameFor(this); + if (scrollFrame) { + scrollFrame->SetChildUnstretchedHeight(desiredSize.mAutoHeight); + } + if (currentMEW && desiredSize.mMaxElementWidth > *currentMEW) { *currentMEW = desiredSize.mMaxElementWidth; } PRBool collapsed = PR_FALSE; Index: mozilla/layout/generic/nsFrameFrame.cpp =================================================================== RCS file: /cvsroot/mozilla/layout/generic/nsFrameFrame.cpp,v retrieving revision 3.304 diff -tpU5 -r3.304 mozilla/layout/generic/nsFrameFrame.cpp --- mozilla/layout/generic/nsFrameFrame.cpp +++ mozilla/layout/generic/nsFrameFrame.cpp @@ -85,10 +85,12 @@ #include "nsIDOMWindow.h" #include "nsIDOMDocument.h" #include "nsIRenderingContext.h" #include "nsIFrameFrame.h" #include "nsAutoPtr.h" +#include "nsLayoutUtils.h" +#include "nsIScrollableFrame.h" #include "nsIDOMNSHTMLDocument.h" #include "nsDisplayList.h" #include "nsUnicharUtils.h" // For Accessibility @@ -142,40 +144,49 @@ public: // and all our contents. We don't extend "visibility:hidden" to // the child content ourselves, since it belongs to a different // document and CSS doesn't inherit in there. virtual PRBool SupportsVisibilityHidden() { return PR_FALSE; } + PRBool IsSameOriginSubdoc(); + #ifdef ACCESSIBILITY NS_IMETHOD GetAccessible(nsIAccessible** aAccessible); #endif // nsIFrameFrame NS_IMETHOD GetDocShell(nsIDocShell **aDocShell); + virtual void NotifySubdocumentReflowed(); + virtual PRBool UsingIntrinsicHeight() { return mUsingIntrinsicHeight; } NS_IMETHOD VerifyTree() const; protected: nsSize GetMargin(); PRBool IsInline() { return mIsInline; } nsresult ShowDocShell(); nsresult CreateViewAndWidget(nsContentType aContentType); + // virtual in nsLeafFrame virtual void GetDesiredSize(nsPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsHTMLReflowMetrics& aDesiredSize); virtual PRIntn GetSkipSides() const; nsCOMPtr mFrameLoader; nsIView* mInnerView; PRPackedBool mDidCreateDoc; PRPackedBool mOwnsFrameLoader; PRPackedBool mIsInline; + PRPackedBool mInReflow; + PRPackedBool mUsingIntrinsicHeight; }; nsSubDocumentFrame::nsSubDocumentFrame(nsStyleContext* aContext) - : nsLeafFrame(aContext), mDidCreateDoc(PR_FALSE), mOwnsFrameLoader(PR_FALSE), - mIsInline(PR_FALSE) + : nsLeafFrame(aContext), mInnerView(nsnull), + mDidCreateDoc(PR_FALSE), mOwnsFrameLoader(PR_FALSE), + mIsInline(PR_FALSE), mInReflow(PR_FALSE), + mUsingIntrinsicHeight(PR_FALSE) { } #ifdef ACCESSIBILITY NS_IMETHODIMP nsSubDocumentFrame::GetAccessible(nsIAccessible** aAccessible) @@ -280,10 +291,86 @@ PRIntn nsSubDocumentFrame::GetSkipSides() const { return 0; } +static +nscoord GetDesiredHeightFromInnerView(nsIView* aInnerView) +{ + if (!aInnerView) + return NS_UNCONSTRAINEDSIZE; + + nsIView* subdocView = aInnerView->GetFirstChild(); + if (!subdocView) + return NS_UNCONSTRAINEDSIZE; + + nscoord height = subdocView->GetBounds().height; + nsIScrollableView* scrollableView; + subdocView->GetViewManager()->GetRootScrollableView(&scrollableView); + if (!scrollableView) + return height; + + nsIScrollableFrame* scrollFrame = + nsLayoutUtils::GetScrollableFrameFor(scrollableView); + if (!scrollFrame) + return height; + + nsMargin scrollbars = scrollFrame->GetActualScrollbarSizes(); + height = scrollFrame->GetChildUnstretchedHeight(); + if (height != NS_UNCONSTRAINEDSIZE) + height += scrollbars.top + scrollbars.bottom; + return height; +} + +static +nscoord ComputeMinMaxConstrainedHeight(nscoord aHeight, + const nsHTMLReflowState& aReflowState) +{ + return PR_MAX(PR_MIN(aHeight, aReflowState.mComputedMaxHeight), + aReflowState.mComputedMinHeight); +} + +/** + * @return PR_TRUE if this document has the same origin as the subdocument. + * In all cases where we're unsure, we stay conservative and assume they're + * different. + */ +PRBool +nsSubDocumentFrame::IsSameOriginSubdoc() +{ + nsIDocument* doc = GetPresContext()->GetDocument(); + if (!doc) + return PR_FALSE; + nsIURI* docURI = doc->GetDocumentURI(); + + if (!mInnerView) + return PR_FALSE; + nsIView* subdocView = mInnerView->GetFirstChild(); + if (!subdocView) + return PR_FALSE; + nsIFrame* subdocRoot = nsLayoutUtils::GetFrameFor(subdocView); + if (!subdocRoot) + return PR_FALSE; + + nsIDocument* subdoc = subdocRoot->GetPresContext()->GetDocument(); + if (!subdoc) + return PR_FALSE; + nsIURI* subdocURI = subdoc->GetDocumentURI(); + + if (!subdocURI || !docURI) + return PR_FALSE; + + nsresult rv; + nsCOMPtr secMan = + do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); + if (NS_FAILED(rv)) + return PR_FALSE; + + rv = secMan->CheckSameOriginURI(docURI, subdocURI); + return NS_SUCCEEDED(rv); +} + NS_IMETHODIMP nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { @@ -334,18 +421,42 @@ nsSubDocumentFrame::GetDesiredSize(nsPre } if (NS_UNCONSTRAINEDSIZE != aReflowState.mComputedHeight) { aDesiredSize.height = aReflowState.mComputedHeight; } else { - aDesiredSize.height = PR_MAX(PR_MIN(NSIntPixelsToTwips(150, p2t), - aReflowState.mComputedMaxHeight), - aReflowState.mComputedMinHeight); + // Only allow the intrinsic height to be used if the + // documents have the same origin. Otherwise the height + // of the subdocument might leak information to a third party. + aDesiredSize.height = NSIntPixelsToTwips(150, p2t); + nscoord internalHeight = GetDesiredHeightFromInnerView(mInnerView); + if (internalHeight != NS_UNCONSTRAINEDSIZE && IsSameOriginSubdoc()) { + aDesiredSize.height = internalHeight; + } + aDesiredSize.height = + ComputeMinMaxConstrainedHeight(aDesiredSize.height, aReflowState); } aDesiredSize.ascent = aDesiredSize.height; aDesiredSize.descent = 0; } +void +nsSubDocumentFrame::NotifySubdocumentReflowed() +{ + // Ignore notifications while we're reflowing, because we must have + // caused the reflow of the child. + if (mInReflow || !mUsingIntrinsicHeight || !mInnerView) + return; + + // If the desired height is still the current height, then no need + // to reflow. + nscoord newDesiredHeight = GetDesiredHeightFromInnerView(mInnerView); + if (newDesiredHeight == mInnerView->GetBounds().height) + return; + + GetParent()->ReflowDirtyChild(GetPresContext()->GetPresShell(), this); +} + #ifdef DEBUG NS_IMETHODIMP nsSubDocumentFrame::GetFrameName(nsAString& aResult) const { return MakeFrameName(NS_LITERAL_STRING("FrameOuter"), aResult); } @@ -368,14 +479,22 @@ nsSubDocumentFrame::Reflow(nsPresContext // printf("OuterFrame::Reflow %X (%d,%d) \n", this, aReflowState.availableWidth, aReflowState.availableHeight); NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS, ("enter nsSubDocumentFrame::Reflow: maxSize=%d,%d reason=%d", aReflowState.availableWidth, aReflowState.availableHeight, aReflowState.reason)); + PRInt32 reflowIterations = 0; + mInReflow = PR_TRUE; + + do { aStatus = NS_FRAME_COMPLETE; + mUsingIntrinsicHeight = PR_FALSE; if (IsInline()) { + mUsingIntrinsicHeight = aReflowState.mComputedHeight == NS_UNCONSTRAINEDSIZE; GetDesiredSize(aPresContext, aReflowState, aDesiredSize); // IFRAME + aDesiredSize.ascent = aDesiredSize.height; + aDesiredSize.descent = 0; } else { aDesiredSize.width = aReflowState.availableWidth; // FRAME aDesiredSize.height = aReflowState.availableHeight; } @@ -445,10 +564,23 @@ nsSubDocumentFrame::Reflow(nsPresContext PRInt32 cy = NSToCoordRound(innerSize.height * t2p); baseWindow->SetPositionAndSize(x, y, cx, cy, PR_FALSE); } } + if (!mUsingIntrinsicHeight) + break; + nscoord newDesiredHeight = GetDesiredHeightFromInnerView(mInnerView); + if (newDesiredHeight == NS_UNCONSTRAINEDSIZE || + ComputeMinMaxConstrainedHeight(newDesiredHeight, aReflowState) + == innerSize.height) + break; + + ++reflowIterations; + } while (reflowIterations < 2); + + mInReflow = PR_FALSE; + // printf("OuterFrame::Reflow DONE %X (%d,%d), MEW=%d(%d)\n", this, // aDesiredSize.width, aDesiredSize.height, aDesiredSize.mMaxElementWidth, // aDesiredSize.mComputeMEW); NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS, Index: mozilla/layout/generic/nsHTMLFrame.cpp =================================================================== RCS file: /cvsroot/mozilla/layout/generic/nsHTMLFrame.cpp,v retrieving revision 1.164 diff -tpU5 -r1.164 mozilla/layout/generic/nsHTMLFrame.cpp --- mozilla/layout/generic/nsHTMLFrame.cpp +++ mozilla/layout/generic/nsHTMLFrame.cpp @@ -56,13 +56,15 @@ #include "nsStyleConsts.h" #include "nsIViewManager.h" #include "nsHTMLAtoms.h" #include "nsIEventStateManager.h" #include "nsIDeviceContext.h" +#include "nsIFrameFrame.h" #include "nsLayoutAtoms.h" #include "nsIPresShell.h" #include "nsIScrollPositionListener.h" +#include "nsLayoutUtils.h" #include "nsDisplayList.h" // for focus #include "nsIDOMWindowInternal.h" #include "nsIFocusController.h" @@ -595,16 +597,24 @@ CanvasFrame::Reflow(nsPresContext* reason = eReflowReason_StyleChange; } else { reason = aReflowState.reason; } + nscoord kidContainingBlockHeight = aReflowState.mComputedHeight; + nsIFrameFrame* subdocFrame = nsLayoutUtils::GetSubDocumentFrameFor(aPresContext); + if (subdocFrame && subdocFrame->UsingIntrinsicHeight()) { + // don't allow the kid to use our height as a containing block + // height, otherwise we could end up in a nasty feedback loop. + kidContainingBlockHeight = NS_AUTOHEIGHT; + } // We must specify an unconstrained available height, because constrained // is only for when we're paginated... nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame, nsSize(aReflowState.availableWidth, NS_UNCONSTRAINEDSIZE), - reason); + aReflowState.mComputedWidth, + kidContainingBlockHeight, reason); // Reflow the frame ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState, kidReflowState.mComputedMargin.left, kidReflowState.mComputedMargin.top, 0, aStatus); @@ -637,11 +647,14 @@ CanvasFrame::Reflow(nsPresContext* nsRect(0, 0, aDesiredSize.width, aDesiredSize.height), kidDesiredSize.mOverflowArea + nsPoint(kidReflowState.mComputedMargin.left, kidReflowState.mComputedMargin.top)); FinishAndStoreOverflow(&aDesiredSize); - + if (kidDesiredSize.mAutoHeight != NS_UNCONSTRAINEDSIZE) { + aDesiredSize.mAutoHeight = kidDesiredSize.mAutoHeight + + kidReflowState.mComputedMargin.top + kidReflowState.mComputedMargin.bottom; + } aDesiredSize.ascent = aDesiredSize.height; aDesiredSize.descent = 0; } NS_FRAME_TRACE_REFLOW_OUT("CanvasFrame::Reflow", aStatus); Index: mozilla/layout/generic/nsHTMLReflowMetrics.h =================================================================== RCS file: /cvsroot/mozilla/layout/generic/nsHTMLReflowMetrics.h,v retrieving revision 3.14 diff -tpU5 -r3.14 mozilla/layout/generic/nsHTMLReflowMetrics.h --- mozilla/layout/generic/nsHTMLReflowMetrics.h +++ mozilla/layout/generic/nsHTMLReflowMetrics.h @@ -39,10 +39,11 @@ #ifndef nsHTMLReflowMetrics_h___ #define nsHTMLReflowMetrics_h___ #include +#include "nsHTMLReflowState.h" #include "nsISupports.h" #include "nsMargin.h" #include "nsRect.h" // for MOZ_MATHML #include "nsIRenderingContext.h" //to get struct nsBoundingMetrics @@ -147,10 +148,14 @@ struct nsHTMLReflowMetrics { // Used for incremental reflow. If the NS_REFLOW_CALC_MAX_WIDTH flag is set, // then the caller is requesting that you update and return your maximum width nscoord mMaximumWidth; // [OUT] + // Can record the height a frame would have had if it had auto height, + // or NS_UNCONSTRAINEDSIZE if not available. Blocks set this. + nscoord mAutoHeight; // [OPTIONAL OUT] + #ifdef MOZ_MATHML // Metrics that _exactly_ enclose the text to allow precise MathML placements. // If the NS_REFLOW_CALC_BOUNDING_METRICS flag is set, then the caller is // requesting that you also compute additional details about your inner // bounding box and italic correction. For example, the bounding box of @@ -198,10 +203,12 @@ struct nsHTMLReflowMetrics { // XXX These are OUT parameters and so they shouldn't have to be // initialized, but there are some bad frame classes that aren't // properly setting them when returning from Reflow()... width = height = 0; ascent = descent = 0; + // This one is optional to set. + mAutoHeight = NS_UNCONSTRAINEDSIZE; } /** * set the maxElementWidth to the desired width. If the frame has a percent * width specification it can be shrinked to 0 if the containing frame shrinks Index: mozilla/layout/generic/nsHTMLReflowState.cpp =================================================================== RCS file: /cvsroot/mozilla/layout/generic/nsHTMLReflowState.cpp,v retrieving revision 1.238 diff -tpU5 -r1.238 mozilla/layout/generic/nsHTMLReflowState.cpp --- mozilla/layout/generic/nsHTMLReflowState.cpp +++ mozilla/layout/generic/nsHTMLReflowState.cpp @@ -48,10 +48,11 @@ #include "nsLayoutAtoms.h" #include "nsIDeviceContext.h" #include "nsIRenderingContext.h" #include "nsIFontMetrics.h" #include "nsBlockFrame.h" +#include "nsIFrameFrame.h" #include "nsLineBox.h" #include "nsImageFrame.h" #include "nsIServiceManager.h" #include "nsIPercentHeightObserver.h" #include "nsContentUtils.h" @@ -1503,10 +1504,18 @@ CalcQuirkContainingBlockHeight(const nsH continue; } } } else if (nsLayoutAtoms::canvasFrame == frameType) { + // if it's an auto-height IFRAME then just bail out and + // don't try to use anything. + nsIFrameFrame* subdocFrame = + nsLayoutUtils::GetSubDocumentFrameFor(rs->frame->GetPresContext()); + if (subdocFrame && subdocFrame->UsingIntrinsicHeight()) { + break; + } + // Use scroll frames' computed height if we have one, this will // allow us to get viewport height for native scrollbars. nsHTMLReflowState* scrollState = (nsHTMLReflowState *)rs->parentReflowState; if (nsLayoutAtoms::scrollFrame == scrollState->frame->GetType()) { rs = scrollState; @@ -1609,20 +1618,27 @@ nsHTMLReflowState::ComputeContainingBloc // If the containing block is the initial containing block and it has a // height that depends on its content, then use the viewport height instead. // This gives us a reasonable value against which to compute percentage // based heights and to do bottom relative positioning - if ((NS_AUTOHEIGHT == aContainingBlockHeight) && - nsLayoutUtils::IsInitialContainingBlock(aContainingBlockRS->frame)) { - + if (NS_AUTOHEIGHT == aContainingBlockHeight) { + // Even if this is an intrinsically sized IFRAME, it's OK to + // use the viewport height here because the placement of + // absolute children will affect the intrinsic size, so we + // won't get into a feedback loop. + PRBool useViewportHeight = + nsLayoutUtils::IsInitialContainingBlock(aContainingBlockRS->frame); + if (useViewportHeight) { // Use the viewport height as the containing block height const nsHTMLReflowState* rs = aContainingBlockRS->parentReflowState; while (rs) { aContainingBlockHeight = rs->mComputedHeight; rs = rs->parentReflowState; } - + } else { + // XXX what to do here? we shouldn't start doing arithmetic on the height + } } else { aContainingBlockHeight += aContainingBlockRS->mComputedPadding.TopBottom(); } } Index: mozilla/layout/generic/nsIFrameFrame.h =================================================================== RCS file: /cvsroot/mozilla/layout/generic/nsIFrameFrame.h,v retrieving revision 3.5 diff -tpU5 -r3.5 mozilla/layout/generic/nsIFrameFrame.h --- mozilla/layout/generic/nsIFrameFrame.h +++ mozilla/layout/generic/nsIFrameFrame.h @@ -53,10 +53,14 @@ class nsIFrameFrame : public nsISupports { public: NS_DECLARE_STATIC_IID_ACCESSOR(NS_IFRAMEFRAME_IID) NS_IMETHOD GetDocShell(nsIDocShell **aDocShell) = 0; + + virtual void NotifySubdocumentReflowed() = 0; + + virtual PRBool UsingIntrinsicHeight() = 0; }; NS_DEFINE_STATIC_IID_ACCESSOR(nsIFrameFrame, NS_IFRAMEFRAME_IID) #endif Index: mozilla/layout/generic/nsIScrollableFrame.h =================================================================== RCS file: /cvsroot/mozilla/layout/generic/nsIScrollableFrame.h,v retrieving revision 3.34 diff -tpU5 -r3.34 mozilla/layout/generic/nsIScrollableFrame.h --- mozilla/layout/generic/nsIScrollableFrame.h +++ mozilla/layout/generic/nsIScrollableFrame.h @@ -55,23 +55,41 @@ class nsBoxLayoutState; // IID for the nsIScrollableFrame interface #define NS_ISCROLLABLE_FRAME_IID \ { 0xf285c180, 0x8492, 0x48d5, \ { 0xb1, 0xb5, 0x03, 0x28, 0x21, 0xc9, 0x72, 0x02 } } +/** This class has data members. It is not a pure interface. */ class nsIScrollableFrame : public nsIScrollableViewProvider { public: + nsIScrollableFrame() : mChildUnstretchedHeight(NS_UNCONSTRAINEDSIZE) {} NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISCROLLABLE_FRAME_IID) /** * Get the frame that we are scrolling within the scrollable frame. * @result child frame */ virtual nsIFrame* GetScrolledFrame() const = 0; - typedef nsPresContext::ScrollbarStyles ScrollbarStyles; + /** + * Get the height of the scrolled frame before it was stretched to be + * at least the height of the scrollport. Returns NS_UNCONSTRAINEDSIZE + * if unknown. + */ + nscoord GetChildUnstretchedHeight() const { return mChildUnstretchedHeight; } + + /** + * Set the size of the scrolled frame before it was stretched to be + * at least the size of the scrollport. + */ + void SetChildUnstretchedHeight(nscoord aHeight) { mChildUnstretchedHeight = aHeight; } + /** + * Get the scrollbar styles being used to style this + * scrollframe. This accounts for weird scrollbar style inheritance. + */ + typedef nsPresContext::ScrollbarStyles ScrollbarStyles; virtual ScrollbarStyles GetScrollbarStyles() const = 0; /** * Return the actual sizes of all possible scrollbars. Returns 0 for scrollbar * positions that don't have a scrollbar or where the scrollbar is not visible. @@ -120,10 +138,13 @@ public: * at least once after state has been restored. It is called by the * scrolled frame itself during reflow, but sometimes state can be * restored after reflows are done... */ virtual void ScrollToRestoredPosition() = 0; + +private: + nscoord mChildUnstretchedHeight; }; NS_DEFINE_STATIC_IID_ACCESSOR(nsIScrollableFrame, NS_ISCROLLABLE_FRAME_IID) #endif