tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsTableRowFrame.h (13989B)


      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/WritingModes.h"
      9 #include "nsContainerFrame.h"
     10 #include "nsTableRowGroupFrame.h"
     11 #include "nscore.h"
     12 
     13 class nsTableCellFrame;
     14 namespace mozilla {
     15 class PresShell;
     16 struct TableCellReflowInput;
     17 
     18 // Yes if table-cells should use 'vertical-align:top' in
     19 // nsTableCellFrame::BlockDirAlignChild(). This is a hack to workaround our
     20 // current table row group fragmentation to avoid data loss.
     21 enum class ForceAlignTopForTableCell : uint8_t { No, Yes };
     22 }  // namespace mozilla
     23 
     24 /**
     25 * nsTableRowFrame is the frame that maps table rows
     26 * (HTML tag TR). This class cannot be reused
     27 * outside of an nsTableRowGroupFrame.  It assumes that its parent is an
     28 * nsTableRowGroupFrame, and its children are nsTableCellFrames.
     29 *
     30 * @see nsTableFrame
     31 * @see nsTableRowGroupFrame
     32 * @see nsTableCellFrame
     33 */
     34 class nsTableRowFrame : public nsContainerFrame {
     35  using TableCellReflowInput = mozilla::TableCellReflowInput;
     36 
     37 public:
     38  NS_DECL_QUERYFRAME
     39  NS_DECL_FRAMEARENA_HELPERS(nsTableRowFrame)
     40 
     41  virtual ~nsTableRowFrame();
     42 
     43  void Init(nsIContent* aContent, nsContainerFrame* aParent,
     44            nsIFrame* aPrevInFlow) override;
     45 
     46  void Destroy(DestroyContext&) override;
     47 
     48  void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) override;
     49 
     50  void AppendFrames(ChildListID aListID, nsFrameList&& aFrameList) override;
     51  void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
     52                    const nsLineList::iterator* aPrevFrameLine,
     53                    nsFrameList&& aFrameList) override;
     54  void RemoveFrame(DestroyContext&, ChildListID, nsIFrame*) override;
     55 
     56  /** instantiate a new instance of nsTableRowFrame.
     57   * @param aPresShell the pres shell for this frame
     58   *
     59   * @return           the frame that was created
     60   */
     61  friend nsTableRowFrame* NS_NewTableRowFrame(mozilla::PresShell* aPresShell,
     62                                              ComputedStyle* aStyle);
     63 
     64  nsTableRowGroupFrame* GetTableRowGroupFrame() const {
     65    nsIFrame* parent = GetParent();
     66    MOZ_ASSERT(parent && parent->IsTableRowGroupFrame());
     67    return static_cast<nsTableRowGroupFrame*>(parent);
     68  }
     69 
     70  nsTableFrame* GetTableFrame() const {
     71    return GetTableRowGroupFrame()->GetTableFrame();
     72  }
     73 
     74  nsMargin GetUsedMargin() const override;
     75  nsMargin GetUsedBorder() const override;
     76  nsMargin GetUsedPadding() const override;
     77 
     78  void BuildDisplayList(nsDisplayListBuilder* aBuilder,
     79                        const nsDisplayListSet& aLists) override;
     80 
     81  void PaintCellBackgroundsForFrame(nsIFrame* aFrame,
     82                                    nsDisplayListBuilder* aBuilder,
     83                                    const nsDisplayListSet& aLists,
     84                                    const nsPoint& aOffset = nsPoint());
     85 
     86  // Implemented in nsTableCellFrame.h, because it needs to know about the
     87  // nsTableCellFrame class, but we can't include nsTableCellFrame.h here.
     88  inline nsTableCellFrame* GetFirstCell() const;
     89 
     90  /** calls Reflow for all of its child cells.
     91   *
     92   * Cells with rowspan=1 are all set to the same height and stacked
     93   * horizontally.
     94   *
     95   * Cells are not split unless absolutely necessary.
     96   *
     97   * Cells are resized in nsTableFrame::BalanceColumnWidths and
     98   * nsTableFrame::ShrinkWrapChildren
     99   *
    100   * @param aDesiredSize width set to width of the sum of the cells,
    101   *                     height set to height of cells with rowspan=1.
    102   *
    103   * @see nsIFrame::Reflow
    104   * @see nsTableFrame::BalanceColumnWidths
    105   * @see nsTableFrame::ShrinkWrapChildren
    106   */
    107  void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
    108              const ReflowInput& aReflowInput,
    109              nsReflowStatus& aStatus) override;
    110 
    111  void DidResize(mozilla::ForceAlignTopForTableCell aForceAlignTop =
    112                     mozilla::ForceAlignTopForTableCell::No);
    113 
    114 #ifdef DEBUG_FRAME_DUMP
    115  nsresult GetFrameName(nsAString& aResult) const override;
    116 #endif
    117 
    118  void UpdateBSize(nscoord aBSize, nsTableFrame* aTableFrame,
    119                   nsTableCellFrame* aCellFrame);
    120 
    121  void ResetBSize();
    122 
    123  // calculate the bsize, considering content bsize of the
    124  // cells and the style bsize of the row and cells, excluding pct bsizes
    125  nscoord CalcBSize(const ReflowInput& aReflowInput);
    126 
    127  // Support for cells with 'vertical-align: baseline'.
    128 
    129  /**
    130   * returns the max-ascent amongst all the cells that have
    131   * 'vertical-align: baseline', *including* cells with rowspans.
    132   * returns 0 if we don't have any cell with 'vertical-align: baseline'
    133   */
    134  nscoord GetMaxCellAscent() const;
    135 
    136  /* return the row ascent
    137   */
    138  Maybe<nscoord> GetRowBaseline(mozilla::WritingMode aWM);
    139 
    140  /** returns the ordinal position of this row in its table */
    141  virtual int32_t GetRowIndex() const;
    142 
    143  /** set this row's starting row index */
    144  void SetRowIndex(int aRowIndex);
    145 
    146  // See nsTableFrame.h
    147  int32_t GetAdjustmentForStoredIndex(int32_t aStoredIndex) const;
    148 
    149  // See nsTableFrame.h
    150  void AddDeletedRowIndex();
    151 
    152  /**
    153   * This function is called by the row group frame's SplitRowGroup() code when
    154   * pushing a row frame that has cell frames that span into it. The cell frame
    155   * should be reflowed with the specified available block-size.
    156   */
    157  nscoord ReflowCellFrame(nsPresContext* aPresContext,
    158                          const ReflowInput& aReflowInput, bool aIsTopOfPage,
    159                          nsTableCellFrame* aCellFrame, nscoord aAvailableBSize,
    160                          nsReflowStatus& aStatus);
    161  /**
    162   * Collapse the row if required, apply col and colgroup visibility: collapse
    163   * info to the cells in the row.
    164   * @return the amount to shift bstart-wards all following rows
    165   * @param aRowOffset     - shift the row bstart-wards by this amount
    166   * @param aISize         - new isize of the row
    167   * @param aCollapseGroup - parent rowgroup is collapsed so this row needs
    168   *                         to be collapsed
    169   * @param aDidCollapse   - the row has been collapsed
    170   */
    171  nscoord CollapseRowIfNecessary(nscoord aRowOffset, nscoord aISize,
    172                                 bool aCollapseGroup, bool& aDidCollapse);
    173 
    174  /**
    175   * Insert a cell frame after the last cell frame that has a col index
    176   * that is less than aColIndex.  If no such cell frame is found the
    177   * frame to insert is prepended to the child list.
    178   * @param aFrame the cell frame to insert
    179   * @param aColIndex the col index
    180   */
    181  void InsertCellFrame(nsTableCellFrame* aFrame, int32_t aColIndex);
    182 
    183  /**
    184   * Calculate the cell frame's actual block-size given its desired block-size
    185   * (the border-box block-size in the last reflow). This method takes into
    186   * account the specified bsize (in the style).
    187   *
    188   * @return the specified block-size if it is larger than the desired
    189   *         block-size. Otherwise, the desired block-size.
    190   */
    191  nscoord CalcCellActualBSize(nsTableCellFrame* aCellFrame,
    192                              const nscoord& aDesiredBSize,
    193                              mozilla::WritingMode aWM);
    194 
    195  bool IsFirstInserted() const;
    196  void SetFirstInserted(bool aValue);
    197 
    198  nscoord GetContentBSize() const;
    199  void SetContentBSize(nscoord aTwipValue);
    200 
    201  bool HasStyleBSize() const;
    202 
    203  bool HasFixedBSize() const;
    204  void SetHasFixedBSize(bool aValue);
    205 
    206  bool HasPctBSize() const;
    207  void SetHasPctBSize(bool aValue);
    208 
    209  nscoord GetFixedBSize() const;
    210  void SetFixedBSize(nscoord aValue);
    211 
    212  float GetPctBSize() const;
    213  void SetPctBSize(float aPctValue, bool aForce = false);
    214 
    215  nscoord GetInitialBSize(nscoord aBasis = 0) const;
    216 
    217  nsTableRowFrame* GetPrevRow() const;
    218  nsTableRowFrame* GetNextRow() const;
    219 
    220  bool HasUnpaginatedBSize() const {
    221    return HasAnyStateBits(NS_TABLE_ROW_HAS_UNPAGINATED_BSIZE);
    222  }
    223  nscoord GetUnpaginatedBSize() const;
    224  void SetUnpaginatedBSize(nscoord aValue);
    225 
    226  nscoord GetBStartBCBorderWidth() const { return mBStartBorderWidth; }
    227  nscoord GetBEndBCBorderWidth() const { return mBEndBorderWidth; }
    228  void SetBStartBCBorderWidth(nscoord aWidth) { mBStartBorderWidth = aWidth; }
    229  void SetBEndBCBorderWidth(nscoord aWidth) { mBEndBorderWidth = aWidth; }
    230  mozilla::LogicalMargin GetBCBorderWidth(mozilla::WritingMode aWM);
    231 
    232  void InvalidateFrame(uint32_t aDisplayItemKey = 0,
    233                       bool aRebuildDisplayItems = true) override;
    234  void InvalidateFrameWithRect(const nsRect& aRect,
    235                               uint32_t aDisplayItemKey = 0,
    236                               bool aRebuildDisplayItems = true) override;
    237  void InvalidateFrameForRemoval() override { InvalidateFrameSubtree(); }
    238 
    239 #ifdef ACCESSIBILITY
    240  mozilla::a11y::AccType AccessibleType() override;
    241 #endif
    242 
    243 protected:
    244  /** protected constructor.
    245   * @see NewFrame
    246   */
    247  explicit nsTableRowFrame(ComputedStyle* aStyle, nsPresContext* aPresContext,
    248                           ClassID aID = kClassID);
    249 
    250  void InitChildReflowInput(nsPresContext& aPresContext,
    251                            const mozilla::LogicalSize& aAvailSize,
    252                            bool aBorderCollapse,
    253                            TableCellReflowInput& aReflowInput);
    254 
    255  LogicalSides GetLogicalSkipSides() const override;
    256 
    257  // row-specific methods
    258 
    259  nscoord ComputeCellXOffset(const ReflowInput& aState, nsIFrame* aKidFrame,
    260                             const nsMargin& aKidMargin) const;
    261  /**
    262   * Called for incremental/dirty and resize reflows. If aDirtyOnly is true then
    263   * only reflow dirty cells.
    264   */
    265  void ReflowChildren(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
    266                      const ReflowInput& aReflowInput,
    267                      nsTableFrame& aTableFrame, nsReflowStatus& aStatus);
    268 
    269 private:
    270  struct RowBits {
    271    unsigned mRowIndex : 29;
    272    unsigned mHasFixedBSize : 1;  // set if the dominating style bsize on the
    273                                  // row or any cell is pixel based
    274    unsigned mHasPctBSize : 1;  // set if the dominating style bsize on the row
    275                                // or any cell is pct based
    276    unsigned mFirstInserted : 1;  // if true, then it was the bstart-most newly
    277                                  // inserted row
    278  } mBits;
    279 
    280  // the desired bsize based on the content of the tallest cell in the row
    281  nscoord mContentBSize = 0;
    282  // the bsize based on a style percentage bsize on either the row or any cell
    283  // if mHasPctBSize is set
    284  nscoord mStylePctBSize = 0;
    285  // the bsize based on a style pixel bsize on the row or any
    286  // cell if mHasFixedBSize is set
    287  nscoord mStyleFixedBSize = 0;
    288 
    289  // max-ascent and max-descent amongst all cells that have
    290  // 'vertical-align: baseline'
    291  nscoord mMaxCellAscent = 0;   // does include cells with rowspan > 1
    292  nscoord mMaxCellDescent = 0;  // does *not* include cells with rowspan > 1
    293 
    294  // border widths in the collapsing border model of the *inner*
    295  // half of the border only
    296  nscoord mBStartBorderWidth = 0;
    297  nscoord mBEndBorderWidth = 0;
    298  nscoord mIEndContBorderWidth = 0;
    299  nscoord mBStartContBorderWidth = 0;
    300  nscoord mIStartContBorderWidth = 0;
    301 
    302  /**
    303   * Sets the NS_ROW_HAS_CELL_WITH_STYLE_BSIZE bit to indicate whether
    304   * this row has any cells that have non-auto-bsize.  (Row-spanning
    305   * cells are ignored.)
    306   */
    307  void InitHasCellWithStyleBSize(nsTableFrame* aTableFrame);
    308 };
    309 
    310 inline int32_t nsTableRowFrame::GetAdjustmentForStoredIndex(
    311    int32_t aStoredIndex) const {
    312  nsTableRowGroupFrame* parentFrame = GetTableRowGroupFrame();
    313  return parentFrame->GetAdjustmentForStoredIndex(aStoredIndex);
    314 }
    315 
    316 inline void nsTableRowFrame::AddDeletedRowIndex() {
    317  nsTableRowGroupFrame* parentFrame = GetTableRowGroupFrame();
    318  parentFrame->AddDeletedRowIndex(int32_t(mBits.mRowIndex));
    319 }
    320 
    321 inline int32_t nsTableRowFrame::GetRowIndex() const {
    322  int32_t storedRowIndex = int32_t(mBits.mRowIndex);
    323  int32_t rowIndexAdjustment = GetAdjustmentForStoredIndex(storedRowIndex);
    324  return (storedRowIndex - rowIndexAdjustment);
    325 }
    326 
    327 inline void nsTableRowFrame::SetRowIndex(int aRowIndex) {
    328  // Note: Setting the index of a row (as in the case of adding new rows) should
    329  // be preceded by a call to nsTableFrame::RecalculateRowIndices()
    330  // so as to correctly clear mDeletedRowIndexRanges.
    331  MOZ_ASSERT(
    332      GetTableRowGroupFrame()->GetTableFrame()->IsDeletedRowIndexRangesEmpty(),
    333      "mDeletedRowIndexRanges should be empty here!");
    334  mBits.mRowIndex = aRowIndex;
    335 }
    336 
    337 inline bool nsTableRowFrame::IsFirstInserted() const {
    338  return bool(mBits.mFirstInserted);
    339 }
    340 
    341 inline void nsTableRowFrame::SetFirstInserted(bool aValue) {
    342  mBits.mFirstInserted = aValue;
    343 }
    344 
    345 inline bool nsTableRowFrame::HasStyleBSize() const {
    346  return (bool)mBits.mHasFixedBSize || (bool)mBits.mHasPctBSize;
    347 }
    348 
    349 inline bool nsTableRowFrame::HasFixedBSize() const {
    350  return (bool)mBits.mHasFixedBSize;
    351 }
    352 
    353 inline void nsTableRowFrame::SetHasFixedBSize(bool aValue) {
    354  mBits.mHasFixedBSize = aValue;
    355 }
    356 
    357 inline bool nsTableRowFrame::HasPctBSize() const {
    358  return (bool)mBits.mHasPctBSize;
    359 }
    360 
    361 inline void nsTableRowFrame::SetHasPctBSize(bool aValue) {
    362  mBits.mHasPctBSize = aValue;
    363 }
    364 
    365 inline nscoord nsTableRowFrame::GetContentBSize() const {
    366  return mContentBSize;
    367 }
    368 
    369 inline void nsTableRowFrame::SetContentBSize(nscoord aValue) {
    370  mContentBSize = aValue;
    371 }
    372 
    373 inline nscoord nsTableRowFrame::GetFixedBSize() const {
    374  if (mBits.mHasFixedBSize) {
    375    return mStyleFixedBSize;
    376  }
    377  return 0;
    378 }
    379 
    380 inline float nsTableRowFrame::GetPctBSize() const {
    381  if (mBits.mHasPctBSize) {
    382    return (float)mStylePctBSize / 100.0f;
    383  }
    384  return 0.0f;
    385 }
    386 
    387 inline mozilla::LogicalMargin nsTableRowFrame::GetBCBorderWidth(
    388    mozilla::WritingMode aWM) {
    389  return mozilla::LogicalMargin(aWM, mBStartBorderWidth, 0, mBEndBorderWidth,
    390                                0);
    391 }
    392 
    393 #endif