Fix Servo build and unify display representation.

This commit is contained in:
Emilio Cobos Álvarez 2019-08-15 16:42:46 +02:00
parent 4d8fc4b8f7
commit 4752110d53
No known key found for this signature in database
GPG key ID: E1152D0994E4BF8A
6 changed files with 128 additions and 168 deletions

View file

@ -1847,6 +1847,10 @@ where
node.type_id() node.type_id()
); );
// FIXME(emilio): This should look at display-outside and
// display-inside, but there's so much stuff that goes through the
// generic "block" codepath (wrongly).
//
// Switch on display and floatedness. // Switch on display and floatedness.
match (display, float, positioning) { match (display, float, positioning) {
// `display: none` contributes no flow construction result. // `display: none` contributes no flow construction result.
@ -1871,12 +1875,6 @@ where
self.set_flow_construction_result(node, construction_result) self.set_flow_construction_result(node, construction_result)
}, },
// List items contribute their own special flows.
(Display::ListItem, float_value, _) => {
let construction_result = self.build_flow_for_list_item(node, float_value);
self.set_flow_construction_result(node, construction_result)
},
// Inline items that are absolutely-positioned contribute inline fragment construction // Inline items that are absolutely-positioned contribute inline fragment construction
// results with a hypothetical fragment. // results with a hypothetical fragment.
(Display::Inline, _, Position::Absolute) | (Display::Inline, _, Position::Absolute) |
@ -1958,7 +1956,12 @@ where
// properties separately. // properties separately.
(_, float_value, _) => { (_, float_value, _) => {
let float_kind = FloatKind::from_property(float_value); let float_kind = FloatKind::from_property(float_value);
let construction_result = self.build_flow_for_block(node, float_kind); // List items contribute their own special flows.
let construction_result = if display.is_list_item() {
self.build_flow_for_list_item(node, float_value)
} else {
self.build_flow_for_block(node, float_kind)
};
self.set_flow_construction_result(node, construction_result) self.set_flow_construction_result(node, construction_result)
}, },
} }

View file

@ -19,7 +19,6 @@ use crate::traversal::InorderFlowTraversal;
use script_layout_interface::wrapper_traits::PseudoElementType; use script_layout_interface::wrapper_traits::PseudoElementType;
use smallvec::SmallVec; use smallvec::SmallVec;
use std::collections::{HashMap, LinkedList}; use std::collections::{HashMap, LinkedList};
use style::computed_values::display::T as Display;
use style::computed_values::list_style_type::T as ListStyleType; use style::computed_values::list_style_type::T as ListStyleType;
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::selector_parser::RestyleDamage; use style::selector_parser::RestyleDamage;
@ -175,7 +174,7 @@ impl<'a, 'b> ResolveGeneratedContentFragmentMutator<'a, 'b> {
} }
let mut list_style_type = fragment.style().get_list().list_style_type; let mut list_style_type = fragment.style().get_list().list_style_type;
if fragment.style().get_box().display != Display::ListItem { if !fragment.style().get_box().display.is_list_item() {
list_style_type = ListStyleType::None list_style_type = ListStyleType::None
} }
@ -291,7 +290,7 @@ impl<'a, 'b> ResolveGeneratedContentFragmentMutator<'a, 'b> {
fn reset_and_increment_counters_as_necessary(&mut self, fragment: &mut Fragment) { fn reset_and_increment_counters_as_necessary(&mut self, fragment: &mut Fragment) {
let mut list_style_type = fragment.style().get_list().list_style_type; let mut list_style_type = fragment.style().get_list().list_style_type;
if !self.is_block || fragment.style().get_box().display != Display::ListItem { if !self.is_block || !fragment.style().get_box().display.is_list_item() {
list_style_type = ListStyleType::None list_style_type = ListStyleType::None
} }

View file

@ -91,6 +91,7 @@ extern crate servo_config;
extern crate servo_url; extern crate servo_url;
extern crate smallbitvec; extern crate smallbitvec;
extern crate smallvec; extern crate smallvec;
#[cfg(feature = "gecko")]
extern crate static_prefs; extern crate static_prefs;
#[cfg(feature = "servo")] #[cfg(feature = "servo")]
extern crate string_cache; extern crate string_cache;

View file

@ -23,14 +23,14 @@
input: &mut Parser<'i, 't>, input: &mut Parser<'i, 't>,
) -> Result<Longhands, ParseError<'i>> { ) -> Result<Longhands, ParseError<'i>> {
% if engine == "gecko": % if engine == "gecko":
let text_decoration_thickness_enabled =
PropertyId::Longhand(LonghandId::TextDecorationThickness).enabled_for_all_content();
let (mut line, mut style, mut color, mut thickness, mut any) = (None, None, None, None, false); let (mut line, mut style, mut color, mut thickness, mut any) = (None, None, None, None, false);
% else: % else:
let (mut line, mut any) = (None, false); let (mut line, mut any) = (None, false);
% endif % endif
let text_decoration_thickness_enabled =
PropertyId::Longhand(LonghandId::TextDecorationThickness).enabled_for_all_content();
loop { loop {
macro_rules! parse_component { macro_rules! parse_component {
($value:ident, $module:ident) => ( ($value:ident, $module:ident) => (

View file

@ -12,7 +12,6 @@ use crate::properties::longhands::float::computed_value::T as Float;
use crate::properties::longhands::overflow_x::computed_value::T as Overflow; use crate::properties::longhands::overflow_x::computed_value::T as Overflow;
use crate::properties::longhands::position::computed_value::T as Position; use crate::properties::longhands::position::computed_value::T as Position;
use crate::properties::{self, ComputedValues, StyleBuilder}; use crate::properties::{self, ComputedValues, StyleBuilder};
#[cfg(feature = "gecko")]
use crate::values::specified::box_::DisplayInside; use crate::values::specified::box_::DisplayInside;
use app_units::Au; use app_units::Au;
@ -206,7 +205,6 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
blockify_if!(self.style.floated()); blockify_if!(self.style.floated());
blockify_if!(self.style.out_of_flow_positioned()); blockify_if!(self.style.out_of_flow_positioned());
#[cfg(feature = "gecko")]
blockify_if!( blockify_if!(
self.style.pseudo.map_or(false, |p| p.is_marker()) && self.style.pseudo.map_or(false, |p| p.is_marker()) &&
self.style.get_parent_list().clone_list_style_position() == self.style.get_parent_list().clone_list_style_position() ==

View file

@ -34,25 +34,11 @@ fn moz_box_display_values_enabled(context: &ParserContext) -> bool {
static_prefs::pref!("layout.css.xul-box-display-values.content.enabled") static_prefs::pref!("layout.css.xul-box-display-values.content.enabled")
} }
#[cfg(feature = "servo-layout-2013")]
fn parse_unimplemented_in_servo_2020(_context: &ParserContext) -> bool {
true
}
#[cfg(feature = "servo-layout-2020")]
fn parse_unimplemented_in_servo_2020(_context: &ParserContext) -> bool {
servo_config::prefs::pref_map()
.get("layout.2020.unimplemented")
.as_bool()
.unwrap_or(false)
}
/// Defines an elements display type, which consists of /// Defines an elements display type, which consists of
/// the two basic qualities of how an element generates boxes /// the two basic qualities of how an element generates boxes
/// <https://drafts.csswg.org/css-display/#propdef-display> /// <https://drafts.csswg.org/css-display/#propdef-display>
#[allow(missing_docs)] #[allow(missing_docs)]
#[derive(Clone, Copy, Debug, Eq, FromPrimitive, Hash, MallocSizeOf, PartialEq, ToCss, ToShmem)] #[derive(Clone, Copy, Debug, Eq, FromPrimitive, Hash, MallocSizeOf, PartialEq, ToCss, ToShmem)]
#[cfg(feature = "gecko")]
#[repr(u8)] #[repr(u8)]
pub enum DisplayOutside { pub enum DisplayOutside {
None = 0, None = 0,
@ -60,21 +46,24 @@ pub enum DisplayOutside {
Block, Block,
TableCaption, TableCaption,
InternalTable, InternalTable,
#[cfg(feature = "gecko")]
InternalRuby, InternalRuby,
#[cfg(feature = "gecko")]
XUL, XUL,
} }
#[allow(missing_docs)] #[allow(missing_docs)]
#[derive(Clone, Copy, Debug, Eq, FromPrimitive, Hash, MallocSizeOf, PartialEq, ToCss, ToShmem)] #[derive(Clone, Copy, Debug, Eq, FromPrimitive, Hash, MallocSizeOf, PartialEq, ToCss, ToShmem)]
#[cfg(feature = "gecko")]
#[repr(u8)] #[repr(u8)]
pub enum DisplayInside { pub enum DisplayInside {
None = 0, None = 0,
#[cfg(feature = "gecko")]
Contents, Contents,
Block, Block,
FlowRoot, FlowRoot,
Inline, Inline,
Flex, Flex,
#[cfg(feature = "gecko")]
Grid, Grid,
Table, Table,
TableRowGroup, TableRowGroup,
@ -84,22 +73,39 @@ pub enum DisplayInside {
TableFooterGroup, TableFooterGroup,
TableRow, TableRow,
TableCell, TableCell,
#[cfg(feature = "gecko")]
Ruby, Ruby,
#[cfg(feature = "gecko")]
RubyBase, RubyBase,
#[cfg(feature = "gecko")]
RubyBaseContainer, RubyBaseContainer,
#[cfg(feature = "gecko")]
RubyText, RubyText,
#[cfg(feature = "gecko")]
RubyTextContainer, RubyTextContainer,
#[cfg(feature = "gecko")]
WebkitBox, WebkitBox,
#[cfg(feature = "gecko")]
MozBox, MozBox,
#[cfg(feature = "gecko")]
MozInlineBox, MozInlineBox,
#[cfg(feature = "gecko")]
MozGrid, MozGrid,
#[cfg(feature = "gecko")]
MozInlineGrid, MozInlineGrid,
#[cfg(feature = "gecko")]
MozGridGroup, MozGridGroup,
#[cfg(feature = "gecko")]
MozGridLine, MozGridLine,
#[cfg(feature = "gecko")]
MozStack, MozStack,
#[cfg(feature = "gecko")]
MozInlineStack, MozInlineStack,
#[cfg(feature = "gecko")]
MozDeck, MozDeck,
#[cfg(feature = "gecko")]
MozGroupbox, MozGroupbox,
#[cfg(feature = "gecko")]
MozPopup, MozPopup,
Flow, // only used for parsing, not computed value Flow, // only used for parsing, not computed value
} }
@ -118,14 +124,12 @@ pub enum DisplayInside {
ToResolvedValue, ToResolvedValue,
ToShmem, ToShmem,
)] )]
#[cfg(feature = "gecko")]
#[repr(transparent)] #[repr(transparent)]
pub struct Display(u16); pub struct Display(u16);
/// Gecko-only impl block for Display (shared stuff later in this file): /// Gecko-only impl block for Display (shared stuff later in this file):
#[allow(missing_docs)] #[allow(missing_docs)]
#[allow(non_upper_case_globals)] #[allow(non_upper_case_globals)]
#[cfg(feature = "gecko")]
impl Display { impl Display {
// Our u16 bits are used as follows: LOOOOOOOIIIIIIII // Our u16 bits are used as follows: LOOOOOOOIIIIIIII
const LIST_ITEM_BIT: u16 = 0x8000; //^ const LIST_ITEM_BIT: u16 = 0x8000; //^
@ -134,23 +138,28 @@ impl Display {
/// https://drafts.csswg.org/css-display/#the-display-properties /// https://drafts.csswg.org/css-display/#the-display-properties
pub const None: Self = Self::new(DisplayOutside::None, DisplayInside::None); pub const None: Self = Self::new(DisplayOutside::None, DisplayInside::None);
#[cfg(feature = "gecko")]
pub const Contents: Self = Self::new(DisplayOutside::None, DisplayInside::Contents); pub const Contents: Self = Self::new(DisplayOutside::None, DisplayInside::Contents);
pub const Inline: Self = Self::new(DisplayOutside::Inline, DisplayInside::Inline); pub const Inline: Self = Self::new(DisplayOutside::Inline, DisplayInside::Inline);
pub const InlineBlock: Self = Self::new(DisplayOutside::Inline, DisplayInside::FlowRoot); pub const InlineBlock: Self = Self::new(DisplayOutside::Inline, DisplayInside::FlowRoot);
pub const Block: Self = Self::new(DisplayOutside::Block, DisplayInside::Block); pub const Block: Self = Self::new(DisplayOutside::Block, DisplayInside::Block);
#[cfg(feature = "gecko")]
pub const FlowRoot: Self = Self::new(DisplayOutside::Block, DisplayInside::FlowRoot); pub const FlowRoot: Self = Self::new(DisplayOutside::Block, DisplayInside::FlowRoot);
pub const Flex: Self = Self::new(DisplayOutside::Block, DisplayInside::Flex); pub const Flex: Self = Self::new(DisplayOutside::Block, DisplayInside::Flex);
pub const InlineFlex: Self = Self::new(DisplayOutside::Inline, DisplayInside::Flex); pub const InlineFlex: Self = Self::new(DisplayOutside::Inline, DisplayInside::Flex);
#[cfg(feature = "gecko")]
pub const Grid: Self = Self::new(DisplayOutside::Block, DisplayInside::Grid); pub const Grid: Self = Self::new(DisplayOutside::Block, DisplayInside::Grid);
#[cfg(feature = "gecko")]
pub const InlineGrid: Self = Self::new(DisplayOutside::Inline, DisplayInside::Grid); pub const InlineGrid: Self = Self::new(DisplayOutside::Inline, DisplayInside::Grid);
pub const Table: Self = Self::new(DisplayOutside::Block, DisplayInside::Table); pub const Table: Self = Self::new(DisplayOutside::Block, DisplayInside::Table);
pub const InlineTable: Self = Self::new(DisplayOutside::Inline, DisplayInside::Table); pub const InlineTable: Self = Self::new(DisplayOutside::Inline, DisplayInside::Table);
pub const TableCaption: Self = Self::new(DisplayOutside::TableCaption, DisplayInside::Block); pub const TableCaption: Self = Self::new(DisplayOutside::TableCaption, DisplayInside::Block);
#[cfg(feature = "gecko")]
pub const Ruby: Self = Self::new(DisplayOutside::Inline, DisplayInside::Ruby); pub const Ruby: Self = Self::new(DisplayOutside::Inline, DisplayInside::Ruby);
#[cfg(feature = "gecko")]
pub const WebkitBox: Self = Self::new(DisplayOutside::Block, DisplayInside::WebkitBox); pub const WebkitBox: Self = Self::new(DisplayOutside::Block, DisplayInside::WebkitBox);
#[cfg(feature = "gecko")]
pub const WebkitInlineBox: Self = Self::new(DisplayOutside::Inline, DisplayInside::WebkitBox); pub const WebkitInlineBox: Self = Self::new(DisplayOutside::Inline, DisplayInside::WebkitBox);
pub const ListItem: Self = Self::new_list_item(DisplayOutside::Block, DisplayInside::Block);
/// Internal table boxes. /// Internal table boxes.
pub const TableRowGroup: Self = pub const TableRowGroup: Self =
Self::new(DisplayOutside::InternalTable, DisplayInside::TableRowGroup); Self::new(DisplayOutside::InternalTable, DisplayInside::TableRowGroup);
@ -169,31 +178,47 @@ impl Display {
DisplayInside::TableColumnGroup, DisplayInside::TableColumnGroup,
); );
pub const TableRow: Self = Self::new(DisplayOutside::InternalTable, DisplayInside::TableRow); pub const TableRow: Self = Self::new(DisplayOutside::InternalTable, DisplayInside::TableRow);
pub const TableCell: Self = Self::new(DisplayOutside::InternalTable, DisplayInside::TableCell); pub const TableCell: Self = Self::new(DisplayOutside::InternalTable, DisplayInside::TableCell);
/// Internal ruby boxes. /// Internal ruby boxes.
#[cfg(feature = "gecko")]
pub const RubyBase: Self = Self::new(DisplayOutside::InternalRuby, DisplayInside::RubyBase); pub const RubyBase: Self = Self::new(DisplayOutside::InternalRuby, DisplayInside::RubyBase);
#[cfg(feature = "gecko")]
pub const RubyBaseContainer: Self = Self::new( pub const RubyBaseContainer: Self = Self::new(
DisplayOutside::InternalRuby, DisplayOutside::InternalRuby,
DisplayInside::RubyBaseContainer, DisplayInside::RubyBaseContainer,
); );
#[cfg(feature = "gecko")]
pub const RubyText: Self = Self::new(DisplayOutside::InternalRuby, DisplayInside::RubyText); pub const RubyText: Self = Self::new(DisplayOutside::InternalRuby, DisplayInside::RubyText);
#[cfg(feature = "gecko")]
pub const RubyTextContainer: Self = Self::new( pub const RubyTextContainer: Self = Self::new(
DisplayOutside::InternalRuby, DisplayOutside::InternalRuby,
DisplayInside::RubyTextContainer, DisplayInside::RubyTextContainer,
); );
/// XUL boxes. /// XUL boxes.
#[cfg(feature = "gecko")]
pub const MozBox: Self = Self::new(DisplayOutside::XUL, DisplayInside::MozBox); pub const MozBox: Self = Self::new(DisplayOutside::XUL, DisplayInside::MozBox);
#[cfg(feature = "gecko")]
pub const MozInlineBox: Self = Self::new(DisplayOutside::XUL, DisplayInside::MozInlineBox); pub const MozInlineBox: Self = Self::new(DisplayOutside::XUL, DisplayInside::MozInlineBox);
#[cfg(feature = "gecko")]
pub const MozGrid: Self = Self::new(DisplayOutside::XUL, DisplayInside::MozGrid); pub const MozGrid: Self = Self::new(DisplayOutside::XUL, DisplayInside::MozGrid);
#[cfg(feature = "gecko")]
pub const MozInlineGrid: Self = Self::new(DisplayOutside::XUL, DisplayInside::MozInlineGrid); pub const MozInlineGrid: Self = Self::new(DisplayOutside::XUL, DisplayInside::MozInlineGrid);
#[cfg(feature = "gecko")]
pub const MozGridGroup: Self = Self::new(DisplayOutside::XUL, DisplayInside::MozGridGroup); pub const MozGridGroup: Self = Self::new(DisplayOutside::XUL, DisplayInside::MozGridGroup);
#[cfg(feature = "gecko")]
pub const MozGridLine: Self = Self::new(DisplayOutside::XUL, DisplayInside::MozGridLine); pub const MozGridLine: Self = Self::new(DisplayOutside::XUL, DisplayInside::MozGridLine);
#[cfg(feature = "gecko")]
pub const MozStack: Self = Self::new(DisplayOutside::XUL, DisplayInside::MozStack); pub const MozStack: Self = Self::new(DisplayOutside::XUL, DisplayInside::MozStack);
#[cfg(feature = "gecko")]
pub const MozInlineStack: Self = Self::new(DisplayOutside::XUL, DisplayInside::MozInlineStack); pub const MozInlineStack: Self = Self::new(DisplayOutside::XUL, DisplayInside::MozInlineStack);
#[cfg(feature = "gecko")]
pub const MozDeck: Self = Self::new(DisplayOutside::XUL, DisplayInside::MozDeck); pub const MozDeck: Self = Self::new(DisplayOutside::XUL, DisplayInside::MozDeck);
#[cfg(feature = "gecko")]
pub const MozGroupbox: Self = Self::new(DisplayOutside::XUL, DisplayInside::MozGroupbox); pub const MozGroupbox: Self = Self::new(DisplayOutside::XUL, DisplayInside::MozGroupbox);
#[cfg(feature = "gecko")]
pub const MozPopup: Self = Self::new(DisplayOutside::XUL, DisplayInside::MozPopup); pub const MozPopup: Self = Self::new(DisplayOutside::XUL, DisplayInside::MozPopup);
/// Make a raw display value from <display-outside> and <display-inside> values. /// Make a raw display value from <display-outside> and <display-inside> values.
@ -204,13 +229,6 @@ impl Display {
Self(o | i) Self(o | i)
} }
/// Make a list-item display value from <display-outside> and <display-inside>.
#[inline]
const fn new_list_item(outside: DisplayOutside, inside: DisplayInside) -> Self {
let v = Self::new(outside, inside);
Self(v.0 | Self::LIST_ITEM_BIT)
}
/// Make a display enum value from <display-outside> and <display-inside> values. /// Make a display enum value from <display-outside> and <display-inside> values.
/// We store `flow` as a synthetic `block` or `inline` inside-value to simplify /// We store `flow` as a synthetic `block` or `inline` inside-value to simplify
/// our layout code. /// our layout code.
@ -253,86 +271,28 @@ impl Display {
/// Returns whether this `display` value is a ruby level container. /// Returns whether this `display` value is a ruby level container.
pub fn is_ruby_level_container(&self) -> bool { pub fn is_ruby_level_container(&self) -> bool {
matches!( match *self {
*self, #[cfg(feature = "gecko")]
Display::RubyBaseContainer | Display::RubyTextContainer Display::RubyBaseContainer | Display::RubyTextContainer => true,
) _ => false,
}
} }
/// Returns whether this `display` value is one of the types for ruby. /// Returns whether this `display` value is one of the types for ruby.
pub fn is_ruby_type(&self) -> bool { pub fn is_ruby_type(&self) -> bool {
matches!( match self.inside() {
self.inside(), #[cfg(feature = "gecko")]
DisplayInside::Ruby | DisplayInside::Ruby |
DisplayInside::RubyBase | DisplayInside::RubyBase |
DisplayInside::RubyText | DisplayInside::RubyText |
DisplayInside::RubyBaseContainer | DisplayInside::RubyBaseContainer |
DisplayInside::RubyTextContainer DisplayInside::RubyTextContainer => true,
) _ => false,
}
} }
} }
/// Servo version of Display only contains single-keyword values, and isn't
/// using outside/inside values at all.
#[allow(missing_docs)]
#[derive(
Clone,
Copy,
Debug,
Deserialize,
Eq,
FromPrimitive,
Hash,
MallocSizeOf,
Parse,
PartialEq,
Serialize,
SpecifiedValueInfo,
ToComputedValue,
ToCss,
ToResolvedValue,
ToShmem,
)]
#[cfg(not(feature = "gecko"))]
#[repr(u8)]
pub enum Display {
None = 0,
Block,
Inline,
#[parse(condition = "parse_unimplemented_in_servo_2020")]
InlineBlock,
#[cfg(feature = "servo-layout-2013")]
ListItem,
#[cfg(feature = "servo-layout-2013")]
Table,
#[cfg(feature = "servo-layout-2013")]
InlineTable,
#[cfg(feature = "servo-layout-2013")]
TableRowGroup,
#[cfg(feature = "servo-layout-2013")]
TableColumn,
#[cfg(feature = "servo-layout-2013")]
TableColumnGroup,
#[cfg(feature = "servo-layout-2013")]
TableHeaderGroup,
#[cfg(feature = "servo-layout-2013")]
TableFooterGroup,
#[cfg(feature = "servo-layout-2013")]
TableRow,
#[cfg(feature = "servo-layout-2013")]
TableCell,
#[cfg(feature = "servo-layout-2013")]
TableCaption,
#[cfg(feature = "servo-layout-2013")]
#[parse(aliases = "-webkit-flex")]
Flex,
#[cfg(feature = "servo-layout-2013")]
#[parse(aliases = "-webkit-inline-flex")]
InlineFlex,
}
/// Shared Display impl for both Gecko and Servo. /// Shared Display impl for both Gecko and Servo.
#[allow(missing_docs)]
#[allow(non_upper_case_globals)] #[allow(non_upper_case_globals)]
impl Display { impl Display {
/// The initial display value. /// The initial display value.
@ -347,7 +307,6 @@ impl Display {
pub fn is_atomic_inline_level(&self) -> bool { pub fn is_atomic_inline_level(&self) -> bool {
match *self { match *self {
Display::InlineBlock => true, Display::InlineBlock => true,
#[cfg(feature = "servo-layout-2013")]
Display::InlineFlex | Display::InlineTable => true, Display::InlineFlex | Display::InlineTable => true,
_ => false, _ => false,
} }
@ -358,20 +317,11 @@ impl Display {
/// ///
/// This is used to implement various style fixups. /// This is used to implement various style fixups.
pub fn is_item_container(&self) -> bool { pub fn is_item_container(&self) -> bool {
#[cfg(feature = "gecko")] match self.inside() {
{ DisplayInside::Flex => true,
match self.inside() { #[cfg(feature = "gecko")]
DisplayInside::Flex | DisplayInside::Grid => true, DisplayInside::Grid => true,
_ => false, _ => false,
}
}
#[cfg(not(feature = "gecko"))]
{
match *self {
#[cfg(feature = "servo-layout-2013")]
Display::Flex | Display::InlineFlex => true,
_ => false,
}
} }
} }
@ -394,35 +344,20 @@ impl Display {
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
{ {
// Special handling for `contents` and `list-item`s on the root element. // Special handling for `contents` and `list-item`s on the root element.
if _is_root_element && (*self == Display::Contents || self.is_list_item()) { if _is_root_element && (self.is_contents() || self.is_list_item()) {
return Display::Block; return Display::Block;
} }
match self.outside() {
DisplayOutside::Inline => {
let inside = match self.inside() {
DisplayInside::Inline | DisplayInside::FlowRoot => DisplayInside::Block,
inside => inside,
};
Display::from3(DisplayOutside::Block, inside, self.is_list_item())
},
DisplayOutside::Block | DisplayOutside::None => *self,
_ => Display::Block,
}
} }
#[cfg(not(feature = "gecko"))]
match *self {
// Values that have a corresponding block-outside version.
#[cfg(feature = "servo-layout-2013")]
Display::InlineTable => Display::Table,
#[cfg(feature = "servo-layout-2013")]
Display::InlineFlex => Display::Flex,
// These are not changed by blockification. match self.outside() {
Display::None | Display::Block => *self, DisplayOutside::Inline => {
#[cfg(feature = "servo-layout-2013")] let inside = match self.inside() {
Display::Flex | Display::ListItem | Display::Table => *self, DisplayInside::Inline | DisplayInside::FlowRoot => DisplayInside::Block,
inside => inside,
// Everything else becomes block. };
Display::from3(DisplayOutside::Block, inside, self.is_list_item())
},
DisplayOutside::Block | DisplayOutside::None => *self,
_ => Display::Block, _ => Display::Block,
} }
} }
@ -439,6 +374,7 @@ impl Display {
}; };
Display::from3(DisplayOutside::Inline, inside, self.is_list_item()) Display::from3(DisplayOutside::Inline, inside, self.is_list_item())
}, },
#[cfg(feature = "gecko")]
DisplayOutside::XUL => match self.inside() { DisplayOutside::XUL => match self.inside() {
DisplayInside::MozBox => Display::MozInlineBox, DisplayInside::MozBox => Display::MozInlineBox,
DisplayInside::MozStack => Display::MozInlineStack, DisplayInside::MozStack => Display::MozInlineStack,
@ -465,7 +401,6 @@ impl Display {
} }
} }
#[cfg(feature = "gecko")]
impl ToCss for Display { impl ToCss for Display {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where where
@ -484,19 +419,24 @@ impl ToCss for Display {
match *self { match *self {
Display::Block | Display::Inline => outside.to_css(dest), Display::Block | Display::Inline => outside.to_css(dest),
Display::InlineBlock => dest.write_str("inline-block"), Display::InlineBlock => dest.write_str("inline-block"),
#[cfg(feature = "gecko")]
Display::WebkitInlineBox => dest.write_str("-webkit-inline-box"), Display::WebkitInlineBox => dest.write_str("-webkit-inline-box"),
#[cfg(feature = "gecko")]
Display::MozInlineBox => dest.write_str("-moz-inline-box"), Display::MozInlineBox => dest.write_str("-moz-inline-box"),
#[cfg(feature = "gecko")]
Display::MozInlineGrid => dest.write_str("-moz-inline-grid"), Display::MozInlineGrid => dest.write_str("-moz-inline-grid"),
#[cfg(feature = "gecko")]
Display::MozInlineStack => dest.write_str("-moz-inline-stack"), Display::MozInlineStack => dest.write_str("-moz-inline-stack"),
Display::TableCaption => dest.write_str("table-caption"), Display::TableCaption => dest.write_str("table-caption"),
Display::ListItem => dest.write_str("list-item"),
_ => match (outside, inside) { _ => match (outside, inside) {
#[cfg(feature = "gecko")]
(DisplayOutside::Inline, DisplayInside::Grid) => dest.write_str("inline-grid"),
(DisplayOutside::Inline, DisplayInside::Flex) | (DisplayOutside::Inline, DisplayInside::Flex) |
(DisplayOutside::Inline, DisplayInside::Grid) |
(DisplayOutside::Inline, DisplayInside::Table) => { (DisplayOutside::Inline, DisplayInside::Table) => {
dest.write_str("inline-")?; dest.write_str("inline-")?;
inside.to_css(dest) inside.to_css(dest)
}, },
#[cfg(feature = "gecko")]
(DisplayOutside::Block, DisplayInside::Ruby) => dest.write_str("block ruby"), (DisplayOutside::Block, DisplayInside::Ruby) => dest.write_str("block ruby"),
(_, inside) => { (_, inside) => {
if self.is_list_item() { if self.is_list_item() {
@ -520,23 +460,24 @@ impl ToCss for Display {
/// <display-inside> = flow | flow-root | table | flex | grid | ruby /// <display-inside> = flow | flow-root | table | flex | grid | ruby
/// https://drafts.csswg.org/css-display/#typedef-display-inside /// https://drafts.csswg.org/css-display/#typedef-display-inside
#[cfg(feature = "gecko")]
fn parse_display_inside<'i, 't>( fn parse_display_inside<'i, 't>(
input: &mut Parser<'i, 't>, input: &mut Parser<'i, 't>,
) -> Result<DisplayInside, ParseError<'i>> { ) -> Result<DisplayInside, ParseError<'i>> {
Ok(try_match_ident_ignore_ascii_case! { input, Ok(try_match_ident_ignore_ascii_case! { input,
"flow" => DisplayInside::Flow, "flow" => DisplayInside::Flow,
#[cfg(feature = "gecko")]
"flow-root" => DisplayInside::FlowRoot, "flow-root" => DisplayInside::FlowRoot,
"table" => DisplayInside::Table, "table" => DisplayInside::Table,
"flex" => DisplayInside::Flex, "flex" => DisplayInside::Flex,
#[cfg(feature = "gecko")]
"grid" => DisplayInside::Grid, "grid" => DisplayInside::Grid,
#[cfg(feature = "gecko")]
"ruby" => DisplayInside::Ruby, "ruby" => DisplayInside::Ruby,
}) })
} }
/// <display-outside> = block | inline | run-in /// <display-outside> = block | inline | run-in
/// https://drafts.csswg.org/css-display/#typedef-display-outside /// https://drafts.csswg.org/css-display/#typedef-display-outside
#[cfg(feature = "gecko")]
fn parse_display_outside<'i, 't>( fn parse_display_outside<'i, 't>(
input: &mut Parser<'i, 't>, input: &mut Parser<'i, 't>,
) -> Result<DisplayOutside, ParseError<'i>> { ) -> Result<DisplayOutside, ParseError<'i>> {
@ -549,34 +490,34 @@ fn parse_display_outside<'i, 't>(
} }
/// (flow | flow-root)? /// (flow | flow-root)?
#[cfg(feature = "gecko")]
fn parse_display_inside_for_list_item<'i, 't>( fn parse_display_inside_for_list_item<'i, 't>(
input: &mut Parser<'i, 't>, input: &mut Parser<'i, 't>,
) -> Result<DisplayInside, ParseError<'i>> { ) -> Result<DisplayInside, ParseError<'i>> {
Ok(try_match_ident_ignore_ascii_case! { input, Ok(try_match_ident_ignore_ascii_case! { input,
"flow" => DisplayInside::Flow, "flow" => DisplayInside::Flow,
#[cfg(feature = "gecko")]
"flow-root" => DisplayInside::FlowRoot, "flow-root" => DisplayInside::FlowRoot,
}) })
} }
/// Test a <display-inside> Result for same values as above. /// Test a <display-inside> Result for same values as above.
#[cfg(feature = "gecko")]
fn is_valid_inside_for_list_item<'i>(inside: &Result<DisplayInside, ParseError<'i>>) -> bool { fn is_valid_inside_for_list_item<'i>(inside: &Result<DisplayInside, ParseError<'i>>) -> bool {
matches!( match inside {
inside, Ok(DisplayInside::Flow) => true,
Ok(DisplayInside::Flow) | Ok(DisplayInside::FlowRoot) #[cfg(feature = "gecko")]
) Ok(DisplayInside::FlowRoot) => true,
_ => false,
}
} }
/// Parse `list-item`. /// Parse `list-item`.
#[cfg(feature = "gecko")]
fn parse_list_item<'i, 't>(input: &mut Parser<'i, 't>) -> Result<(), ParseError<'i>> { fn parse_list_item<'i, 't>(input: &mut Parser<'i, 't>) -> Result<(), ParseError<'i>> {
Ok(try_match_ident_ignore_ascii_case! { input, Ok(try_match_ident_ignore_ascii_case! { input,
"list-item" => (), "list-item" => (),
}) })
} }
#[cfg(feature = "gecko")]
impl Parse for Display { impl Parse for Display {
#[allow(unused)] // `context` isn't used for servo-2020 for now
fn parse<'i, 't>( fn parse<'i, 't>(
context: &ParserContext, context: &ParserContext,
input: &mut Parser<'i, 't>, input: &mut Parser<'i, 't>,
@ -615,6 +556,7 @@ impl Parse for Display {
// "If <display-outside> is omitted, the elements outside display type // "If <display-outside> is omitted, the elements outside display type
// defaults to block — except for ruby, which defaults to inline." // defaults to block — except for ruby, which defaults to inline."
// https://drafts.csswg.org/css-display/#inside-model // https://drafts.csswg.org/css-display/#inside-model
#[cfg(feature = "gecko")]
DisplayInside::Ruby => DisplayOutside::Inline, DisplayInside::Ruby => DisplayOutside::Inline,
_ => DisplayOutside::Block, _ => DisplayOutside::Block,
}); });
@ -624,12 +566,13 @@ impl Parse for Display {
// Now parse the single-keyword `display` values. // Now parse the single-keyword `display` values.
Ok(try_match_ident_ignore_ascii_case! { input, Ok(try_match_ident_ignore_ascii_case! { input,
"none" => Display::None, "none" => Display::None,
#[cfg(feature = "gecko")]
"contents" => Display::Contents, "contents" => Display::Contents,
"inline-block" => Display::InlineBlock, "inline-block" => Display::InlineBlock,
"inline-table" => Display::InlineTable, "inline-table" => Display::InlineTable,
"inline-flex" => Display::InlineFlex,
"-webkit-flex" => Display::Flex, "-webkit-flex" => Display::Flex,
"-webkit-inline-flex" => Display::InlineFlex, "inline-flex" | "-webkit-inline-flex" => Display::InlineFlex,
#[cfg(feature = "gecko")]
"inline-grid" => Display::InlineGrid, "inline-grid" => Display::InlineGrid,
"table-caption" => Display::TableCaption, "table-caption" => Display::TableCaption,
"table-row-group" => Display::TableRowGroup, "table-row-group" => Display::TableRowGroup,
@ -639,28 +582,44 @@ impl Parse for Display {
"table-column-group" => Display::TableColumnGroup, "table-column-group" => Display::TableColumnGroup,
"table-row" => Display::TableRow, "table-row" => Display::TableRow,
"table-cell" => Display::TableCell, "table-cell" => Display::TableCell,
#[cfg(feature = "gecko")]
"ruby-base" => Display::RubyBase, "ruby-base" => Display::RubyBase,
#[cfg(feature = "gecko")]
"ruby-base-container" => Display::RubyBaseContainer, "ruby-base-container" => Display::RubyBaseContainer,
#[cfg(feature = "gecko")]
"ruby-text" => Display::RubyText, "ruby-text" => Display::RubyText,
#[cfg(feature = "gecko")]
"ruby-text-container" => Display::RubyTextContainer, "ruby-text-container" => Display::RubyTextContainer,
#[cfg(feature = "gecko")]
"-webkit-box" => Display::WebkitBox, "-webkit-box" => Display::WebkitBox,
#[cfg(feature = "gecko")]
"-webkit-inline-box" => Display::WebkitInlineBox, "-webkit-inline-box" => Display::WebkitInlineBox,
#[cfg(feature = "gecko")]
"-moz-box" if moz_box_display_values_enabled(context) => Display::MozBox, "-moz-box" if moz_box_display_values_enabled(context) => Display::MozBox,
#[cfg(feature = "gecko")]
"-moz-inline-box" if moz_box_display_values_enabled(context) => Display::MozInlineBox, "-moz-inline-box" if moz_box_display_values_enabled(context) => Display::MozInlineBox,
#[cfg(feature = "gecko")]
"-moz-grid" if moz_display_values_enabled(context) => Display::MozGrid, "-moz-grid" if moz_display_values_enabled(context) => Display::MozGrid,
#[cfg(feature = "gecko")]
"-moz-inline-grid" if moz_display_values_enabled(context) => Display::MozInlineGrid, "-moz-inline-grid" if moz_display_values_enabled(context) => Display::MozInlineGrid,
#[cfg(feature = "gecko")]
"-moz-grid-group" if moz_display_values_enabled(context) => Display::MozGridGroup, "-moz-grid-group" if moz_display_values_enabled(context) => Display::MozGridGroup,
#[cfg(feature = "gecko")]
"-moz-grid-line" if moz_display_values_enabled(context) => Display::MozGridLine, "-moz-grid-line" if moz_display_values_enabled(context) => Display::MozGridLine,
#[cfg(feature = "gecko")]
"-moz-stack" if moz_display_values_enabled(context) => Display::MozStack, "-moz-stack" if moz_display_values_enabled(context) => Display::MozStack,
#[cfg(feature = "gecko")]
"-moz-inline-stack" if moz_display_values_enabled(context) => Display::MozInlineStack, "-moz-inline-stack" if moz_display_values_enabled(context) => Display::MozInlineStack,
#[cfg(feature = "gecko")]
"-moz-deck" if moz_display_values_enabled(context) => Display::MozDeck, "-moz-deck" if moz_display_values_enabled(context) => Display::MozDeck,
#[cfg(feature = "gecko")]
"-moz-groupbox" if moz_display_values_enabled(context) => Display::MozGroupbox, "-moz-groupbox" if moz_display_values_enabled(context) => Display::MozGroupbox,
#[cfg(feature = "gecko")]
"-moz-popup" if moz_display_values_enabled(context) => Display::MozPopup, "-moz-popup" if moz_display_values_enabled(context) => Display::MozPopup,
}) })
} }
} }
#[cfg(feature = "gecko")]
impl SpecifiedValueInfo for Display { impl SpecifiedValueInfo for Display {
fn collect_completion_keywords(f: KeywordsCollectFn) { fn collect_completion_keywords(f: KeywordsCollectFn) {
f(&[ f(&[