DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (56e7b9127e89)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsTableColGroupFrame_h__
#define nsTableColGroupFrame_h__

#include "mozilla/Attributes.h"
#include "nscore.h"
#include "nsContainerFrame.h"
#include "nsTableFrame.h"
#include "mozilla/WritingModes.h"

class nsTableColFrame;

/**
 * nsTableColGroupFrame
 * data structure to maintain information about a single table cell's frame
 */
class nsTableColGroupFrame final : public nsContainerFrame
{
public:
  NS_DECL_FRAMEARENA_HELPERS(nsTableColGroupFrame)

  /** instantiate a new instance of nsTableRowFrame.
    * @param aPresShell the pres shell for this frame
    *
    * @return           the frame that was created
    */
  friend nsTableColGroupFrame* NS_NewTableColGroupFrame(nsIPresShell* aPresShell,
                                                        ComputedStyle* aStyle);

  // nsIFrame overrides
  virtual void Init(nsIContent*       aContent,
                    nsContainerFrame* aParent,
                    nsIFrame*         aPrevInFlow) override
  {
    nsContainerFrame::Init(aContent, aParent, aPrevInFlow);
    if (!aPrevInFlow) {
      mWritingMode = GetTableFrame()->GetWritingMode();
    }
  }

  nsTableFrame* GetTableFrame() const
  {
    nsIFrame* parent = GetParent();
    MOZ_ASSERT(parent && parent->IsTableFrame());
    MOZ_ASSERT(!parent->GetPrevInFlow(),
               "Col group should always be in a first-in-flow table frame");
    return static_cast<nsTableFrame*>(parent);
  }

  virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                const nsDisplayListSet& aLists) override;

  /** A colgroup can be caused by three things:
    * 1) An element with table-column-group display
    * 2) An element with a table-column display without a
    *    table-column-group parent
    * 3) Cells that are not in a column (and hence get an anonymous
    *    column and colgroup).
    *
    * In practice, we don't need to differentiate between cases (1) and (2),
    * because they both correspond to table-column-group boxes in the spec and
    * hence have observably identical behavior.  Case three is flagged as a
    * synthetic colgroup, because it may need to have different behavior in some
    * cases.
    */
  bool IsSynthetic() const;
  void SetIsSynthetic();

  /** Real in this context are colgroups that come from an element
    * with table-column-group display or wrap around columns that
    * come from an element with table-column display. Colgroups
    * that are the result of wrapping cells in an anonymous
    * column and colgroup are not considered real here.
    * @param aTableFrame - the table parent of the colgroups
    * @return the last real colgroup
    */
  static nsTableColGroupFrame* GetLastRealColGroup(nsTableFrame* aTableFrame);

  /** @see nsIFrame::DidSetComputedStyle */
  virtual void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) override;

  virtual void SetInitialChildList(ChildListID     aListID,
                                   nsFrameList&    aChildList) override;
  virtual void AppendFrames(ChildListID     aListID,
                            nsFrameList&    aFrameList) override;
  virtual void InsertFrames(ChildListID     aListID,
                            nsIFrame*       aPrevFrame,
                            nsFrameList&    aFrameList) override;
  virtual void RemoveFrame(ChildListID     aListID,
                           nsIFrame*       aOldFrame) override;

  /** remove the column aChild from the column group, if requested renumber
    * the subsequent columns in this column group and all following column
    * groups. see also ResetColIndices for this
    * @param aChild       - the column frame that needs to be removed
    * @param aResetSubsequentColIndices - if true the columns that follow
    *                                     after aChild will be reenumerated
    */
  void RemoveChild(nsTableColFrame& aChild,
                   bool             aResetSubsequentColIndices);

  /** reflow of a column group is a trivial matter of reflowing
    * the col group's children (columns), and setting this frame
    * to 0-size.  Since tables are row-centric, column group frames
    * don't play directly in the rendering game.  They do however
    * maintain important state that effects table and cell layout.
    */
  virtual void Reflow(nsPresContext* aPresContext,
                      ReflowOutput& aDesiredSize,
                      const ReflowInput& aReflowInput,
                      nsReflowStatus& aStatus) override;

  /** Add column frames to the table storages: colframe cache and cellmap
    * this doesn't change the mFrames of the colgroup frame.
    * @param aFirstColIndex - the index at which aFirstFrame should be inserted
    *                         into the colframe cache.
    * @param aResetSubsequentColIndices - the indices of the col frames
    *                                     after the insertion might need
    *                                     an update
    * @param aCols - an iterator that can be used to iterate over the col
    *                frames to be added.  Once this is done, the frames on the
    *                sbling chain of its .get() at that point will still need
    *                their col indices updated.
    * @result            - if there is no table frame or the table frame is not
    *                      the first in flow it will return an error
    */
  nsresult AddColsToTable(int32_t                   aFirstColIndex,
                          bool                      aResetSubsequentColIndices,
                          const nsFrameList::Slice& aCols);

#ifdef DEBUG_FRAME_DUMP
  virtual nsresult GetFrameName(nsAString& aResult) const override;
  void Dump(int32_t aIndent);
#endif

  /** returns the number of columns represented by this group.
    * if there are col children, count them (taking into account the span of each)
    * else, check my own span attribute.
    */
  virtual int32_t GetColCount() const;

  /** first column on the child list */
  nsTableColFrame * GetFirstColumn();
  /** next sibling to aChildFrame that is a column frame, first column frame
    * in the column group if aChildFrame is null
    */
  nsTableColFrame * GetNextColumn(nsIFrame *aChildFrame);

  /** @return - the position of the first column in this colgroup in the table
    * colframe cache.
    */
  int32_t GetStartColumnIndex();

  /** set the position of the first column in this colgroup in the table
    * colframe cache.
    */
  void SetStartColumnIndex(int32_t aIndex);

  /** helper method to get the span attribute for this colgroup */
  int32_t GetSpan();

  /** provide access to the mFrames list
    */
  nsFrameList& GetWritableChildList();

  /** set the column index for all frames starting at aStartColFrame, it
    * will also reset the column indices in all subsequent colgroups
    * @param aFirstColGroup - start the reset operation inside this colgroup
    * @param aFirstColIndex - first column that is reset should get this index
    * @param aStartColFrame - if specified the reset starts with this column
    *                         inside the colgroup; if not specified, the reset
    *                         starts with the first column
    */
  static void ResetColIndices(nsIFrame*       aFirstColGroup,
                              int32_t         aFirstColIndex,
                              nsIFrame*       aStartColFrame = nullptr);

  /**
   * Gets inner border widths before collapsing with cell borders
   * Caller must get istart border from previous column
   * GetContinuousBCBorderWidth will not overwrite aBorder.IStart
   * see nsTablePainter about continuous borders
   */
  void GetContinuousBCBorderWidth(mozilla::WritingMode aWM,
                                  mozilla::LogicalMargin& aBorder);
  /**
   * Set full border widths before collapsing with cell borders
   * @param aForSide - side to set; only accepts bstart and bend
   */
  void SetContinuousBCBorderWidth(mozilla::LogicalSide aForSide,
                                  BCPixelSize aPixelValue);

  virtual bool IsFrameOfType(uint32_t aFlags) const override
  {
    if (aFlags & eSupportsContainLayoutAndPaint) {
      return false;
    }

    return nsContainerFrame::IsFrameOfType(aFlags & ~(nsIFrame::eTablePart));
  }

  virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0, bool aRebuildDisplayItems = true) override;
  virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0, bool aRebuildDisplayItems = true) override;
  virtual void InvalidateFrameForRemoval() override { InvalidateFrameSubtree(); }

protected:
  explicit nsTableColGroupFrame(ComputedStyle* aStyle);

  void InsertColsReflow(int32_t                   aColIndex,
                        const nsFrameList::Slice& aCols);

  virtual LogicalSides GetLogicalSkipSides(const ReflowInput* aReflowInput = nullptr) const override;

  // data members
  int32_t mColCount;
  // the starting column index this col group represents. Must be >= 0.
  int32_t mStartColIndex;

  // border width in pixels
  BCPixelSize mBStartContBorderWidth;
  BCPixelSize mBEndContBorderWidth;
};

inline nsTableColGroupFrame::nsTableColGroupFrame(ComputedStyle* aStyle)
  : nsContainerFrame(aStyle, kClassID)
  , mColCount(0)
  , mStartColIndex(0)
{
}

inline int32_t nsTableColGroupFrame::GetStartColumnIndex()
{
  return mStartColIndex;
}

inline void nsTableColGroupFrame::SetStartColumnIndex (int32_t aIndex)
{
  mStartColIndex = aIndex;
}

inline int32_t nsTableColGroupFrame::GetColCount() const
{
  return mColCount;
}

inline nsFrameList& nsTableColGroupFrame::GetWritableChildList()
{
  return mFrames;
}

#endif