chromium/third_party/blink/renderer/core/layout/table/layout_table.h

// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_TABLE_LAYOUT_TABLE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_TABLE_LAYOUT_TABLE_H_

#include "base/dcheck_is_on.h"
#include "base/notreached.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/layout_block.h"
#include "third_party/blink/renderer/core/layout/table/table_layout_algorithm_types.h"

namespace blink {

class LayoutTableSection;
class LayoutTableCell;
class TableBorders;

// LayoutTable is the LayoutObject associated with display: table or
// inline-table.
//
// LayoutTable is the coordinator for determining the overall table structure.
// The reason is that LayoutTableSection children have a local view over what
// their structure is but don't account for other LayoutTableSection. Thus
// LayoutTable helps keep consistency across LayoutTableSection.
//
// LayoutTable expects only 3 types of children:
// - zero or more LayoutTableColumn
// - zero or more LayoutTableCaption
// - zero or more LayoutTableSection
// This is aligned with what HTML5 expects:
// https://html.spec.whatwg.org/C/#the-table-element
// with one difference: we allow more than one caption as we follow what
// CSS expects (https://bugs.webkit.org/show_bug.cgi?id=69773).
// Those expectations are enforced by LayoutTable::AddChild, that wraps
// unknown children into an anonymous LayoutTableSection. This is what the
// "generate missing child wrapper" step in CSS mandates in
// http://www.w3.org/TR/CSS21/tables.html#anonymous-boxes.
//
// LayoutTable assumes a pretty strict structure that is mandated by CSS:
// (note that this structure in HTML is enforced by the HTML5 Parser).
//
//                 LayoutTable
//                 |          |
//    LayoutTableSection    LayoutTableCaption
//                 |
//        LayoutTableRow
//                 |
//       LayoutTableCell
//
// This means that we have to generate some anonymous table wrappers in order to
// satisfy the structure. See again
// http://www.w3.org/TR/CSS21/tables.html#anonymous-boxes.
// The anonymous table wrappers are inserted in LayoutTable::AddChild,
// LayoutTableSection::AddChild, LayoutTableRow::AddChild and
// LayoutObject::AddChild.
//
// Note that this yields to interesting issues in the insertion code. The DOM
// code is unaware of the anonymous LayoutObjects and thus can insert
// LayoutObjects into a different part of the layout tree. An example is:
//
// <!DOCTYPE html>
// <style>
// tablerow { display: table-row; }
// tablecell { display: table-cell; border: 5px solid purple; }
// </style>
// <tablerow id="firstRow">
//     <tablecell>Short first row.</tablecell>
// </tablerow>
// <tablecell id="cell">Long second row, shows the table structure.</tablecell>
//
// The page generates a single anonymous table (LayoutTable) and table row
// group (LayoutTableSection) to wrap the <tablerow> (#firstRow) and an
// anonymous table row (LayoutTableRow) for the second <tablecell>. It is
// possible for JavaScript to insert a new element between these 2 <tablecell>
// (using Node.insertBefore), requiring us to split the anonymous table (or the
// anonymous table row group) in 2. Also note that even though the second
// <tablecell> and <tablerow> are siblings in the DOM tree, they are not in the
// layout tree.
//
// Invalidation: LayoutTable differences from block invalidation:
//
// Cached collapsed borders:
// Table caches collapsed borders as TableBorders.
// TableBorders are stored on Table fragment for painting.
// If TableBorders change, table fragment must be regenerated.
// Any table part that contributes to collapsed borders must invalidate
// cached borders on border change by calling GridBordersChanged.
//
// Cached column constraints:
// Column constraints are used in layout. They must be regenerated
// whenever table geometry changes.
// The validation state is a IsTableColumnsConstraintsDirty flag
// on LayoutObject. They are invalidated inside
// LayoutObject::SetNeeds*Layout.
class CORE_EXPORT LayoutTable : public LayoutBlock {};

// wtf/casting.h helper.
template <>
struct DowncastTraits<LayoutTable> {};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_TABLE_LAYOUT_TABLE_H_