| /* |
| * Copyright (C) 1997 Martin Jones (mjones@kde.org) |
| * (C) 1997 Torben Weis (weis@kde.org) |
| * (C) 1998 Waldo Bastian (bastian@kde.org) |
| * (C) 1999 Lars Knoll (knoll@kde.org) |
| * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| * Copyright (C) 2003, 2004, 2005, 2006, 2009, 2013 Apple Inc. |
| * All rights reserved. |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Library General Public |
| * License as published by the Free Software Foundation; either |
| * version 2 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Library General Public License for more details. |
| * |
| * You should have received a copy of the GNU Library General Public License |
| * along with this library; see the file COPYING.LIB. If not, write to |
| * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| * Boston, MA 02110-1301, USA. |
| */ |
| |
| #ifndef LayoutTableRow_h |
| #define LayoutTableRow_h |
| |
| #include "core/CoreExport.h" |
| #include "core/layout/LayoutTableSection.h" |
| |
| namespace blink { |
| |
| // There is a window of opportunity to read |m_rowIndex| before it is set when |
| // inserting the LayoutTableRow or during LayoutTableSection::recalcCells. |
| // This value is used to detect that case. |
| static const unsigned kUnsetRowIndex = 0x7FFFFFFF; |
| static const unsigned kMaxRowIndex = 0x7FFFFFFE; // 2,147,483,646 |
| |
| // LayoutTableRow is used to represent a table row (display: table-row). |
| // |
| // LayoutTableRow is a simple object. The reason is that most operations |
| // have to be coordinated at the LayoutTableSection level and thus are |
| // handled in LayoutTableSection (see e.g. layoutRows). |
| // |
| // The table model prevents any layout overflow on rows (but allow visual |
| // overflow). For row height, it is defined as "the maximum of the row's |
| // computed 'height', the computed 'height' of each cell in the row, and |
| // the minimum height (MIN) required by the cells" (CSS 2.1 - section 17.5.3). |
| // Note that this means that rows and cells differ from other LayoutObject as |
| // they will ignore 'height' in some situation (when other LayoutObject just |
| // allow some layout overflow to occur). |
| // |
| // LayoutTableRow doesn't establish a containing block for the underlying |
| // LayoutTableCells. That's why it inherits from LayoutTableBoxComponent and not |
| // LayoutBlock. |
| // One oddity is that LayoutTableRow doesn't establish a new coordinate system |
| // for its children. LayoutTableCells are positioned with respect to the |
| // enclosing LayoutTableSection (this object's parent()). This particularity is |
| // why functions accumulating offset while walking the tree have to special case |
| // LayoutTableRow (see e.g. PaintInvalidatorContext or |
| // LayoutBox::PositionFromPoint()). |
| // |
| // LayoutTableRow is also positioned with respect to the enclosing |
| // LayoutTableSection. See LayoutTableSection::layoutRows() for the placement |
| // logic. |
| class CORE_EXPORT LayoutTableRow final : public LayoutTableBoxComponent { |
| public: |
| explicit LayoutTableRow(Element*); |
| |
| LayoutTableCell* FirstCell() const; |
| LayoutTableCell* LastCell() const; |
| |
| LayoutTableRow* PreviousRow() const; |
| LayoutTableRow* NextRow() const; |
| |
| LayoutTableSection* Section() const { return ToLayoutTableSection(Parent()); } |
| LayoutTable* Table() const final { return ToLayoutTable(Parent()->Parent()); } |
| |
| static LayoutTableRow* CreateAnonymous(Document*); |
| static LayoutTableRow* CreateAnonymousWithParent(const LayoutObject*); |
| LayoutBox* CreateAnonymousBoxWithSameTypeAs( |
| const LayoutObject* parent) const override { |
| return CreateAnonymousWithParent(parent); |
| } |
| |
| void SetRowIndex(unsigned row_index) { |
| CHECK_LE(row_index, kMaxRowIndex); |
| row_index_ = row_index; |
| } |
| |
| bool RowIndexWasSet() const { return row_index_ != kUnsetRowIndex; } |
| unsigned RowIndex() const { |
| DCHECK(RowIndexWasSet()); |
| DCHECK( |
| !Section() || |
| !Section() |
| ->NeedsCellRecalc()); // index may be bogus if cells need recalc. |
| return row_index_; |
| } |
| |
| bool NodeAtPoint(HitTestResult&, |
| const HitTestLocation& location_in_container, |
| const LayoutPoint& accumulated_offset, |
| HitTestAction) override; |
| |
| PaginationBreakability GetPaginationBreakability() const final; |
| |
| void ComputeOverflow(); |
| |
| const char* GetName() const override { return "LayoutTableRow"; } |
| |
| // Whether a row has opaque background depends on many factors, e.g. border |
| // spacing, border collapsing, missing cells, etc. |
| // For simplicity, just conservatively assume all table rows are not opaque. |
| bool ForegroundIsKnownToBeOpaqueInRect(const LayoutRect&, |
| unsigned) const override { |
| return false; |
| } |
| bool BackgroundIsKnownToBeOpaqueInRect(const LayoutRect&) const override { |
| return false; |
| } |
| bool PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const override; |
| |
| private: |
| void AddOverflowFromCell(const LayoutTableCell*); |
| |
| bool IsOfType(LayoutObjectType type) const override { |
| return type == kLayoutObjectTableRow || |
| LayoutTableBoxComponent::IsOfType(type); |
| } |
| |
| void WillBeRemovedFromTree() override; |
| |
| void AddChild(LayoutObject* child, |
| LayoutObject* before_child = nullptr) override; |
| void UpdateLayout() override; |
| |
| PaintLayerType LayerTypeRequired() const override { |
| if (HasTransformRelatedProperty() || HasHiddenBackface() || HasClipPath() || |
| CreatesGroup() || Style()->ShouldCompositeForCurrentAnimations() || |
| IsInFlowPositioned()) |
| return kNormalPaintLayer; |
| |
| if (HasOverflowClip()) |
| return kOverflowClipPaintLayer; |
| |
| return kNoPaintLayer; |
| } |
| |
| void Paint(const PaintInfo&, const LayoutPoint&) const override; |
| |
| void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override; |
| |
| void NextSibling() const = delete; |
| void PreviousSibling() const = delete; |
| |
| // This field should never be read directly. It should be read through |
| // rowIndex() above instead. This is to ensure that we never read this |
| // value before it is set. |
| unsigned row_index_ : 31; |
| }; |
| |
| DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutTableRow, IsTableRow()); |
| |
| inline LayoutTableRow* LayoutTableRow::PreviousRow() const { |
| return ToLayoutTableRow(LayoutObject::PreviousSibling()); |
| } |
| |
| inline LayoutTableRow* LayoutTableRow::NextRow() const { |
| return ToLayoutTableRow(LayoutObject::NextSibling()); |
| } |
| |
| inline LayoutTableRow* LayoutTableSection::FirstRow() const { |
| return ToLayoutTableRow(FirstChild()); |
| } |
| |
| inline LayoutTableRow* LayoutTableSection::LastRow() const { |
| return ToLayoutTableRow(LastChild()); |
| } |
| |
| } // namespace blink |
| |
| #endif // LayoutTableRow_h |