nsTableWrapperFrame.h (10486B)
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 nsTableWrapperFrame_h__ 6 #define nsTableWrapperFrame_h__ 7 8 #include "LayoutConstants.h" 9 #include "mozilla/Maybe.h" 10 #include "nsCellMap.h" 11 #include "nsContainerFrame.h" 12 #include "nsTableFrame.h" 13 #include "nscore.h" 14 15 namespace mozilla { 16 class PresShell; 17 } // namespace mozilla 18 19 /** 20 * Primary frame for a table element, 21 * the nsTableWrapperFrame contains 0 or one caption frame, and a nsTableFrame 22 * pseudo-frame (referred to as the "inner frame'). 23 */ 24 class nsTableWrapperFrame : public nsContainerFrame { 25 public: 26 NS_DECL_QUERYFRAME 27 NS_DECL_FRAMEARENA_HELPERS(nsTableWrapperFrame) 28 29 /** instantiate a new instance of nsTableRowFrame. 30 * @param aPresShell the pres shell for this frame 31 * 32 * @return the frame that was created 33 */ 34 friend nsTableWrapperFrame* NS_NewTableWrapperFrame( 35 mozilla::PresShell* aPresShell, ComputedStyle* aStyle); 36 37 // nsIFrame overrides - see there for a description 38 39 void Destroy(DestroyContext&) override; 40 41 void AppendFrames(ChildListID aListID, nsFrameList&& aFrameList) override; 42 void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, 43 const nsLineList::iterator* aPrevFrameLine, 44 nsFrameList&& aFrameList) override; 45 void RemoveFrame(DestroyContext&, ChildListID, nsIFrame*) override; 46 47 nsContainerFrame* GetContentInsertionFrame() override { 48 return PrincipalChildList().FirstChild()->GetContentInsertionFrame(); 49 } 50 51 #ifdef ACCESSIBILITY 52 mozilla::a11y::AccType AccessibleType() override; 53 #endif 54 55 void BuildDisplayList(nsDisplayListBuilder* aBuilder, 56 const nsDisplayListSet& aLists) override; 57 58 nscoord SynthesizeFallbackBaseline( 59 mozilla::WritingMode aWM, 60 BaselineSharingGroup aBaselineGroup) const override; 61 Maybe<nscoord> GetNaturalBaselineBOffset( 62 mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup, 63 BaselineExportContext aExportContext) const override; 64 65 nscoord IntrinsicISize(const mozilla::IntrinsicSizeInput& aInput, 66 mozilla::IntrinsicISizeType aType) override; 67 68 SizeComputationResult ComputeSize( 69 const SizeComputationInput& aSizingInput, mozilla::WritingMode aWM, 70 const mozilla::LogicalSize& aCBSize, nscoord aAvailableISize, 71 const mozilla::LogicalSize& aMargin, 72 const mozilla::LogicalSize& aBorderPadding, 73 const mozilla::StyleSizeOverrides& aSizeOverrides, 74 mozilla::ComputeSizeFlags aFlags) override; 75 76 mozilla::LogicalSize ComputeAutoSize( 77 const SizeComputationInput& aSizingInput, mozilla::WritingMode aWM, 78 const mozilla::LogicalSize& aCBSize, nscoord aAvailableISize, 79 const mozilla::LogicalSize& aMargin, 80 const mozilla::LogicalSize& aBorderPadding, 81 const mozilla::StyleSizeOverrides& aSizeOverrides, 82 mozilla::ComputeSizeFlags aFlags) override; 83 84 /** process a reflow command for the table. 85 * This involves reflowing the caption and the inner table. 86 * @see nsIFrame::Reflow */ 87 void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize, 88 const ReflowInput& aReflowInput, 89 nsReflowStatus& aStatus) override; 90 91 #ifdef DEBUG_FRAME_DUMP 92 nsresult GetFrameName(nsAString& aResult) const override; 93 #endif 94 95 ComputedStyle* GetParentComputedStyle( 96 nsIFrame** aProviderFrame) const override; 97 98 /** 99 * Return the content for the cell at the given row and column. 100 */ 101 nsIContent* GetCellAt(uint32_t aRowIdx, uint32_t aColIdx) const; 102 103 /** 104 * Return the number of rows in the table. 105 */ 106 int32_t GetRowCount() const { return InnerTableFrame()->GetRowCount(); } 107 108 /** 109 * Return the number of columns in the table. 110 */ 111 int32_t GetColCount() const { return InnerTableFrame()->GetColCount(); } 112 113 /** 114 * Return the index of the cell at the given row and column. 115 */ 116 int32_t GetIndexByRowAndColumn(int32_t aRowIdx, int32_t aColIdx) const { 117 nsTableCellMap* cellMap = InnerTableFrame()->GetCellMap(); 118 if (!cellMap) { 119 return -1; 120 } 121 122 return cellMap->GetIndexByRowAndColumn(aRowIdx, aColIdx); 123 } 124 125 /** 126 * Get the row and column indices for the cell at the given index. 127 */ 128 void GetRowAndColumnByIndex(int32_t aCellIdx, int32_t* aRowIdx, 129 int32_t* aColIdx) const { 130 *aRowIdx = *aColIdx = 0; 131 nsTableCellMap* cellMap = InnerTableFrame()->GetCellMap(); 132 if (cellMap) { 133 cellMap->GetRowAndColumnByIndex(aCellIdx, aRowIdx, aColIdx); 134 } 135 } 136 137 /** 138 * return the frame for the cell at the given row and column. 139 */ 140 nsTableCellFrame* GetCellFrameAt(uint32_t aRowIdx, uint32_t aColIdx) const { 141 nsTableCellMap* map = InnerTableFrame()->GetCellMap(); 142 if (!map) { 143 return nullptr; 144 } 145 146 return map->GetCellInfoAt(aRowIdx, aColIdx); 147 } 148 149 /** 150 * Return the col span of the cell at the given row and column indices. 151 */ 152 uint32_t GetEffectiveColSpanAt(uint32_t aRowIdx, uint32_t aColIdx) const { 153 nsTableCellMap* map = InnerTableFrame()->GetCellMap(); 154 return map->GetEffectiveColSpan(aRowIdx, aColIdx); 155 } 156 157 /** 158 * Return the effective row span of the cell at the given row and column. 159 */ 160 uint32_t GetEffectiveRowSpanAt(uint32_t aRowIdx, uint32_t aColIdx) const { 161 nsTableCellMap* map = InnerTableFrame()->GetCellMap(); 162 return map->GetEffectiveRowSpan(aRowIdx, aColIdx); 163 } 164 165 bool HasCaption() const { return !mFrames.OnlyChild(); } 166 nsIFrame* GetCaption() const { 167 return HasCaption() ? mFrames.FirstChild()->GetNextSibling() : nullptr; 168 } 169 170 // Always non-null unless we are mid-destruction. 171 nsTableFrame* InnerTableFrame() const { 172 return static_cast<nsTableFrame*>(mFrames.FirstChild()); 173 } 174 175 protected: 176 nsTableWrapperFrame(ComputedStyle* aStyle, nsPresContext* aPresContext, 177 ClassID aID = kClassID); 178 virtual ~nsTableWrapperFrame(); 179 180 using MaybeCaptionSide = Maybe<mozilla::StyleCaptionSide>; 181 182 // Get a StyleCaptionSide value, or Nothing if no caption is present. 183 // 184 // (Remember that caption-side values are interpreted logically, despite 185 // having "physical" names.) 186 MaybeCaptionSide GetCaptionSide() const; 187 188 nscoord ComputeFinalBSize(const mozilla::LogicalSize& aInnerSize, 189 const mozilla::LogicalSize& aCaptionSize, 190 const mozilla::LogicalMargin& aCaptionMargin, 191 const mozilla::WritingMode aWM) const; 192 193 void GetCaptionOrigin(mozilla::StyleCaptionSide, 194 const mozilla::LogicalSize& aInnerSize, 195 const mozilla::LogicalSize& aCaptionSize, 196 mozilla::LogicalMargin& aCaptionMargin, 197 mozilla::LogicalPoint& aOrigin, 198 mozilla::WritingMode aWM) const; 199 200 void GetInnerOrigin(const MaybeCaptionSide&, 201 const mozilla::LogicalSize& aCaptionSize, 202 const mozilla::LogicalMargin& aCaptionMargin, 203 const mozilla::LogicalSize& aInnerSize, 204 mozilla::LogicalPoint& aOrigin, 205 mozilla::WritingMode aWM) const; 206 207 // This is a helper for CreateReflowInputForInnerTable() and 208 // ComputeAutoSize(). It computes whether we need shrink-wrap behavior for 209 // children. 210 // 211 // Note: We don't need to call this in CreateReflowInputForCaption() because 212 // when we reflow the captions, we want them to stretch their inline-sizes to 213 // be at least as wide as the inner table frame. 214 mozilla::ComputeSizeFlags CreateComputeSizeFlagsForChild() const; 215 216 // Create and init the child reflow input, using passed-in aChildRI, so that 217 // caller can use it after we return. 218 // 219 // @param aBSizeOccupiedByCaption the block size occupied by the caption 220 // within our content box. 221 void CreateReflowInputForInnerTable( 222 nsPresContext* aPresContext, nsTableFrame* aTableFrame, 223 const ReflowInput& aOuterRI, Maybe<ReflowInput>& aChildRI, 224 const nscoord aAvailISize, nscoord aBSizeOccupiedByCaption = 0) const; 225 void CreateReflowInputForCaption(nsPresContext* aPresContext, 226 nsIFrame* aCaptionFrame, 227 const ReflowInput& aOuterRI, 228 Maybe<ReflowInput>& aChildRI, 229 const nscoord aAvailISize) const; 230 231 // Reflow the child (caption or inner table frame). 232 void ReflowChild(nsPresContext* aPresContext, nsIFrame* aChildFrame, 233 const ReflowInput& aChildRI, ReflowOutput& aMetrics, 234 nsReflowStatus& aStatus); 235 236 // Set the overflow areas in our reflow metrics 237 void UpdateOverflowAreas(ReflowOutput& aMet); 238 239 /** 240 * Helper for ComputeAutoSize. 241 * Compute the margin-box inline size of the frame given the inputs. 242 * 243 * Note: CaptionShrinkWrapISize doesn't need StyleSizeOverrides parameter. 244 */ 245 mozilla::LogicalSize InnerTableShrinkWrapSize( 246 const SizeComputationInput& aSizingInput, nsTableFrame* aTableFrame, 247 mozilla::WritingMode aWM, const mozilla::LogicalSize& aCBSize, 248 nscoord aAvailableISize, 249 const mozilla::StyleSizeOverrides& aSizeOverrides, 250 mozilla::ComputeSizeFlags aFlag) const; 251 mozilla::LogicalSize CaptionShrinkWrapSize( 252 const SizeComputationInput& aSizingInput, nsIFrame* aCaptionFrame, 253 mozilla::WritingMode aWM, const mozilla::LogicalSize& aCBSize, 254 nscoord aAvailableISize, mozilla::ComputeSizeFlags aFlag) const; 255 256 /** 257 * Create a new StyleSize by reducing the size by aAmountToReduce. 258 * 259 * @param aStyleSize must be a Length. 260 */ 261 mozilla::StyleSize ReduceStyleSizeBy(const mozilla::StyleSize& aStyleSize, 262 const nscoord aAmountToReduce) const; 263 264 /** 265 * Compute StyleSizeOverrides for inner table frame given the overrides of the 266 * table wrapper frame. 267 */ 268 mozilla::StyleSizeOverrides ComputeSizeOverridesForInnerTable( 269 const nsTableFrame* aTableFrame, 270 const mozilla::StyleSizeOverrides& aWrapperSizeOverrides, 271 const mozilla::LogicalSize& aBorderPadding, 272 nscoord aBSizeOccupiedByCaption) const; 273 }; 274 275 #endif