summaryrefslogtreecommitdiff
path: root/layout/tables/nsTableFrame.h
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /layout/tables/nsTableFrame.h
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloaduxp-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
Add m-esr52 at 52.6.0
Diffstat (limited to 'layout/tables/nsTableFrame.h')
-rw-r--r--layout/tables/nsTableFrame.h997
1 files changed, 997 insertions, 0 deletions
diff --git a/layout/tables/nsTableFrame.h b/layout/tables/nsTableFrame.h
new file mode 100644
index 0000000000..a786253395
--- /dev/null
+++ b/layout/tables/nsTableFrame.h
@@ -0,0 +1,997 @@
+/* -*- 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 nsTableFrame_h__
+#define nsTableFrame_h__
+
+#include "mozilla/Attributes.h"
+#include "celldata.h"
+#include "imgIContainer.h"
+#include "nscore.h"
+#include "nsContainerFrame.h"
+#include "nsStyleCoord.h"
+#include "nsStyleConsts.h"
+#include "nsCellMap.h"
+#include "nsGkAtoms.h"
+#include "nsDisplayList.h"
+#include "TableArea.h"
+
+class nsTableCellFrame;
+class nsTableCellMap;
+class nsTableColFrame;
+class nsTableRowGroupFrame;
+class nsTableRowFrame;
+class nsTableColGroupFrame;
+class nsITableLayoutStrategy;
+class nsStyleContext;
+namespace mozilla {
+class WritingMode;
+class LogicalMargin;
+struct TableReflowInput;
+} // namespace mozilla
+
+struct BCPropertyData;
+
+static inline bool IS_TABLE_CELL(nsIAtom* frameType) {
+ return nsGkAtoms::tableCellFrame == frameType ||
+ nsGkAtoms::bcTableCellFrame == frameType;
+}
+
+static inline bool FrameHasBorderOrBackground(nsIFrame* f) {
+ return (f->StyleVisibility()->IsVisible() &&
+ (!f->StyleBackground()->IsTransparent() ||
+ f->StyleDisplay()->mAppearance ||
+ f->StyleBorder()->HasBorder()));
+}
+
+class nsDisplayTableItem : public nsDisplayItem
+{
+public:
+ nsDisplayTableItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
+ bool aDrawsBackground = true) :
+ nsDisplayItem(aBuilder, aFrame),
+ mPartHasFixedBackground(false),
+ mDrawsBackground(aDrawsBackground) {}
+
+ // With collapsed borders, parts of the collapsed border can extend outside
+ // the table part frames, so allow this display element to blow out to our
+ // overflow rect. This is also useful for row frames that have spanning
+ // cells extending outside them.
+ virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override;
+
+ virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override;
+ virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
+ const nsDisplayItemGeometry* aGeometry,
+ nsRegion *aInvalidRegion) override;
+
+ void UpdateForFrameBackground(nsIFrame* aFrame);
+
+private:
+ bool mPartHasFixedBackground;
+ bool mDrawsBackground;
+};
+
+class nsAutoPushCurrentTableItem
+{
+public:
+ nsAutoPushCurrentTableItem() : mBuilder(nullptr) {}
+
+ void Push(nsDisplayListBuilder* aBuilder, nsDisplayTableItem* aPushItem)
+ {
+ mBuilder = aBuilder;
+ mOldCurrentItem = aBuilder->GetCurrentTableItem();
+ aBuilder->SetCurrentTableItem(aPushItem);
+#ifdef DEBUG
+ mPushedItem = aPushItem;
+#endif
+ }
+ ~nsAutoPushCurrentTableItem() {
+ if (!mBuilder)
+ return;
+#ifdef DEBUG
+ NS_ASSERTION(mBuilder->GetCurrentTableItem() == mPushedItem,
+ "Someone messed with the current table item behind our back!");
+#endif
+ mBuilder->SetCurrentTableItem(mOldCurrentItem);
+ }
+
+private:
+ nsDisplayListBuilder* mBuilder;
+ nsDisplayTableItem* mOldCurrentItem;
+#ifdef DEBUG
+ nsDisplayTableItem* mPushedItem;
+#endif
+};
+
+/* ============================================================================ */
+
+enum nsTableColGroupType {
+ eColGroupContent = 0, // there is real col group content associated
+ eColGroupAnonymousCol = 1, // the result of a col
+ eColGroupAnonymousCell = 2 // the result of a cell alone
+};
+
+enum nsTableColType {
+ eColContent = 0, // there is real col content associated
+ eColAnonymousCol = 1, // the result of a span on a col
+ eColAnonymousColGroup = 2, // the result of a span on a col group
+ eColAnonymousCell = 3 // the result of a cell alone
+};
+
+/**
+ * nsTableFrame maps the inner portion of a table (everything except captions.)
+ * Used as a pseudo-frame within nsTableWrapperFrame, it may also be used
+ * stand-alone as the top-level frame.
+ *
+ * The principal child list contains row group frames. There is also an
+ * additional child list, kColGroupList, which contains the col group frames.
+ */
+class nsTableFrame : public nsContainerFrame
+{
+ typedef mozilla::image::DrawResult DrawResult;
+ typedef mozilla::WritingMode WritingMode;
+ typedef mozilla::LogicalMargin LogicalMargin;
+ typedef mozilla::TableReflowInput TableReflowInput;
+
+public:
+ NS_DECL_QUERYFRAME_TARGET(nsTableFrame)
+ NS_DECL_FRAMEARENA_HELPERS
+
+ typedef nsTArray<nsIFrame*> FrameTArray;
+ NS_DECLARE_FRAME_PROPERTY_DELETABLE(PositionedTablePartArray, FrameTArray)
+
+ /** nsTableWrapperFrame has intimate knowledge of the inner table frame */
+ friend class nsTableWrapperFrame;
+
+ /** instantiate a new instance of nsTableRowFrame.
+ * @param aPresShell the pres shell for this frame
+ *
+ * @return the frame that was created
+ */
+ friend nsTableFrame* NS_NewTableFrame(nsIPresShell* aPresShell,
+ nsStyleContext* aContext);
+
+ /** sets defaults for table-specific style.
+ * @see nsIFrame::Init
+ */
+ virtual void Init(nsIContent* aContent,
+ nsContainerFrame* aParent,
+ nsIFrame* aPrevInFlow) override;
+
+ static float GetTwipsToPixels(nsPresContext* aPresContext);
+
+ // Return true if aParentReflowInput.frame or any of its ancestors within
+ // the containing table have non-auto bsize. (e.g. pct or fixed bsize)
+ static bool AncestorsHaveStyleBSize(const ReflowInput& aParentReflowInput);
+
+ // See if a special bsize reflow will occur due to having a pct bsize when
+ // the pct bsize basis may not yet be valid.
+ static void CheckRequestSpecialBSizeReflow(const ReflowInput& aReflowInput);
+
+ // Notify the frame and its ancestors (up to the containing table) that a special
+ // height reflow will occur.
+ static void RequestSpecialBSizeReflow(const ReflowInput& aReflowInput);
+
+ static void RePositionViews(nsIFrame* aFrame);
+
+ static bool PageBreakAfter(nsIFrame* aSourceFrame,
+ nsIFrame* aNextFrame);
+
+ // Register a positioned table part with its nsTableFrame. These objects will
+ // be visited by FixupPositionedTableParts after reflow is complete. (See that
+ // function for more explanation.) Should be called during frame construction.
+ static void RegisterPositionedTablePart(nsIFrame* aFrame);
+
+ // Unregister a positioned table part with its nsTableFrame.
+ static void UnregisterPositionedTablePart(nsIFrame* aFrame,
+ nsIFrame* aDestructRoot);
+
+ nsPoint GetFirstSectionOrigin(const ReflowInput& aReflowInput) const;
+ /*
+ * Notification that aAttribute has changed for content inside a table (cell, row, etc)
+ */
+ void AttributeChangedFor(nsIFrame* aFrame,
+ nsIContent* aContent,
+ nsIAtom* aAttribute);
+
+ /** @see nsIFrame::DestroyFrom */
+ virtual void DestroyFrom(nsIFrame* aDestructRoot) override;
+
+ /** @see nsIFrame::DidSetStyleContext */
+ virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) 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;
+
+ virtual nsMargin GetUsedBorder() const override;
+ virtual nsMargin GetUsedPadding() const override;
+ virtual nsMargin GetUsedMargin() const override;
+
+ // Get the offset from the border box to the area where the row groups fit
+ LogicalMargin GetChildAreaOffset(const WritingMode aWM,
+ const ReflowInput* aReflowInput) const;
+
+ /** helper method to find the table parent of any table frame object */
+ static nsTableFrame* GetTableFrame(nsIFrame* aSourceFrame);
+
+ /* Like GetTableFrame, but will set *aDidPassThrough to false if we don't
+ * pass through aMustPassThrough on the way to the table.
+ */
+ static nsTableFrame* GetTableFramePassingThrough(nsIFrame* aMustPassThrough,
+ nsIFrame* aSourceFrame,
+ bool* aDidPassThrough);
+
+ typedef void (* DisplayGenericTablePartTraversal)
+ (nsDisplayListBuilder* aBuilder, nsFrame* aFrame,
+ const nsRect& aDirtyRect, const nsDisplayListSet& aLists);
+ static void GenericTraversal(nsDisplayListBuilder* aBuilder, nsFrame* aFrame,
+ const nsRect& aDirtyRect, const nsDisplayListSet& aLists);
+
+ /**
+ * Helper method to handle display common to table frames, rowgroup frames
+ * and row frames. It creates a background display item for handling events
+ * if necessary, an outline display item if necessary, and displays
+ * all the the frame's children.
+ * @param aDisplayItem the display item created for this part, or null
+ * if this part's border/background painting is delegated to an ancestor
+ * @param aTraversal a function that gets called to traverse the table
+ * part's child frames and add their display list items to a
+ * display list set.
+ */
+ static void DisplayGenericTablePart(nsDisplayListBuilder* aBuilder,
+ nsFrame* aFrame,
+ const nsRect& aDirtyRect,
+ const nsDisplayListSet& aLists,
+ nsDisplayTableItem* aDisplayItem,
+ DisplayGenericTablePartTraversal aTraversal = GenericTraversal);
+
+ // Return the closest sibling of aPriorChildFrame (including aPriroChildFrame)
+ // of type aChildType.
+ static nsIFrame* GetFrameAtOrBefore(nsIFrame* aParentFrame,
+ nsIFrame* aPriorChildFrame,
+ nsIAtom* aChildType);
+ bool IsAutoBSize(mozilla::WritingMode aWM);
+
+ /** @return true if aDisplayType represents a rowgroup of any sort
+ * (header, footer, or body)
+ */
+ bool IsRowGroup(mozilla::StyleDisplay aDisplayType) const;
+
+ virtual const nsFrameList& GetChildList(ChildListID aListID) const override;
+ virtual void GetChildLists(nsTArray<ChildList>* aLists) const override;
+
+ virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
+ const nsRect& aDirtyRect,
+ const nsDisplayListSet& aLists) override;
+
+ /**
+ * Paint the background of the table and its parts (column groups,
+ * columns, row groups, rows, and cells), and the table border, and all
+ * internal borders if border-collapse is on.
+ */
+ DrawResult PaintTableBorderBackground(nsDisplayListBuilder* aBuilder,
+ nsRenderingContext& aRenderingContext,
+ const nsRect& aDirtyRect,
+ nsPoint aPt);
+
+ /** Get the outer half (i.e., the part outside the height and width of
+ * the table) of the largest segment (?) of border-collapsed border on
+ * the table on each side, or 0 for non border-collapsed tables.
+ */
+ LogicalMargin GetOuterBCBorder(const WritingMode aWM) const;
+
+ /** Same as above, but only if it's included from the border-box width
+ * of the table.
+ */
+ LogicalMargin GetIncludedOuterBCBorder(const WritingMode aWM) const;
+
+ /** Same as above, but only if it's excluded from the border-box width
+ * of the table. This is the area that leaks out into the margin
+ * (or potentially past it, if there is no margin).
+ */
+ LogicalMargin GetExcludedOuterBCBorder(const WritingMode aWM) const;
+
+ /**
+ * In quirks mode, the size of the table background is reduced
+ * by the outer BC border. Compute the reduction needed.
+ */
+ nsMargin GetDeflationForBackground(nsPresContext* aPresContext) const;
+
+ /** Get width of table + colgroup + col collapse: elements that
+ * continue along the length of the whole iStart side.
+ * see nsTablePainter about continuous borders
+ */
+ nscoord GetContinuousIStartBCBorderWidth() const;
+ void SetContinuousIStartBCBorderWidth(nscoord aValue);
+
+ friend class nsDelayedCalcBCBorders;
+
+ void AddBCDamageArea(const mozilla::TableArea& aValue);
+ bool BCRecalcNeeded(nsStyleContext* aOldStyleContext,
+ nsStyleContext* aNewStyleContext);
+ void PaintBCBorders(DrawTarget& aDrawTarget, const nsRect& aDirtyRect);
+
+ virtual void MarkIntrinsicISizesDirty() override;
+ // For border-collapse tables, the caller must not add padding and
+ // border to the results of these functions.
+ virtual nscoord GetMinISize(nsRenderingContext *aRenderingContext) override;
+ virtual nscoord GetPrefISize(nsRenderingContext *aRenderingContext) override;
+ virtual IntrinsicISizeOffsetData IntrinsicISizeOffsets() override;
+
+ virtual mozilla::LogicalSize
+ ComputeSize(nsRenderingContext* aRenderingContext,
+ mozilla::WritingMode aWM,
+ const mozilla::LogicalSize& aCBSize,
+ nscoord aAvailableISize,
+ const mozilla::LogicalSize& aMargin,
+ const mozilla::LogicalSize& aBorder,
+ const mozilla::LogicalSize& aPadding,
+ ComputeSizeFlags aFlags) override;
+
+ virtual mozilla::LogicalSize
+ ComputeAutoSize(nsRenderingContext* aRenderingContext,
+ mozilla::WritingMode aWM,
+ const mozilla::LogicalSize& aCBSize,
+ nscoord aAvailableISize,
+ const mozilla::LogicalSize& aMargin,
+ const mozilla::LogicalSize& aBorder,
+ const mozilla::LogicalSize& aPadding,
+ ComputeSizeFlags aFlags) override;
+
+ /**
+ * A copy of nsFrame::ShrinkWidthToFit that calls a different
+ * GetPrefISize, since tables have two different ones.
+ */
+ nscoord TableShrinkISizeToFit(nsRenderingContext *aRenderingContext,
+ nscoord aWidthInCB);
+
+ // XXXldb REWRITE THIS COMMENT!
+ /** inner tables are reflowed in two steps.
+ * <pre>
+ * if mFirstPassValid is false, this is our first time through since content was last changed
+ * set pass to 1
+ * do pass 1
+ * get min/max info for all cells in an infinite space
+ * do column balancing
+ * set mFirstPassValid to true
+ * do pass 2
+ * use column widths to Reflow cells
+ * </pre>
+ *
+ * @see nsIFrame::Reflow
+ */
+ virtual void Reflow(nsPresContext* aPresContext,
+ ReflowOutput& aDesiredSize,
+ const ReflowInput& aReflowInput,
+ nsReflowStatus& aStatus) override;
+
+ void ReflowTable(ReflowOutput& aDesiredSize,
+ const ReflowInput& aReflowInput,
+ nscoord aAvailBSize,
+ nsIFrame*& aLastChildReflowed,
+ nsReflowStatus& aStatus);
+
+ nsFrameList& GetColGroups();
+
+ virtual nsStyleContext*
+ GetParentStyleContext(nsIFrame** aProviderFrame) const override;
+
+ /**
+ * Get the "type" of the frame
+ *
+ * @see nsGkAtoms::tableFrame
+ */
+ virtual nsIAtom* GetType() const override;
+
+ virtual bool IsFrameOfType(uint32_t aFlags) const override
+ {
+ if (aFlags & eSupportsCSSTransforms) {
+ return false;
+ }
+ return nsContainerFrame::IsFrameOfType(aFlags);
+ }
+
+#ifdef DEBUG_FRAME_DUMP
+ /** @see nsIFrame::GetFrameName */
+ virtual nsresult GetFrameName(nsAString& aResult) const override;
+#endif
+
+ /** Return the isize of the column at aColIndex.
+ * This may only be called on the table's first-in-flow.
+ */
+ nscoord GetColumnISizeFromFirstInFlow(int32_t aColIndex);
+
+ /** Helper to get the column spacing style value.
+ * The argument refers to the space between column aColIndex and column
+ * aColIndex + 1. An index of -1 indicates the padding between the table
+ * and the left border, an index equal to the number of columns indicates
+ * the padding between the table and the right border.
+ *
+ * Although in this class cell spacing does not depend on the index, it
+ * may be important for overriding classes.
+ */
+ virtual nscoord GetColSpacing(int32_t aColIndex);
+
+ /** Helper to find the sum of the cell spacing between arbitrary columns.
+ * The argument refers to the space between column aColIndex and column
+ * aColIndex + 1. An index of -1 indicates the padding between the table
+ * and the left border, an index equal to the number of columns indicates
+ * the padding between the table and the right border.
+ *
+ * This method is equivalent to
+ * nscoord result = 0;
+ * for (i = aStartColIndex; i < aEndColIndex; i++) {
+ * result += GetColSpacing(i);
+ * }
+ * return result;
+ */
+ virtual nscoord GetColSpacing(int32_t aStartColIndex,
+ int32_t aEndColIndex);
+
+ /** Helper to get the row spacing style value.
+ * The argument refers to the space between row aRowIndex and row
+ * aRowIndex + 1. An index of -1 indicates the padding between the table
+ * and the top border, an index equal to the number of rows indicates
+ * the padding between the table and the bottom border.
+ *
+ * Although in this class cell spacing does not depend on the index, it
+ * may be important for overriding classes.
+ */
+ virtual nscoord GetRowSpacing(int32_t aRowIndex);
+
+ /** Helper to find the sum of the cell spacing between arbitrary rows.
+ * The argument refers to the space between row aRowIndex and row
+ * aRowIndex + 1. An index of -1 indicates the padding between the table
+ * and the top border, an index equal to the number of rows indicates
+ * the padding between the table and the bottom border.
+ *
+ * This method is equivalent to
+ * nscoord result = 0;
+ * for (i = aStartRowIndex; i < aEndRowIndex; i++) {
+ * result += GetRowSpacing(i);
+ * }
+ * return result;
+ */
+ virtual nscoord GetRowSpacing(int32_t aStartRowIndex,
+ int32_t aEndRowIndex);
+
+private:
+ /* For the base implementation of nsTableFrame, cell spacing does not depend
+ * on row/column indexing.
+ */
+ nscoord GetColSpacing();
+ nscoord GetRowSpacing();
+
+public:
+ virtual nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const override;
+ bool GetNaturalBaselineBOffset(mozilla::WritingMode aWM,
+ BaselineSharingGroup aBaselineGroup,
+ nscoord* aBaseline) const override;
+
+ /** return the row span of a cell, taking into account row span magic at the bottom
+ * of a table. The row span equals the number of rows spanned by aCell starting at
+ * aStartRowIndex, and can be smaller if aStartRowIndex is greater than the row
+ * index in which aCell originates.
+ *
+ * @param aStartRowIndex the cell
+ * @param aCell the cell
+ *
+ * @return the row span, correcting for row spans that extend beyond the bottom
+ * of the table.
+ */
+ int32_t GetEffectiveRowSpan(int32_t aStartRowIndex,
+ const nsTableCellFrame& aCell) const;
+ int32_t GetEffectiveRowSpan(const nsTableCellFrame& aCell,
+ nsCellMap* aCellMap = nullptr);
+
+ /** return the col span of a cell, taking into account col span magic at the edge
+ * of a table.
+ *
+ * @param aCell the cell
+ *
+ * @return the col span, correcting for col spans that extend beyond the edge
+ * of the table.
+ */
+ int32_t GetEffectiveColSpan(const nsTableCellFrame& aCell,
+ nsCellMap* aCellMap = nullptr) const;
+
+ /** indicate whether the row has more than one cell that either originates
+ * or is spanned from the rows above
+ */
+ bool HasMoreThanOneCell(int32_t aRowIndex) const;
+
+ /** return the column frame associated with aColIndex
+ * returns nullptr if the col frame has not yet been allocated, or if
+ * aColIndex is out of range
+ */
+ nsTableColFrame* GetColFrame(int32_t aColIndex) const;
+
+ /** Insert a col frame reference into the colframe cache and adapt the cellmap
+ * @param aColFrame - the column frame
+ * @param aColIndex - index where the column should be inserted into the
+ * colframe cache
+ */
+ void InsertCol(nsTableColFrame& aColFrame,
+ int32_t aColIndex);
+
+ nsTableColGroupFrame* CreateAnonymousColGroupFrame(nsTableColGroupType aType);
+
+ int32_t DestroyAnonymousColFrames(int32_t aNumFrames);
+
+ // Append aNumColsToAdd anonymous col frames of type eColAnonymousCell to our
+ // last eColGroupAnonymousCell colgroup. If we have no such colgroup, then
+ // create one.
+ void AppendAnonymousColFrames(int32_t aNumColsToAdd);
+
+ // Append aNumColsToAdd anonymous col frames of type aColType to
+ // aColGroupFrame. If aAddToTable is true, also call AddColsToTable on the
+ // new cols.
+ void AppendAnonymousColFrames(nsTableColGroupFrame* aColGroupFrame,
+ int32_t aNumColsToAdd,
+ nsTableColType aColType,
+ bool aAddToTable);
+
+ void MatchCellMapToColCache(nsTableCellMap* aCellMap);
+ /** empty the column frame cache */
+ void ClearColCache();
+
+ void DidResizeColumns();
+
+ void AppendCell(nsTableCellFrame& aCellFrame,
+ int32_t aRowIndex);
+
+ void InsertCells(nsTArray<nsTableCellFrame*>& aCellFrames,
+ int32_t aRowIndex,
+ int32_t aColIndexBefore);
+
+ void RemoveCell(nsTableCellFrame* aCellFrame,
+ int32_t aRowIndex);
+
+ void AppendRows(nsTableRowGroupFrame* aRowGroupFrame,
+ int32_t aRowIndex,
+ nsTArray<nsTableRowFrame*>& aRowFrames);
+
+ int32_t InsertRows(nsTableRowGroupFrame* aRowGroupFrame,
+ nsTArray<nsTableRowFrame*>& aFrames,
+ int32_t aRowIndex,
+ bool aConsiderSpans);
+
+ void RemoveRows(nsTableRowFrame& aFirstRowFrame,
+ int32_t aNumRowsToRemove,
+ bool aConsiderSpans);
+
+ /** Insert multiple rowgroups into the table cellmap handling
+ * @param aRowGroups - iterator that iterates over the rowgroups to insert
+ */
+ void InsertRowGroups(const nsFrameList::Slice& aRowGroups);
+
+ void InsertColGroups(int32_t aStartColIndex,
+ const nsFrameList::Slice& aColgroups);
+
+ void RemoveCol(nsTableColGroupFrame* aColGroupFrame,
+ int32_t aColIndex,
+ bool aRemoveFromCache,
+ bool aRemoveFromCellMap);
+
+ bool ColumnHasCellSpacingBefore(int32_t aColIndex) const;
+
+ bool HasPctCol() const;
+ void SetHasPctCol(bool aValue);
+
+ bool HasCellSpanningPctCol() const;
+ void SetHasCellSpanningPctCol(bool aValue);
+
+ /**
+ * To be called on a frame by its parent after setting its size/position and
+ * calling DidReflow (possibly via FinishReflowChild()). This can also be
+ * used for child frames which are not being reflowed but did have their size
+ * or position changed.
+ *
+ * @param aFrame The frame to invalidate
+ * @param aOrigRect The original rect of aFrame (before the change).
+ * @param aOrigVisualOverflow The original overflow rect of aFrame.
+ * @param aIsFirstReflow True if the size/position change is due to the
+ * first reflow of aFrame.
+ */
+ static void InvalidateTableFrame(nsIFrame* aFrame,
+ const nsRect& aOrigRect,
+ const nsRect& aOrigVisualOverflow,
+ bool aIsFirstReflow);
+
+ virtual bool ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas) override;
+
+protected:
+
+ /** protected constructor.
+ * @see NewFrame
+ */
+ explicit nsTableFrame(nsStyleContext* aContext);
+
+ /** destructor, responsible for mColumnLayoutData */
+ virtual ~nsTableFrame();
+
+ void InitChildReflowInput(ReflowInput& aReflowInput);
+
+ virtual LogicalSides GetLogicalSkipSides(const ReflowInput* aReflowInput = nullptr) const override;
+
+public:
+ bool IsRowInserted() const;
+ void SetRowInserted(bool aValue);
+
+protected:
+
+ // A helper function to reflow a header or footer with unconstrained height
+ // to see if it should be made repeatable and also to determine its desired
+ // height.
+ nsresult SetupHeaderFooterChild(const TableReflowInput& aReflowInput,
+ nsTableRowGroupFrame* aFrame,
+ nscoord* aDesiredHeight);
+
+ void ReflowChildren(TableReflowInput& aReflowInput,
+ nsReflowStatus& aStatus,
+ nsIFrame*& aLastChildReflowed,
+ nsOverflowAreas& aOverflowAreas);
+
+ // This calls the col group and column reflow methods, which do two things:
+ // (1) set all the dimensions to 0
+ // (2) notify the table about colgroups or columns with hidden visibility
+ void ReflowColGroups(nsRenderingContext* aRenderingContext);
+
+ /** return the isize of the table taking into account visibility collapse
+ * on columns and colgroups
+ * @param aBorderPadding the border and padding of the table
+ */
+ nscoord GetCollapsedISize(const WritingMode aWM,
+ const LogicalMargin& aBorderPadding);
+
+
+ /** Adjust the table for visibility.collapse set on rowgroups, rows,
+ * colgroups and cols
+ * @param aDesiredSize the metrics of the table
+ * @param aBorderPadding the border and padding of the table
+ */
+ void AdjustForCollapsingRowsCols(ReflowOutput& aDesiredSize,
+ const WritingMode aWM,
+ const LogicalMargin& aBorderPadding);
+
+ /** FixupPositionedTableParts is called at the end of table reflow to reflow
+ * the absolutely positioned descendants of positioned table parts. This is
+ * necessary because the dimensions of table parts may change after they've
+ * been reflowed (e.g. in AdjustForCollapsingRowsCols).
+ */
+ void FixupPositionedTableParts(nsPresContext* aPresContext,
+ ReflowOutput& aDesiredSize,
+ const ReflowInput& aReflowInput);
+
+ // Clears the list of positioned table parts.
+ void ClearAllPositionedTableParts();
+
+ nsITableLayoutStrategy* LayoutStrategy() const {
+ return static_cast<nsTableFrame*>(FirstInFlow())->
+ mTableLayoutStrategy;
+ }
+
+ // Helper for InsertFrames.
+ void HomogenousInsertFrames(ChildListID aListID,
+ nsIFrame* aPrevFrame,
+ nsFrameList& aFrameList);
+private:
+ /* Handle a row that got inserted during reflow. aNewHeight is the
+ new height of the table after reflow. */
+ void ProcessRowInserted(nscoord aNewHeight);
+
+ // WIDTH AND HEIGHT CALCULATION
+
+public:
+
+ // calculate the computed block-size of aFrame including its border and
+ // padding given its reflow state.
+ nscoord CalcBorderBoxBSize(const ReflowInput& aReflowInput);
+
+protected:
+
+ // update the desired block-size of this table taking into account the current
+ // reflow state, the table attributes and the content driven rowgroup bsizes
+ // this function can change the overflow area
+ void CalcDesiredBSize(const ReflowInput& aReflowInput,
+ ReflowOutput& aDesiredSize);
+
+ // The following is a helper for CalcDesiredBSize
+
+ void DistributeBSizeToRows(const ReflowInput& aReflowInput,
+ nscoord aAmount);
+
+ void PlaceChild(TableReflowInput& aReflowInput,
+ nsIFrame* aKidFrame,
+ nsPoint aKidPosition,
+ ReflowOutput& aKidDesiredSize,
+ const nsRect& aOriginalKidRect,
+ const nsRect& aOriginalKidVisualOverflow);
+ void PlaceRepeatedFooter(TableReflowInput& aReflowInput,
+ nsTableRowGroupFrame *aTfoot,
+ nscoord aFooterHeight);
+
+ nsIFrame* GetFirstBodyRowGroupFrame();
+public:
+ typedef AutoTArray<nsTableRowGroupFrame*, 8> RowGroupArray;
+ /**
+ * Push all our child frames from the aRowGroups array, in order, starting
+ * from the frame at aPushFrom to the end of the array. The frames are put on
+ * our overflow list or moved directly to our next-in-flow if one exists.
+ */
+protected:
+ void PushChildren(const RowGroupArray& aRowGroups, int32_t aPushFrom);
+
+public:
+ // put the children frames in the display order (e.g. thead before tbodies
+ // before tfoot). This will handle calling GetRowGroupFrame() on the
+ // children, and not append nulls, so the array is guaranteed to contain
+ // nsTableRowGroupFrames. If there are multiple theads or tfoots, all but
+ // the first one are treated as tbodies instead.
+
+ void OrderRowGroups(RowGroupArray& aChildren,
+ nsTableRowGroupFrame** aHead = nullptr,
+ nsTableRowGroupFrame** aFoot = nullptr) const;
+
+ // Return the thead, if any
+ nsTableRowGroupFrame* GetTHead() const;
+
+ // Return the tfoot, if any
+ nsTableRowGroupFrame* GetTFoot() const;
+
+ // Returns true if there are any cells above the row at
+ // aRowIndex and spanning into the row at aRowIndex, the number of
+ // effective columns limits the search up to that column
+ bool RowIsSpannedInto(int32_t aRowIndex, int32_t aNumEffCols);
+
+ // Returns true if there is a cell originating in aRowIndex
+ // which spans into the next row, the number of effective
+ // columns limits the search up to that column
+ bool RowHasSpanningCells(int32_t aRowIndex, int32_t aNumEffCols);
+
+protected:
+
+ bool HaveReflowedColGroups() const;
+ void SetHaveReflowedColGroups(bool aValue);
+
+public:
+ bool IsBorderCollapse() const;
+
+ bool NeedToCalcBCBorders() const;
+ void SetNeedToCalcBCBorders(bool aValue);
+
+ bool NeedToCollapse() const;
+ void SetNeedToCollapse(bool aValue);
+
+ /** The GeometryDirty bit is similar to the NS_FRAME_IS_DIRTY frame
+ * state bit, which implies that all descendants are dirty. The
+ * GeometryDirty still implies that all the parts of the table are
+ * dirty, but resizing optimizations should still apply to the
+ * contents of the individual cells.
+ */
+ void SetGeometryDirty() { mBits.mGeometryDirty = true; }
+ void ClearGeometryDirty() { mBits.mGeometryDirty = false; }
+ bool IsGeometryDirty() const { return mBits.mGeometryDirty; }
+
+ /** Get the cell map for this table frame. It is not always mCellMap.
+ * Only the firstInFlow has a legit cell map
+ */
+ nsTableCellMap* GetCellMap() const;
+
+ /** Iterate over the row groups and adjust the row indices of all rows
+ * whose index is >= aRowIndex.
+ * @param aRowIndex - start adjusting with this index
+ * @param aAdjustment - shift the row index by this amount
+ */
+ void AdjustRowIndices(int32_t aRowIndex,
+ int32_t aAdjustment);
+
+ /** Reset the rowindices of all rows as they might have changed due to
+ * rowgroup reordering, exclude new row group frames that show in the
+ * reordering but are not yet inserted into the cellmap
+ * @param aRowGroupsToExclude - an iterator that will produce the row groups
+ * to exclude.
+ */
+ void ResetRowIndices(const nsFrameList::Slice& aRowGroupsToExclude);
+
+ nsTArray<nsTableColFrame*>& GetColCache();
+
+
+protected:
+
+ void SetBorderCollapse(bool aValue);
+
+ BCPropertyData* GetBCProperty(bool aCreateIfNecessary = false) const;
+ void SetFullBCDamageArea();
+ void CalcBCBorders();
+
+ void ExpandBCDamageArea(mozilla::TableArea& aRect) const;
+
+ void SetColumnDimensions(nscoord aHeight, WritingMode aWM,
+ const LogicalMargin& aBorderPadding,
+ const nsSize& aContainerSize);
+
+ int32_t CollectRows(nsIFrame* aFrame,
+ nsTArray<nsTableRowFrame*>& aCollection);
+
+public: /* ----- Cell Map public methods ----- */
+
+ int32_t GetStartRowIndex(nsTableRowGroupFrame* aRowGroupFrame);
+
+ /** returns the number of rows in this table.
+ */
+ int32_t GetRowCount () const
+ {
+ return GetCellMap()->GetRowCount();
+ }
+
+ /** returns the number of columns in this table after redundant columns have been removed
+ */
+ int32_t GetEffectiveColCount() const;
+
+ /* return the col count including dead cols */
+ int32_t GetColCount () const
+ {
+ return GetCellMap()->GetColCount();
+ }
+
+ // return the last col index which isn't of type eColAnonymousCell
+ int32_t GetIndexOfLastRealCol();
+
+ /** returns true if table-layout:auto */
+ bool IsAutoLayout();
+
+public:
+
+#ifdef DEBUG
+ void Dump(bool aDumpRows,
+ bool aDumpCols,
+ bool aDumpCellMap);
+#endif
+
+protected:
+ /**
+ * Helper method for RemoveFrame.
+ */
+ void DoRemoveFrame(ChildListID aListID, nsIFrame* aOldFrame);
+#ifdef DEBUG
+ void DumpRowGroup(nsIFrame* aChildFrame);
+#endif
+ // DATA MEMBERS
+ AutoTArray<nsTableColFrame*, 8> mColFrames;
+
+ struct TableBits {
+ uint32_t mHaveReflowedColGroups:1; // have the col groups gotten their initial reflow
+ uint32_t mHasPctCol:1; // does any cell or col have a pct width
+ uint32_t mCellSpansPctCol:1; // does any cell span a col with a pct width (or containing a cell with a pct width)
+ uint32_t mIsBorderCollapse:1; // border collapsing model vs. separate model
+ uint32_t mRowInserted:1;
+ uint32_t mNeedToCalcBCBorders:1;
+ uint32_t mGeometryDirty:1;
+ uint32_t mIStartContBCBorder:8;
+ uint32_t mNeedToCollapse:1; // rows, cols that have visibility:collapse need to be collapsed
+ uint32_t mResizedColumns:1; // have we resized columns since last reflow?
+ } mBits;
+
+ nsTableCellMap* mCellMap; // maintains the relationships between rows, cols, and cells
+ nsITableLayoutStrategy* mTableLayoutStrategy;// the layout strategy for this frame
+ nsFrameList mColGroups; // the list of colgroup frames
+};
+
+
+inline bool nsTableFrame::IsRowGroup(mozilla::StyleDisplay aDisplayType) const
+{
+ return mozilla::StyleDisplay::TableHeaderGroup == aDisplayType ||
+ mozilla::StyleDisplay::TableFooterGroup == aDisplayType ||
+ mozilla::StyleDisplay::TableRowGroup == aDisplayType;
+}
+
+inline void nsTableFrame::SetHaveReflowedColGroups(bool aValue)
+{
+ mBits.mHaveReflowedColGroups = aValue;
+}
+
+inline bool nsTableFrame::HaveReflowedColGroups() const
+{
+ return (bool)mBits.mHaveReflowedColGroups;
+}
+
+inline bool nsTableFrame::HasPctCol() const
+{
+ return (bool)mBits.mHasPctCol;
+}
+
+inline void nsTableFrame::SetHasPctCol(bool aValue)
+{
+ mBits.mHasPctCol = (unsigned)aValue;
+}
+
+inline bool nsTableFrame::HasCellSpanningPctCol() const
+{
+ return (bool)mBits.mCellSpansPctCol;
+}
+
+inline void nsTableFrame::SetHasCellSpanningPctCol(bool aValue)
+{
+ mBits.mCellSpansPctCol = (unsigned)aValue;
+}
+
+inline bool nsTableFrame::IsRowInserted() const
+{
+ return (bool)mBits.mRowInserted;
+}
+
+inline void nsTableFrame::SetRowInserted(bool aValue)
+{
+ mBits.mRowInserted = (unsigned)aValue;
+}
+
+inline void nsTableFrame::SetNeedToCollapse(bool aValue)
+{
+ static_cast<nsTableFrame*>(FirstInFlow())->mBits.mNeedToCollapse = (unsigned)aValue;
+}
+
+inline bool nsTableFrame::NeedToCollapse() const
+{
+ return (bool) static_cast<nsTableFrame*>(FirstInFlow())->mBits.mNeedToCollapse;
+}
+
+inline nsFrameList& nsTableFrame::GetColGroups()
+{
+ return static_cast<nsTableFrame*>(FirstInFlow())->mColGroups;
+}
+
+inline nsTArray<nsTableColFrame*>& nsTableFrame::GetColCache()
+{
+ return mColFrames;
+}
+
+inline bool nsTableFrame::IsBorderCollapse() const
+{
+ return (bool)mBits.mIsBorderCollapse;
+}
+
+inline void nsTableFrame::SetBorderCollapse(bool aValue)
+{
+ mBits.mIsBorderCollapse = aValue;
+}
+
+inline bool nsTableFrame::NeedToCalcBCBorders() const
+{
+ return (bool)mBits.mNeedToCalcBCBorders;
+}
+
+inline void nsTableFrame::SetNeedToCalcBCBorders(bool aValue)
+{
+ mBits.mNeedToCalcBCBorders = (unsigned)aValue;
+}
+
+inline nscoord
+nsTableFrame::GetContinuousIStartBCBorderWidth() const
+{
+ int32_t aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel();
+ return BC_BORDER_END_HALF_COORD(aPixelsToTwips, mBits.mIStartContBCBorder);
+}
+
+inline void nsTableFrame::SetContinuousIStartBCBorderWidth(nscoord aValue)
+{
+ mBits.mIStartContBCBorder = (unsigned) aValue;
+}
+
+#define ABORT0() \
+{NS_ASSERTION(false, "CellIterator program error"); \
+return;}
+
+#define ABORT1(aReturn) \
+{NS_ASSERTION(false, "CellIterator program error"); \
+return aReturn;}
+
+#endif