|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 #ifndef nsTableRowFrame_h__ |
|
6 #define nsTableRowFrame_h__ |
|
7 |
|
8 #include "mozilla/Attributes.h" |
|
9 #include "nscore.h" |
|
10 #include "nsContainerFrame.h" |
|
11 #include "nsTablePainter.h" |
|
12 |
|
13 class nsTableFrame; |
|
14 class nsTableCellFrame; |
|
15 struct nsTableCellReflowState; |
|
16 |
|
17 /** |
|
18 * nsTableRowFrame is the frame that maps table rows |
|
19 * (HTML tag TR). This class cannot be reused |
|
20 * outside of an nsTableRowGroupFrame. It assumes that its parent is an nsTableRowGroupFrame, |
|
21 * and its children are nsTableCellFrames. |
|
22 * |
|
23 * @see nsTableFrame |
|
24 * @see nsTableRowGroupFrame |
|
25 * @see nsTableCellFrame |
|
26 */ |
|
27 class nsTableRowFrame : public nsContainerFrame |
|
28 { |
|
29 public: |
|
30 NS_DECL_QUERYFRAME_TARGET(nsTableRowFrame) |
|
31 NS_DECL_QUERYFRAME |
|
32 NS_DECL_FRAMEARENA_HELPERS |
|
33 |
|
34 virtual ~nsTableRowFrame(); |
|
35 |
|
36 virtual void Init(nsIContent* aContent, |
|
37 nsIFrame* aParent, |
|
38 nsIFrame* aPrevInFlow) MOZ_OVERRIDE; |
|
39 |
|
40 virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; |
|
41 |
|
42 /** @see nsIFrame::DidSetStyleContext */ |
|
43 virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE; |
|
44 |
|
45 virtual nsresult AppendFrames(ChildListID aListID, |
|
46 nsFrameList& aFrameList) MOZ_OVERRIDE; |
|
47 virtual nsresult InsertFrames(ChildListID aListID, |
|
48 nsIFrame* aPrevFrame, |
|
49 nsFrameList& aFrameList) MOZ_OVERRIDE; |
|
50 virtual nsresult RemoveFrame(ChildListID aListID, |
|
51 nsIFrame* aOldFrame) MOZ_OVERRIDE; |
|
52 |
|
53 /** instantiate a new instance of nsTableRowFrame. |
|
54 * @param aPresShell the pres shell for this frame |
|
55 * |
|
56 * @return the frame that was created |
|
57 */ |
|
58 friend nsIFrame* NS_NewTableRowFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); |
|
59 |
|
60 virtual nsMargin GetUsedMargin() const MOZ_OVERRIDE; |
|
61 virtual nsMargin GetUsedBorder() const MOZ_OVERRIDE; |
|
62 virtual nsMargin GetUsedPadding() const MOZ_OVERRIDE; |
|
63 |
|
64 virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, |
|
65 const nsRect& aDirtyRect, |
|
66 const nsDisplayListSet& aLists) MOZ_OVERRIDE; |
|
67 |
|
68 nsTableCellFrame* GetFirstCell() ; |
|
69 |
|
70 /** calls Reflow for all of its child cells. |
|
71 * Cells with rowspan=1 are all set to the same height and stacked horizontally. |
|
72 * <P> Cells are not split unless absolutely necessary. |
|
73 * <P> Cells are resized in nsTableFrame::BalanceColumnWidths |
|
74 * and nsTableFrame::ShrinkWrapChildren |
|
75 * |
|
76 * @param aDesiredSize width set to width of the sum of the cells, height set to |
|
77 * height of cells with rowspan=1. |
|
78 * |
|
79 * @see nsIFrame::Reflow |
|
80 * @see nsTableFrame::BalanceColumnWidths |
|
81 * @see nsTableFrame::ShrinkWrapChildren |
|
82 */ |
|
83 virtual nsresult Reflow(nsPresContext* aPresContext, |
|
84 nsHTMLReflowMetrics& aDesiredSize, |
|
85 const nsHTMLReflowState& aReflowState, |
|
86 nsReflowStatus& aStatus) MOZ_OVERRIDE; |
|
87 |
|
88 void DidResize(); |
|
89 |
|
90 /** |
|
91 * Get the "type" of the frame |
|
92 * |
|
93 * @see nsGkAtoms::tableRowFrame |
|
94 */ |
|
95 virtual nsIAtom* GetType() const MOZ_OVERRIDE; |
|
96 |
|
97 #ifdef DEBUG_FRAME_DUMP |
|
98 virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; |
|
99 #endif |
|
100 |
|
101 void UpdateHeight(nscoord aHeight, |
|
102 nscoord aAscent, |
|
103 nscoord aDescent, |
|
104 nsTableFrame* aTableFrame = nullptr, |
|
105 nsTableCellFrame* aCellFrame = nullptr); |
|
106 |
|
107 void ResetHeight(nscoord aRowStyleHeight); |
|
108 |
|
109 // calculate the height, considering content height of the |
|
110 // cells and the style height of the row and cells, excluding pct heights |
|
111 nscoord CalcHeight(const nsHTMLReflowState& aReflowState); |
|
112 |
|
113 // Support for cells with 'vertical-align: baseline'. |
|
114 |
|
115 /** |
|
116 * returns the max-ascent amongst all the cells that have |
|
117 * 'vertical-align: baseline', *including* cells with rowspans. |
|
118 * returns 0 if we don't have any cell with 'vertical-align: baseline' |
|
119 */ |
|
120 nscoord GetMaxCellAscent() const; |
|
121 |
|
122 /* return the row ascent |
|
123 */ |
|
124 nscoord GetRowBaseline(); |
|
125 |
|
126 /** returns the ordinal position of this row in its table */ |
|
127 virtual int32_t GetRowIndex() const; |
|
128 |
|
129 /** set this row's starting row index */ |
|
130 void SetRowIndex (int aRowIndex); |
|
131 |
|
132 /** used by row group frame code */ |
|
133 nscoord ReflowCellFrame(nsPresContext* aPresContext, |
|
134 const nsHTMLReflowState& aReflowState, |
|
135 bool aIsTopOfPage, |
|
136 nsTableCellFrame* aCellFrame, |
|
137 nscoord aAvailableHeight, |
|
138 nsReflowStatus& aStatus); |
|
139 /** |
|
140 * Collapse the row if required, apply col and colgroup visibility: collapse |
|
141 * info to the cells in the row. |
|
142 * @return he amount to shift up all following rows |
|
143 * @param aRowOffset - shift the row up by this amount |
|
144 * @param aWidth - new width of the row |
|
145 * @param aCollapseGroup - parent rowgroup is collapsed so this row needs |
|
146 * to be collapsed |
|
147 * @param aDidCollapse - the row has been collapsed |
|
148 */ |
|
149 nscoord CollapseRowIfNecessary(nscoord aRowOffset, |
|
150 nscoord aWidth, |
|
151 bool aCollapseGroup, |
|
152 bool& aDidCollapse); |
|
153 |
|
154 /** |
|
155 * Insert a cell frame after the last cell frame that has a col index |
|
156 * that is less than aColIndex. If no such cell frame is found the |
|
157 * frame to insert is prepended to the child list. |
|
158 * @param aFrame the cell frame to insert |
|
159 * @param aColIndex the col index |
|
160 */ |
|
161 void InsertCellFrame(nsTableCellFrame* aFrame, |
|
162 int32_t aColIndex); |
|
163 |
|
164 nsresult CalculateCellActualHeight(nsTableCellFrame* aCellFrame, |
|
165 nscoord& aDesiredHeight); |
|
166 |
|
167 bool IsFirstInserted() const; |
|
168 void SetFirstInserted(bool aValue); |
|
169 |
|
170 nscoord GetContentHeight() const; |
|
171 void SetContentHeight(nscoord aTwipValue); |
|
172 |
|
173 bool HasStyleHeight() const; |
|
174 |
|
175 bool HasFixedHeight() const; |
|
176 void SetHasFixedHeight(bool aValue); |
|
177 |
|
178 bool HasPctHeight() const; |
|
179 void SetHasPctHeight(bool aValue); |
|
180 |
|
181 nscoord GetFixedHeight() const; |
|
182 void SetFixedHeight(nscoord aValue); |
|
183 |
|
184 float GetPctHeight() const; |
|
185 void SetPctHeight(float aPctValue, |
|
186 bool aForce = false); |
|
187 |
|
188 nscoord GetHeight(nscoord aBasis = 0) const; |
|
189 |
|
190 nsTableRowFrame* GetNextRow() const; |
|
191 |
|
192 bool HasUnpaginatedHeight(); |
|
193 void SetHasUnpaginatedHeight(bool aValue); |
|
194 nscoord GetUnpaginatedHeight(nsPresContext* aPresContext); |
|
195 void SetUnpaginatedHeight(nsPresContext* aPresContext, nscoord aValue); |
|
196 |
|
197 nscoord GetTopBCBorderWidth(); |
|
198 void SetTopBCBorderWidth(BCPixelSize aWidth); |
|
199 nscoord GetBottomBCBorderWidth(); |
|
200 void SetBottomBCBorderWidth(BCPixelSize aWidth); |
|
201 nsMargin* GetBCBorderWidth(nsMargin& aBorder); |
|
202 |
|
203 /** |
|
204 * Gets inner border widths before collapsing with cell borders |
|
205 * Caller must get bottom border from next row or from table |
|
206 * GetContinuousBCBorderWidth will not overwrite aBorder.bottom |
|
207 * see nsTablePainter about continuous borders |
|
208 */ |
|
209 void GetContinuousBCBorderWidth(nsMargin& aBorder); |
|
210 /** |
|
211 * @returns outer top bc border == prev row's bottom inner |
|
212 */ |
|
213 nscoord GetOuterTopContBCBorderWidth(); |
|
214 /** |
|
215 * Sets full border widths before collapsing with cell borders |
|
216 * @param aForSide - side to set; only accepts right, left, and top |
|
217 */ |
|
218 void SetContinuousBCBorderWidth(uint8_t aForSide, |
|
219 BCPixelSize aPixelValue); |
|
220 |
|
221 virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE |
|
222 { |
|
223 return nsContainerFrame::IsFrameOfType(aFlags & ~(nsIFrame::eTablePart)); |
|
224 } |
|
225 |
|
226 virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0) MOZ_OVERRIDE; |
|
227 virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0) MOZ_OVERRIDE; |
|
228 virtual void InvalidateFrameForRemoval() MOZ_OVERRIDE { InvalidateFrameSubtree(); } |
|
229 |
|
230 #ifdef ACCESSIBILITY |
|
231 virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE; |
|
232 #endif |
|
233 |
|
234 protected: |
|
235 |
|
236 /** protected constructor. |
|
237 * @see NewFrame |
|
238 */ |
|
239 nsTableRowFrame(nsStyleContext *aContext); |
|
240 |
|
241 void InitChildReflowState(nsPresContext& aPresContext, |
|
242 const nsSize& aAvailSize, |
|
243 bool aBorderCollapse, |
|
244 nsTableCellReflowState& aReflowState); |
|
245 |
|
246 virtual int GetLogicalSkipSides(const nsHTMLReflowState* aReflowState = nullptr) const MOZ_OVERRIDE; |
|
247 |
|
248 // row-specific methods |
|
249 |
|
250 nscoord ComputeCellXOffset(const nsHTMLReflowState& aState, |
|
251 nsIFrame* aKidFrame, |
|
252 const nsMargin& aKidMargin) const; |
|
253 /** |
|
254 * Called for incremental/dirty and resize reflows. If aDirtyOnly is true then |
|
255 * only reflow dirty cells. |
|
256 */ |
|
257 nsresult ReflowChildren(nsPresContext* aPresContext, |
|
258 nsHTMLReflowMetrics& aDesiredSize, |
|
259 const nsHTMLReflowState& aReflowState, |
|
260 nsTableFrame& aTableFrame, |
|
261 nsReflowStatus& aStatus); |
|
262 |
|
263 private: |
|
264 struct RowBits { |
|
265 unsigned mRowIndex:29; |
|
266 unsigned mHasFixedHeight:1; // set if the dominating style height on the row or any cell is pixel based |
|
267 unsigned mHasPctHeight:1; // set if the dominating style height on the row or any cell is pct based |
|
268 unsigned mFirstInserted:1; // if true, then it was the top most newly inserted row |
|
269 } mBits; |
|
270 |
|
271 // the desired height based on the content of the tallest cell in the row |
|
272 nscoord mContentHeight; |
|
273 // the height based on a style percentage height on either the row or any cell |
|
274 // if mHasPctHeight is set |
|
275 nscoord mStylePctHeight; |
|
276 // the height based on a style pixel height on the row or any |
|
277 // cell if mHasFixedHeight is set |
|
278 nscoord mStyleFixedHeight; |
|
279 |
|
280 // max-ascent and max-descent amongst all cells that have 'vertical-align: baseline' |
|
281 nscoord mMaxCellAscent; // does include cells with rowspan > 1 |
|
282 nscoord mMaxCellDescent; // does *not* include cells with rowspan > 1 |
|
283 |
|
284 // border widths in pixels in the collapsing border model of the *inner* |
|
285 // half of the border only |
|
286 BCPixelSize mTopBorderWidth; |
|
287 BCPixelSize mBottomBorderWidth; |
|
288 BCPixelSize mRightContBorderWidth; |
|
289 BCPixelSize mTopContBorderWidth; |
|
290 BCPixelSize mLeftContBorderWidth; |
|
291 |
|
292 /** |
|
293 * Sets the NS_ROW_HAS_CELL_WITH_STYLE_HEIGHT bit to indicate whether |
|
294 * this row has any cells that have non-auto-height. (Row-spanning |
|
295 * cells are ignored.) |
|
296 */ |
|
297 void InitHasCellWithStyleHeight(nsTableFrame* aTableFrame); |
|
298 |
|
299 }; |
|
300 |
|
301 inline int32_t nsTableRowFrame::GetRowIndex() const |
|
302 { |
|
303 return int32_t(mBits.mRowIndex); |
|
304 } |
|
305 |
|
306 inline void nsTableRowFrame::SetRowIndex (int aRowIndex) |
|
307 { |
|
308 mBits.mRowIndex = aRowIndex; |
|
309 } |
|
310 |
|
311 inline bool nsTableRowFrame::IsFirstInserted() const |
|
312 { |
|
313 return bool(mBits.mFirstInserted); |
|
314 } |
|
315 |
|
316 inline void nsTableRowFrame::SetFirstInserted(bool aValue) |
|
317 { |
|
318 mBits.mFirstInserted = aValue; |
|
319 } |
|
320 |
|
321 inline bool nsTableRowFrame::HasStyleHeight() const |
|
322 { |
|
323 return (bool)mBits.mHasFixedHeight || (bool)mBits.mHasPctHeight; |
|
324 } |
|
325 |
|
326 inline bool nsTableRowFrame::HasFixedHeight() const |
|
327 { |
|
328 return (bool)mBits.mHasFixedHeight; |
|
329 } |
|
330 |
|
331 inline void nsTableRowFrame::SetHasFixedHeight(bool aValue) |
|
332 { |
|
333 mBits.mHasFixedHeight = aValue; |
|
334 } |
|
335 |
|
336 inline bool nsTableRowFrame::HasPctHeight() const |
|
337 { |
|
338 return (bool)mBits.mHasPctHeight; |
|
339 } |
|
340 |
|
341 inline void nsTableRowFrame::SetHasPctHeight(bool aValue) |
|
342 { |
|
343 mBits.mHasPctHeight = aValue; |
|
344 } |
|
345 |
|
346 inline nscoord nsTableRowFrame::GetContentHeight() const |
|
347 { |
|
348 return mContentHeight; |
|
349 } |
|
350 |
|
351 inline void nsTableRowFrame::SetContentHeight(nscoord aValue) |
|
352 { |
|
353 mContentHeight = aValue; |
|
354 } |
|
355 |
|
356 inline nscoord nsTableRowFrame::GetFixedHeight() const |
|
357 { |
|
358 if (mBits.mHasFixedHeight) |
|
359 return mStyleFixedHeight; |
|
360 else |
|
361 return 0; |
|
362 } |
|
363 |
|
364 inline float nsTableRowFrame::GetPctHeight() const |
|
365 { |
|
366 if (mBits.mHasPctHeight) |
|
367 return (float)mStylePctHeight / 100.0f; |
|
368 else |
|
369 return 0.0f; |
|
370 } |
|
371 |
|
372 inline bool nsTableRowFrame::HasUnpaginatedHeight() |
|
373 { |
|
374 return (mState & NS_TABLE_ROW_HAS_UNPAGINATED_HEIGHT) == |
|
375 NS_TABLE_ROW_HAS_UNPAGINATED_HEIGHT; |
|
376 } |
|
377 |
|
378 inline void nsTableRowFrame::SetHasUnpaginatedHeight(bool aValue) |
|
379 { |
|
380 if (aValue) { |
|
381 mState |= NS_TABLE_ROW_HAS_UNPAGINATED_HEIGHT; |
|
382 } else { |
|
383 mState &= ~NS_TABLE_ROW_HAS_UNPAGINATED_HEIGHT; |
|
384 } |
|
385 } |
|
386 |
|
387 inline nscoord nsTableRowFrame::GetTopBCBorderWidth() |
|
388 { |
|
389 return mTopBorderWidth; |
|
390 } |
|
391 |
|
392 inline void nsTableRowFrame::SetTopBCBorderWidth(BCPixelSize aWidth) |
|
393 { |
|
394 mTopBorderWidth = aWidth; |
|
395 } |
|
396 |
|
397 inline nscoord nsTableRowFrame::GetBottomBCBorderWidth() |
|
398 { |
|
399 return mBottomBorderWidth; |
|
400 } |
|
401 |
|
402 inline void nsTableRowFrame::SetBottomBCBorderWidth(BCPixelSize aWidth) |
|
403 { |
|
404 mBottomBorderWidth = aWidth; |
|
405 } |
|
406 |
|
407 inline nsMargin* nsTableRowFrame::GetBCBorderWidth(nsMargin& aBorder) |
|
408 { |
|
409 aBorder.left = aBorder.right = 0; |
|
410 |
|
411 aBorder.top = nsPresContext::CSSPixelsToAppUnits(mTopBorderWidth); |
|
412 aBorder.bottom = nsPresContext::CSSPixelsToAppUnits(mBottomBorderWidth); |
|
413 |
|
414 return &aBorder; |
|
415 } |
|
416 |
|
417 inline void |
|
418 nsTableRowFrame::GetContinuousBCBorderWidth(nsMargin& aBorder) |
|
419 { |
|
420 int32_t aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel(); |
|
421 aBorder.right = BC_BORDER_LEFT_HALF_COORD(aPixelsToTwips, |
|
422 mLeftContBorderWidth); |
|
423 aBorder.top = BC_BORDER_BOTTOM_HALF_COORD(aPixelsToTwips, |
|
424 mTopContBorderWidth); |
|
425 aBorder.left = BC_BORDER_RIGHT_HALF_COORD(aPixelsToTwips, |
|
426 mRightContBorderWidth); |
|
427 } |
|
428 |
|
429 inline nscoord nsTableRowFrame::GetOuterTopContBCBorderWidth() |
|
430 { |
|
431 int32_t aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel(); |
|
432 return BC_BORDER_TOP_HALF_COORD(aPixelsToTwips, mTopContBorderWidth); |
|
433 } |
|
434 |
|
435 #endif |