CLOSED TREE: TraceMonkey merge head. (a=blockers)
[mozilla-central.git] / layout / generic / nsPageContentFrame.cpp
blob769defbeb232be78e12008d8b85960c86eab6e3a
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
37 #include "nsPageContentFrame.h"
38 #include "nsPageFrame.h"
39 #include "nsPlaceholderFrame.h"
40 #include "nsCSSFrameConstructor.h"
41 #include "nsHTMLContainerFrame.h"
42 #include "nsHTMLParts.h"
43 #include "nsIContent.h"
44 #include "nsPresContext.h"
45 #include "nsIRenderingContext.h"
46 #include "nsGkAtoms.h"
47 #include "nsIPresShell.h"
48 #include "nsIDeviceContext.h"
49 #include "nsReadableUtils.h"
50 #include "nsSimplePageSequence.h"
51 #include "nsDisplayList.h"
53 nsIFrame*
54 NS_NewPageContentFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
56 return new (aPresShell) nsPageContentFrame(aContext);
59 NS_IMPL_FRAMEARENA_HELPERS(nsPageContentFrame)
61 /* virtual */ nsSize
62 nsPageContentFrame::ComputeSize(nsIRenderingContext *aRenderingContext,
63 nsSize aCBSize, nscoord aAvailableWidth,
64 nsSize aMargin, nsSize aBorder, nsSize aPadding,
65 PRBool aShrinkWrap)
67 NS_ASSERTION(mPD, "Pages are supposed to have page data");
68 nscoord height = (!mPD || mPD->mReflowSize.height == NS_UNCONSTRAINEDSIZE)
69 ? NS_UNCONSTRAINEDSIZE
70 : (mPD->mReflowSize.height - mPD->mReflowMargin.TopBottom());
71 return nsSize(aAvailableWidth, height);
74 NS_IMETHODIMP
75 nsPageContentFrame::Reflow(nsPresContext* aPresContext,
76 nsHTMLReflowMetrics& aDesiredSize,
77 const nsHTMLReflowState& aReflowState,
78 nsReflowStatus& aStatus)
80 DO_GLOBAL_REFLOW_COUNT("nsPageContentFrame");
81 DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
82 aStatus = NS_FRAME_COMPLETE; // initialize out parameter
83 nsresult rv = NS_OK;
85 if (GetPrevInFlow() && (GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
86 nsresult rv = aPresContext->PresShell()->FrameConstructor()
87 ->ReplicateFixedFrames(this);
88 NS_ENSURE_SUCCESS(rv, rv);
91 // Set our size up front, since some parts of reflow depend on it
92 // being already set. Note that the computed height may be
93 // unconstrained; that's ok. Consumers should watch out for that.
94 SetSize(nsSize(aReflowState.availableWidth, aReflowState.availableHeight));
96 // A PageContentFrame must always have one child: the canvas frame.
97 // Resize our frame allowing it only to be as big as we are
98 // XXX Pay attention to the page's border and padding...
99 if (mFrames.NotEmpty()) {
100 nsIFrame* frame = mFrames.FirstChild();
101 nsSize maxSize(aReflowState.availableWidth, aReflowState.availableHeight);
102 nsHTMLReflowState kidReflowState(aPresContext, aReflowState, frame, maxSize);
103 kidReflowState.SetComputedHeight(aReflowState.availableHeight);
105 mPD->mPageContentSize = aReflowState.availableWidth;
107 // Reflow the page content area
108 rv = ReflowChild(frame, aPresContext, aDesiredSize, kidReflowState, 0, 0, 0, aStatus);
109 NS_ENSURE_SUCCESS(rv, rv);
111 // The document element's background should cover the entire canvas, so
112 // take into account the combined area and any space taken up by
113 // absolutely positioned elements
114 nsMargin padding(0,0,0,0);
116 // XXXbz this screws up percentage padding (sets padding to zero
117 // in the percentage padding case)
118 kidReflowState.mStylePadding->GetPadding(padding);
120 // This is for shrink-to-fit, and therefore we want to use the
121 // scrollable overflow, since the purpose of shrink to fit is to
122 // make the content that ought to be reachable (represented by the
123 // scrollable overflow) fit in the page.
124 if (frame->HasOverflowAreas()) {
125 // The background covers the content area and padding area, so check
126 // for children sticking outside the child frame's padding edge
127 nscoord xmost = aDesiredSize.ScrollableOverflow().XMost();
128 if (xmost > aDesiredSize.width) {
129 mPD->mPageContentXMost =
130 xmost +
131 kidReflowState.mStyleBorder->GetActualBorderWidth(NS_SIDE_RIGHT) +
132 padding.right;
136 // Place and size the child
137 FinishReflowChild(frame, aPresContext, &kidReflowState, aDesiredSize, 0, 0, 0);
139 NS_ASSERTION(aPresContext->IsDynamic() || !NS_FRAME_IS_FULLY_COMPLETE(aStatus) ||
140 !frame->GetNextInFlow(), "bad child flow list");
142 // Reflow our fixed frames
143 nsReflowStatus fixedStatus = NS_FRAME_COMPLETE;
144 mFixedContainer.Reflow(this, aPresContext, aReflowState, fixedStatus,
145 aReflowState.availableWidth,
146 aReflowState.availableHeight,
147 PR_FALSE, PR_TRUE, PR_TRUE, // XXX could be optimized
148 nsnull /* ignore overflow */);
149 NS_ASSERTION(NS_FRAME_IS_COMPLETE(fixedStatus), "fixed frames can be truncated, but not incomplete");
151 // Return our desired size
152 aDesiredSize.width = aReflowState.availableWidth;
153 if (aReflowState.availableHeight != NS_UNCONSTRAINEDSIZE) {
154 aDesiredSize.height = aReflowState.availableHeight;
157 FinishAndStoreOverflow(&aDesiredSize);
159 NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
160 return NS_OK;
163 nsIAtom*
164 nsPageContentFrame::GetType() const
166 return nsGkAtoms::pageContentFrame;
169 #ifdef DEBUG
170 NS_IMETHODIMP
171 nsPageContentFrame::GetFrameName(nsAString& aResult) const
173 return MakeFrameName(NS_LITERAL_STRING("PageContent"), aResult);
175 #endif
177 /* virtual */ PRBool
178 nsPageContentFrame::IsContainingBlock() const
180 return PR_TRUE;