Source code

Revision control

Copy as Markdown

Other Tools

/* -*- 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;
namespace mozilla {
class PresShell;
} // namespace mozilla
/**
* 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(
mozilla::PresShell* aPresShell, ComputedStyle* aStyle);
// nsIFrame overrides
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);
}
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 */
void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) override;
void SetInitialChildList(ChildListID aListID,
nsFrameList&& aChildList) override;
void AppendFrames(ChildListID aListID, nsFrameList&& aFrameList) override;
void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
const nsLineList::iterator* aPrevFrameLine,
nsFrameList&& aFrameList) override;
void RemoveFrame(DestroyContext&, ChildListID, nsIFrame*) 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(DestroyContext& aContext, 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.
*/
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
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.
*/
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);
void InvalidateFrame(uint32_t aDisplayItemKey = 0,
bool aRebuildDisplayItems = true) override;
void InvalidateFrameWithRect(const nsRect& aRect,
uint32_t aDisplayItemKey = 0,
bool aRebuildDisplayItems = true) override;
void InvalidateFrameForRemoval() override { InvalidateFrameSubtree(); }
protected:
nsTableColGroupFrame(ComputedStyle* aStyle, nsPresContext* aPresContext);
void InsertColsReflow(int32_t aColIndex, const nsFrameList::Slice& aCols);
LogicalSides GetLogicalSkipSides() const override;
// data members
int32_t mColCount;
// the starting column index this col group represents. Must be >= 0.
int32_t mStartColIndex;
};
inline nsTableColGroupFrame::nsTableColGroupFrame(ComputedStyle* aStyle,
nsPresContext* aPresContext)
: nsContainerFrame(aStyle, aPresContext, 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