123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- /*
- * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
- #pragma once
- #include <AK/Assertions.h>
- #include <AK/String.h>
- namespace Web::CSS {
- class Display {
- public:
- Display() = default;
- ~Display() = default;
- String to_string() const;
- bool operator==(Display const& other) const
- {
- if (m_type != other.m_type)
- return false;
- switch (m_type) {
- case Type::Box:
- return m_value.box == other.m_value.box;
- case Type::Internal:
- return m_value.internal == other.m_value.internal;
- case Type::OutsideAndInside:
- return m_value.outside_inside.outside == other.m_value.outside_inside.outside
- && m_value.outside_inside.inside == other.m_value.outside_inside.inside
- && m_value.outside_inside.list_item == other.m_value.outside_inside.list_item;
- }
- VERIFY_NOT_REACHED();
- }
- bool operator!=(Display const& other) const { return !(*this == other); }
- enum class Outside {
- Block,
- Inline,
- RunIn,
- };
- enum class Inside {
- Flow,
- FlowRoot,
- Table,
- Flex,
- Grid,
- Ruby,
- };
- enum class Internal {
- TableRowGroup,
- TableHeaderGroup,
- TableFooterGroup,
- TableRow,
- TableCell,
- TableColumnGroup,
- TableColumn,
- TableCaption,
- RubyBase,
- RubyText,
- RubyBaseContainer,
- RubyTextContainer,
- };
- enum class Box {
- Contents,
- None,
- };
- enum class Type {
- OutsideAndInside,
- Internal,
- Box,
- };
- bool is_internal() const { return m_type == Type::Internal; }
- Internal internal() const
- {
- VERIFY(is_internal());
- return m_value.internal;
- }
- bool is_table_column() const { return is_internal() && internal() == Internal::TableColumn; }
- bool is_table_row_group() const { return is_internal() && internal() == Internal::TableRowGroup; }
- bool is_table_header_group() const { return is_internal() && internal() == Internal::TableHeaderGroup; }
- bool is_table_footer_group() const { return is_internal() && internal() == Internal::TableFooterGroup; }
- bool is_table_row() const { return is_internal() && internal() == Internal::TableRow; }
- bool is_table_cell() const { return is_internal() && internal() == Internal::TableCell; }
- bool is_table_column_group() const { return is_internal() && internal() == Internal::TableColumnGroup; }
- bool is_table_caption() const { return is_internal() && internal() == Internal::TableCaption; }
- bool is_none() const { return m_type == Type::Box && m_value.box == Box::None; }
- bool is_contents() const { return m_type == Type::Box && m_value.box == Box::Contents; }
- Type type() const { return m_type; }
- bool it_outside_and_inside() const { return m_type == Type::OutsideAndInside; }
- Outside outside() const
- {
- VERIFY(it_outside_and_inside());
- return m_value.outside_inside.outside;
- }
- bool is_block_outside() const { return it_outside_and_inside() && outside() == Outside::Block; }
- bool is_inline_outside() const { return it_outside_and_inside() && outside() == Outside::Inline; }
- bool is_list_item() const { return it_outside_and_inside() && m_value.outside_inside.list_item == ListItem::Yes; }
- Inside inside() const
- {
- VERIFY(it_outside_and_inside());
- return m_value.outside_inside.inside;
- }
- bool is_flow_inside() const { return it_outside_and_inside() && inside() == Inside::Flow; }
- bool is_flow_root_inside() const { return it_outside_and_inside() && inside() == Inside::FlowRoot; }
- bool is_table_inside() const { return it_outside_and_inside() && inside() == Inside::Table; }
- bool is_flex_inside() const { return it_outside_and_inside() && inside() == Inside::Flex; }
- bool is_grid_inside() const { return it_outside_and_inside() && inside() == Inside::Grid; }
- bool is_ruby_inside() const { return it_outside_and_inside() && inside() == Inside::Ruby; }
- enum class Short {
- None,
- Contents,
- Block,
- FlowRoot,
- Inline,
- InlineBlock,
- RunIn,
- ListItem,
- InlineListItem,
- Flex,
- InlineFlex,
- Grid,
- InlineGrid,
- Ruby,
- BlockRuby,
- Table,
- InlineTable,
- };
- enum class ListItem {
- No,
- Yes,
- };
- static Display from_short(Short short_)
- {
- switch (short_) {
- case Short::None:
- return Display { Box::None };
- case Short::Contents:
- return Display { Box::Contents };
- case Short::Block:
- return Display { Outside::Block, Inside::Flow };
- case Short::FlowRoot:
- return Display { Outside::Block, Inside::FlowRoot };
- case Short::Inline:
- return Display { Outside::Inline, Inside::Flow };
- case Short::InlineBlock:
- return Display { Outside::Inline, Inside::FlowRoot };
- case Short::RunIn:
- return Display { Outside::RunIn, Inside::Flow };
- case Short::ListItem:
- return Display { Outside::Block, Inside::Flow, ListItem::Yes };
- case Short::InlineListItem:
- return Display { Outside::Inline, Inside::Flow, ListItem::Yes };
- case Short::Flex:
- return Display { Outside::Block, Inside::Flex };
- case Short::InlineFlex:
- return Display { Outside::Inline, Inside::Flex };
- case Short::Grid:
- return Display { Outside::Block, Inside::Grid };
- case Short::InlineGrid:
- return Display { Outside::Inline, Inside::Grid };
- case Short::Ruby:
- return Display { Outside::Inline, Inside::Ruby };
- case Short::BlockRuby:
- return Display { Outside::Block, Inside::Ruby };
- case Short::Table:
- return Display { Outside::Block, Inside::Table };
- case Short::InlineTable:
- return Display { Outside::Inline, Inside::Table };
- }
- VERIFY_NOT_REACHED();
- }
- Display(Outside outside, Inside inside)
- : m_type(Type::OutsideAndInside)
- {
- m_value.outside_inside = {
- .outside = outside,
- .inside = inside,
- .list_item = ListItem::No,
- };
- }
- Display(Outside outside, Inside inside, ListItem list_item)
- : m_type(Type::OutsideAndInside)
- {
- m_value.outside_inside = {
- .outside = outside,
- .inside = inside,
- .list_item = list_item,
- };
- }
- explicit Display(Internal internal)
- : m_type(Type::Internal)
- {
- m_value.internal = internal;
- }
- explicit Display(Box box)
- : m_type(Type::Box)
- {
- m_value.box = box;
- }
- private:
- Type m_type {};
- union {
- struct {
- Outside outside;
- Inside inside;
- ListItem list_item;
- } outside_inside;
- Internal internal;
- Box box;
- } m_value {};
- };
- }
|