2 * Copyright (C) 1997 Martin Jones (mjones@kde.org)
3 * (C) 1997 Torben Weis (weis@kde.org)
4 * (C) 1998 Waldo Bastian (bastian@kde.org)
5 * (C) 1999 Lars Knoll (knoll@kde.org)
6 * (C) 1999 Antti Koivisto (koivisto@kde.org)
7 * Copyright (C) 2003, 2004, 2005, 2006, 2009, 2013 Apple Inc. All rights reserved.
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public License
20 * along with this library; see the file COPYING.LIB. If not, write to
21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
25 #ifndef LayoutTableRow_h
26 #define LayoutTableRow_h
28 #include "core/CoreExport.h"
29 #include "core/layout/LayoutTableSection.h"
33 // There is a window of opportunity to read |m_rowIndex| before it is set when
34 // inserting the LayoutTableRow or during LayoutTableSection::recalcCells.
35 // This value is used to detect that case.
36 static const unsigned unsetRowIndex
= 0x7FFFFFFF;
37 static const unsigned maxRowIndex
= 0x7FFFFFFE; // 2,147,483,646
39 // LayoutTableRow is used to represent a table row (display: table-row).
41 // LayoutTableRow is a simple object. The reason is that most operations
42 // have to be coordinated at the LayoutTableSection level and thus are
43 // handled in LayoutTableSection (see e.g. layoutRows).
45 // The table model prevents any layout overflow on rows (but allow visual
46 // overflow). For row height, it is defined as "the maximum of the row's
47 // computed 'height', the computed 'height' of each cell in the row, and
48 // the minimum height (MIN) required by the cells" (CSS 2.1 - section 17.5.3).
49 // Note that this means that rows and cells differ from other LayoutObject as
50 // they will ignore 'height' in some situation (when other LayoutObject just
51 // allow some layout overflow to occur).
53 // LayoutTableRow doesn't establish a containing block for the underlying
54 // LayoutTableCells. That's why it inherits from LayoutBox and not LayoutBlock.
55 // One oddity is that LayoutTableRow doesn't establish a new coordinate system
56 // for its children. LayoutTableCells are positioned with respect to the
57 // enclosing LayoutTableSection (this object's parent()). This particularity is
58 // why functions accumulating offset while walking the tree have to special case
59 // LayoutTableRow (see e.g. PaintInvalidationState or
60 // LayoutBox::positionFromPoint()).
62 // LayoutTableRow is also positioned with respect to the enclosing
63 // LayoutTableSection. See LayoutTableSection::layoutRows() for the placement
65 class CORE_EXPORT LayoutTableRow final
: public LayoutBox
{
67 explicit LayoutTableRow(Element
*);
69 LayoutTableCell
* firstCell() const;
70 LayoutTableCell
* lastCell() const;
72 LayoutTableRow
* previousRow() const;
73 LayoutTableRow
* nextRow() const;
75 const LayoutObjectChildList
* children() const { return &m_children
; }
76 LayoutObjectChildList
* children() { return &m_children
; }
78 LayoutTableSection
* section() const { return toLayoutTableSection(parent()); }
79 LayoutTable
* table() const { return toLayoutTable(parent()->parent()); }
81 static LayoutTableRow
* createAnonymous(Document
*);
82 static LayoutTableRow
* createAnonymousWithParent(const LayoutObject
*);
83 LayoutBox
* createAnonymousBoxWithSameTypeAs(const LayoutObject
* parent
) const override
85 return createAnonymousWithParent(parent
);
88 void setRowIndex(unsigned rowIndex
)
90 if (UNLIKELY(rowIndex
> maxRowIndex
))
93 m_rowIndex
= rowIndex
;
96 bool rowIndexWasSet() const { return m_rowIndex
!= unsetRowIndex
; }
97 unsigned rowIndex() const
99 ASSERT(rowIndexWasSet());
100 ASSERT(!section() || !section()->needsCellRecalc()); // index may be bogus if cells need recalc.
104 const BorderValue
& borderAdjoiningTableStart() const
106 if (section()->hasSameDirectionAs(table()))
107 return style()->borderStart();
109 return style()->borderEnd();
112 const BorderValue
& borderAdjoiningTableEnd() const
114 if (section()->hasSameDirectionAs(table()))
115 return style()->borderEnd();
117 return style()->borderStart();
120 const BorderValue
& borderAdjoiningStartCell(const LayoutTableCell
*) const;
121 const BorderValue
& borderAdjoiningEndCell(const LayoutTableCell
*) const;
123 bool nodeAtPoint(HitTestResult
&, const HitTestLocation
& locationInContainer
, const LayoutPoint
& accumulatedOffset
, HitTestAction
) override
;
125 void addOverflowFromCell(const LayoutTableCell
*);
127 const char* name() const override
{ return "LayoutTableRow"; }
130 LayoutObjectChildList
* virtualChildren() override
{ return children(); }
131 const LayoutObjectChildList
* virtualChildren() const override
{ return children(); }
133 bool isOfType(LayoutObjectType type
) const override
{ return type
== LayoutObjectTableRow
|| LayoutBox::isOfType(type
); }
135 void willBeRemovedFromTree() override
;
137 void addChild(LayoutObject
* child
, LayoutObject
* beforeChild
= nullptr) override
;
138 void layout() override
;
140 DeprecatedPaintLayerType
layerTypeRequired() const override
142 if (hasTransformRelatedProperty() || hasHiddenBackface() || hasClipPath() || createsGroup() || style()->shouldCompositeForCurrentAnimations() || style()->hasCompositorProxy())
143 return NormalDeprecatedPaintLayer
;
145 if (hasOverflowClip())
146 return OverflowClipDeprecatedPaintLayer
;
148 return NoDeprecatedPaintLayer
;
151 void paint(const PaintInfo
&, const LayoutPoint
&) override
;
153 void imageChanged(WrappedImagePtr
, const IntRect
* = nullptr) override
;
155 void styleDidChange(StyleDifference
, const ComputedStyle
* oldStyle
) override
;
157 void nextSibling() const = delete;
158 void previousSibling() const = delete;
160 LayoutObjectChildList m_children
;
162 // This field should never be read directly. It should be read through
163 // rowIndex() above instead. This is to ensure that we never read this
164 // value before it is set.
165 unsigned m_rowIndex
: 31;
168 DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutTableRow
, isTableRow());
170 inline LayoutTableRow
* LayoutTableRow::previousRow() const
172 return toLayoutTableRow(LayoutObject::previousSibling());
175 inline LayoutTableRow
* LayoutTableRow::nextRow() const
177 return toLayoutTableRow(LayoutObject::nextSibling());
180 inline LayoutTableRow
* LayoutTableSection::firstRow() const
182 ASSERT(children() == virtualChildren());
183 return toLayoutTableRow(children()->firstChild());
186 inline LayoutTableRow
* LayoutTableSection::lastRow() const
188 ASSERT(children() == virtualChildren());
189 return toLayoutTableRow(children()->lastChild());
194 #endif // LayoutTableRow_h