mirror of
https://github.com/servo/servo.git
synced 2025-06-04 07:35:36 +00:00
* Use 2024 style edition Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Reformat all code Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> --------- Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
140 lines
5.2 KiB
Rust
140 lines
5.2 KiB
Rust
/* 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 https://mozilla.org/MPL/2.0/. */
|
|
|
|
use bitflags::bitflags;
|
|
use script_layout_interface::{FragmentType, combine_id_with_fragment_type};
|
|
use style::dom::OpaqueNode;
|
|
use style::selector_parser::PseudoElement;
|
|
|
|
/// This data structure stores fields that are common to all non-base
|
|
/// Fragment types and should generally be the first member of all
|
|
/// concrete fragments.
|
|
#[derive(Clone, Debug)]
|
|
pub(crate) struct BaseFragment {
|
|
/// A tag which identifies the DOM node and pseudo element of this
|
|
/// Fragment's content. If this fragment isn't related to any DOM
|
|
/// node at all, the tag will be None.
|
|
pub tag: Option<Tag>,
|
|
|
|
/// Flags which various information about this fragment used during
|
|
/// layout.
|
|
pub flags: FragmentFlags,
|
|
}
|
|
|
|
impl BaseFragment {
|
|
pub(crate) fn anonymous() -> Self {
|
|
BaseFragment {
|
|
tag: None,
|
|
flags: FragmentFlags::empty(),
|
|
}
|
|
}
|
|
|
|
/// Returns true if this fragment is non-anonymous and it is for the given
|
|
/// OpaqueNode, regardless of the pseudo element.
|
|
pub(crate) fn is_for_node(&self, node: OpaqueNode) -> bool {
|
|
self.tag.map(|tag| tag.node == node).unwrap_or(false)
|
|
}
|
|
}
|
|
|
|
/// Information necessary to construct a new BaseFragment.
|
|
#[derive(Clone, Copy, Debug)]
|
|
pub(crate) struct BaseFragmentInfo {
|
|
/// The tag to use for the new BaseFragment, if it is not an anonymous Fragment.
|
|
pub tag: Option<Tag>,
|
|
|
|
/// The flags to use for the new BaseFragment.
|
|
pub flags: FragmentFlags,
|
|
}
|
|
|
|
impl BaseFragmentInfo {
|
|
pub(crate) fn new_for_node(node: OpaqueNode) -> Self {
|
|
Self {
|
|
tag: Some(Tag::new(node)),
|
|
flags: FragmentFlags::empty(),
|
|
}
|
|
}
|
|
|
|
pub(crate) fn anonymous() -> Self {
|
|
Self {
|
|
tag: None,
|
|
flags: FragmentFlags::empty(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<BaseFragmentInfo> for BaseFragment {
|
|
fn from(info: BaseFragmentInfo) -> Self {
|
|
Self {
|
|
tag: info.tag,
|
|
flags: info.flags,
|
|
}
|
|
}
|
|
}
|
|
|
|
bitflags! {
|
|
/// Flags used to track various information about a DOM node during layout.
|
|
#[derive(Clone, Copy, Debug)]
|
|
pub(crate) struct FragmentFlags: u8 {
|
|
/// Whether or not the node that created this fragment is a `<body>` element on an HTML document.
|
|
const IS_BODY_ELEMENT_OF_HTML_ELEMENT_ROOT = 1 << 0;
|
|
/// Whether or not the node that created this Fragment is a `<br>` element.
|
|
const IS_BR_ELEMENT = 1 << 1;
|
|
/// Whether or not this Fragment is a flex item.
|
|
const IS_FLEX_ITEM = 1 << 2;
|
|
/// Whether or not this Fragment was created to contain a replaced element or is
|
|
/// a replaced element.
|
|
const IS_REPLACED = 1 << 3;
|
|
/// Whether or not the node that created was a `<table>`, `<th>` or
|
|
/// `<td>` element. Note that this does *not* include elements with
|
|
/// `display: table` or `display: table-cell`.
|
|
const IS_TABLE_TH_OR_TD_ELEMENT = 1 << 4;
|
|
/// Whether or not this Fragment was created to contain a list item marker
|
|
/// with a used value of `list-style-position: outside`.
|
|
const IS_OUTSIDE_LIST_ITEM_MARKER = 1 << 5;
|
|
/// Avoid painting the borders, backgrounds, and drop shadow for this fragment, this is used
|
|
/// for empty table cells when 'empty-cells' is 'hide' and also table wrappers. This flag
|
|
/// doesn't avoid hit-testing nor does it prevent the painting outlines.
|
|
const DO_NOT_PAINT = 1 << 6;
|
|
/// Whether or not the size of this fragment depends on the block size of its container
|
|
/// and the fragment can be a flex item. This flag is used to cache items during flex
|
|
/// layout.
|
|
const SIZE_DEPENDS_ON_BLOCK_CONSTRAINTS_AND_CAN_BE_CHILD_OF_FLEX_ITEM = 1 << 7;
|
|
}
|
|
}
|
|
|
|
/// A data structure used to hold DOM and pseudo-element information about
|
|
/// a particular layout object.
|
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
|
pub(crate) struct Tag {
|
|
pub(crate) node: OpaqueNode,
|
|
pub(crate) pseudo: Option<PseudoElement>,
|
|
}
|
|
|
|
impl Tag {
|
|
/// Create a new Tag for a non-pseudo element. This is mainly used for
|
|
/// matching existing tags, since it does not accept an `info` argument.
|
|
pub(crate) fn new(node: OpaqueNode) -> Self {
|
|
Tag { node, pseudo: None }
|
|
}
|
|
|
|
/// Create a new Tag for a pseudo element. This is mainly used for
|
|
/// matching existing tags, since it does not accept an `info` argument.
|
|
pub(crate) fn new_pseudo(node: OpaqueNode, pseudo: Option<PseudoElement>) -> Self {
|
|
Tag { node, pseudo }
|
|
}
|
|
|
|
/// Returns true if this tag is for a pseudo element.
|
|
pub(crate) fn is_pseudo(&self) -> bool {
|
|
self.pseudo.is_some()
|
|
}
|
|
|
|
pub(crate) fn to_display_list_fragment_id(self) -> u64 {
|
|
let fragment_type = match self.pseudo {
|
|
Some(PseudoElement::Before) => FragmentType::BeforePseudoContent,
|
|
Some(PseudoElement::After) => FragmentType::AfterPseudoContent,
|
|
_ => FragmentType::FragmentBody,
|
|
};
|
|
combine_id_with_fragment_type(self.node.id(), fragment_type)
|
|
}
|
|
}
|