servo: Merge #19659 - style: Move display outside of mako (from CYBAI:display-out-of-mako); r=emilio

This is a sub-PR of #19015
r? emilio

---
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix #19658
- [x] These changes do not require tests

Source-Repo: https://github.com/servo/servo
Source-Revision: 2a139cebacc02b3ae04974e1e5b2b601df5b774c

--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 77c791f1c8ee001deef16ed754ca3200ddcbee77
This commit is contained in:
CYBAI 2018-01-01 12:14:39 -06:00
Родитель 643bbbf5a0
Коммит 2ff1e2200e
5 изменённых файлов: 249 добавлений и 226 удалений

Просмотреть файл

@ -13,229 +13,36 @@
// //
// We allow "display" to apply to placeholders because we need to make the // We allow "display" to apply to placeholders because we need to make the
// placeholder pseudo-element an inline-block in the UA stylesheet in Gecko. // placeholder pseudo-element an inline-block in the UA stylesheet in Gecko.
<%helpers:longhand name="display" ${helpers.predefined_type(
animation_value_type="discrete" "display",
custom_cascade="${product == 'servo'}" "Display",
flags="APPLIES_TO_PLACEHOLDER" "computed::Display::inline()",
spec="https://drafts.csswg.org/css-display/#propdef-display"> initial_specified_value="specified::Display::inline()",
<% animation_value_type="discrete",
values = """inline block inline-block needs_context=False,
table inline-table table-row-group table-header-group table-footer-group custom_cascade= product == 'servo',
table-row table-column-group table-column table-cell table-caption custom_cascade_function="specified::Display::cascade_property_custom",
list-item none flags="APPLIES_TO_PLACEHOLDER",
""".split() spec="https://drafts.csswg.org/css-display/#propdef-display",
webkit_prefixed_values = "flex inline-flex".split() )}
values += webkit_prefixed_values
if product == "gecko":
values += """grid inline-grid ruby ruby-base ruby-base-container
ruby-text ruby-text-container contents flow-root -webkit-box
-webkit-inline-box -moz-box -moz-inline-box -moz-grid -moz-inline-grid
-moz-grid-group -moz-grid-line -moz-stack -moz-inline-stack -moz-deck
-moz-popup -moz-groupbox""".split()
%>
use style_traits::ToCss;
pub mod computed_value { // FIXME(emilio): Listing all the display values here is very unfortunate, we should teach C++ to use the
pub use super::SpecifiedValue as T; // Rust enum directly, or generate the conversions to `StyleDisplay`.
use super::SpecifiedValue as Display; ${helpers.gecko_keyword_conversion(
Keyword('display', """
impl Display { inline block inline-block
/// Returns whether this "display" value is the display of a flex or table inline-table table-row-group table-header-group table-footer-group
/// grid container. table-row table-column-group table-column table-cell table-caption
/// list-item none flex inline-flex grid inline-grid ruby ruby-base ruby-base-container
/// This is used to implement various style fixups. ruby-text ruby-text-container contents flow-root -webkit-box
pub fn is_item_container(&self) -> bool { -webkit-inline-box -moz-box -moz-inline-box -moz-grid -moz-inline-grid
matches!(*self, -moz-grid-group -moz-grid-line -moz-stack -moz-inline-stack -moz-deck
Display::Flex -moz-popup -moz-groupbox
| Display::InlineFlex """,
% if product == "gecko": gecko_enum_prefix='StyleDisplay',
| Display::Grid gecko_strip_moz_prefix=False),
| Display::InlineGrid type="::values::specified::Display"
% endif )}
)
}
/// Returns whether an element with this display type is a line
/// participant, which means it may lay its children on the same
/// line as itself.
pub fn is_line_participant(&self) -> bool {
matches!(*self,
Display::Inline
% if product == "gecko":
| Display::Contents
| Display::Ruby
| Display::RubyBaseContainer
% endif
)
}
/// Whether `new_display` should be ignored, given a previous
/// `old_display` value.
///
/// This is used to ignore `display: -moz-box` declarations after an
/// equivalent `display: -webkit-box` declaration, since the former
/// has a vastly different meaning. See bug 1107378 and bug 1407701.
///
/// FIXME(emilio): This is a pretty decent hack, we should try to
/// remove it.
pub fn should_ignore_parsed_value(
_old_display: Self,
_new_display: Self,
) -> bool {
#[cfg(feature = "gecko")]
{
match (_old_display, _new_display) {
(Display::WebkitBox, Display::MozBox) |
(Display::WebkitInlineBox, Display::MozInlineBox) => {
return true;
}
_ => {},
}
}
return false;
}
/// Returns whether this "display" value is one of the types for
/// ruby.
#[cfg(feature = "gecko")]
pub fn is_ruby_type(&self) -> bool {
matches!(*self,
Display::Ruby |
Display::RubyBase |
Display::RubyText |
Display::RubyBaseContainer |
Display::RubyTextContainer)
}
/// Returns whether this "display" value is a ruby level container.
#[cfg(feature = "gecko")]
pub fn is_ruby_level_container(&self) -> bool {
matches!(*self,
Display::RubyBaseContainer |
Display::RubyTextContainer)
}
/// Convert this display into an equivalent block display.
///
/// Also used for style adjustments.
pub fn equivalent_block_display(&self, _is_root_element: bool) -> Self {
match *self {
// Values that have a corresponding block-outside version.
Display::InlineTable => Display::Table,
Display::InlineFlex => Display::Flex,
% if product == "gecko":
Display::InlineGrid => Display::Grid,
Display::WebkitInlineBox => Display::WebkitBox,
% endif
// Special handling for contents and list-item on the root
// element for Gecko.
% if product == "gecko":
Display::Contents | Display::ListItem if _is_root_element => Display::Block,
% endif
// These are not changed by blockification.
Display::None |
Display::Block |
Display::Flex |
Display::ListItem |
Display::Table => *self,
% if product == "gecko":
Display::Contents |
Display::FlowRoot |
Display::Grid |
Display::WebkitBox => *self,
% endif
// Everything else becomes block.
_ => Display::Block,
}
}
/// Convert this display into an inline-outside display.
///
/// Ideally it should implement spec: https://drafts.csswg.org/css-display/#inlinify
/// but the spec isn't stable enough, so we copy what Gecko does for now.
#[cfg(feature = "gecko")]
pub fn inlinify(&self) -> Self {
match *self {
Display::Block |
Display::FlowRoot => Display::InlineBlock,
Display::Table => Display::InlineTable,
Display::Flex => Display::InlineFlex,
Display::Grid => Display::InlineGrid,
Display::MozBox => Display::MozInlineBox,
Display::MozStack => Display::MozInlineStack,
Display::WebkitBox => Display::WebkitInlineBox,
other => other,
}
}
}
}
// FIXME(emilio): Why does this reinvent the wheel, again?
#[allow(non_camel_case_types)]
#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToComputedValue)]
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
pub enum SpecifiedValue {
% for value in values:
${to_camel_case(value)},
% endfor
}
// TODO(emilio): derive.
impl ToCss for SpecifiedValue {
fn to_css<W>(&self, dest: &mut W) -> ::std::fmt::Result
where W: ::std::fmt::Write,
{
match *self {
% for value in values:
SpecifiedValue::${to_camel_case(value)} => dest.write_str("${value}"),
% endfor
}
}
}
/// The initial display value.
#[inline]
pub fn get_initial_value() -> computed_value::T {
computed_value::T::${to_camel_case(values[0])}
}
/// Parse a display value.
pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>)
-> Result<SpecifiedValue, ParseError<'i>> {
try_match_ident_ignore_ascii_case! { input,
% for value in values:
"${value}" => {
Ok(computed_value::T::${to_camel_case(value)})
},
% endfor
% for value in webkit_prefixed_values:
"-webkit-${value}" => {
Ok(computed_value::T::${to_camel_case(value)})
},
% endfor
}
}
% if product == "servo":
fn cascade_property_custom(_declaration: &PropertyDeclaration,
context: &mut computed::Context) {
longhands::_servo_display_for_hypothetical_box::derive_from_display(context);
longhands::_servo_text_decorations_in_effect::derive_from_display(context);
}
% endif
${helpers.gecko_keyword_conversion(Keyword('display', ' '.join(values),
gecko_enum_prefix='StyleDisplay',
gecko_strip_moz_prefix=False))}
</%helpers:longhand>
${helpers.single_keyword("-moz-top-layer", "none top", ${helpers.single_keyword("-moz-top-layer", "none top",
gecko_constant_prefix="NS_STYLE_TOP_LAYER", gecko_constant_prefix="NS_STYLE_TOP_LAYER",

Просмотреть файл

@ -9,8 +9,8 @@ use values::computed::length::LengthOrPercentage;
use values::generics::box_::AnimationIterationCount as GenericAnimationIterationCount; use values::generics::box_::AnimationIterationCount as GenericAnimationIterationCount;
use values::generics::box_::VerticalAlign as GenericVerticalAlign; use values::generics::box_::VerticalAlign as GenericVerticalAlign;
pub use values::specified::box_::{AnimationName, OverflowClipBox, OverscrollBehavior}; pub use values::specified::box_::{AnimationName, Display, OverflowClipBox};
pub use values::specified::box_::{ScrollSnapType, TouchAction, WillChange}; pub use values::specified::box_::{OverscrollBehavior, ScrollSnapType, TouchAction, WillChange};
/// A computed value for the `vertical-align` property. /// A computed value for the `vertical-align` property.
pub type VerticalAlign = GenericVerticalAlign<LengthOrPercentage>; pub type VerticalAlign = GenericVerticalAlign<LengthOrPercentage>;

Просмотреть файл

@ -40,7 +40,7 @@ pub use self::font::{FontSize, FontSizeAdjust, FontSynthesis, FontWeight, FontVa
pub use self::font::{FontFamily, FontLanguageOverride, FontVariantSettings, FontVariantEastAsian}; pub use self::font::{FontFamily, FontLanguageOverride, FontVariantSettings, FontVariantEastAsian};
pub use self::font::{FontVariantLigatures, FontVariantNumeric, FontFeatureSettings}; pub use self::font::{FontVariantLigatures, FontVariantNumeric, FontFeatureSettings};
pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, XTextZoom, XLang}; pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, XTextZoom, XLang};
pub use self::box_::{AnimationIterationCount, AnimationName, OverscrollBehavior}; pub use self::box_::{AnimationIterationCount, AnimationName, Display, OverscrollBehavior};
pub use self::box_::{OverflowClipBox, ScrollSnapType, TouchAction, VerticalAlign, WillChange}; pub use self::box_::{OverflowClipBox, ScrollSnapType, TouchAction, VerticalAlign, WillChange};
pub use self::color::{Color, ColorPropertyValue, RGBAColor}; pub use self::color::{Color, ColorPropertyValue, RGBAColor};
pub use self::effects::{BoxShadow, Filter, SimpleShadow}; pub use self::effects::{BoxShadow, Filter, SimpleShadow};

Просмотреть файл

@ -7,15 +7,231 @@
use Atom; use Atom;
use cssparser::Parser; use cssparser::Parser;
use parser::{Parse, ParserContext}; use parser::{Parse, ParserContext};
#[cfg(feature = "servo")]
use properties::{longhands, PropertyDeclaration};
use std::fmt; use std::fmt;
use style_traits::{ParseError, ToCss}; use style_traits::{ParseError, ToCss};
use values::CustomIdent; use values::CustomIdent;
use values::KeyframesName; use values::KeyframesName;
#[cfg(feature = "servo")]
use values::computed::Context;
use values::generics::box_::AnimationIterationCount as GenericAnimationIterationCount; use values::generics::box_::AnimationIterationCount as GenericAnimationIterationCount;
use values::generics::box_::VerticalAlign as GenericVerticalAlign; use values::generics::box_::VerticalAlign as GenericVerticalAlign;
use values::specified::{AllowQuirks, Number}; use values::specified::{AllowQuirks, Number};
use values::specified::length::LengthOrPercentage; use values::specified::length::LengthOrPercentage;
#[allow(missing_docs)]
#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, ToComputedValue, ToCss)]
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
/// Defines an elements display type, which consists of
/// the two basic qualities of how an element generates boxes
/// <https://drafts.csswg.org/css-display/#propdef-display>
pub enum Display {
Inline, Block, InlineBlock,
Table, InlineTable, TableRowGroup, TableHeaderGroup,
TableFooterGroup, TableRow, TableColumnGroup,
TableColumn, TableCell, TableCaption, ListItem, None,
#[parse(aliases = "-webkit-flex")]
Flex,
#[parse(aliases = "-webkit-inline-flex")]
InlineFlex,
#[cfg(feature = "gecko")]
Grid,
#[cfg(feature = "gecko")]
InlineGrid,
#[cfg(feature = "gecko")]
Ruby,
#[cfg(feature = "gecko")]
RubyBase,
#[cfg(feature = "gecko")]
RubyBaseContainer,
#[cfg(feature = "gecko")]
RubyText,
#[cfg(feature = "gecko")]
RubyTextContainer,
#[cfg(feature = "gecko")]
Contents,
#[cfg(feature = "gecko")]
FlowRoot,
#[cfg(feature = "gecko")]
WebkitBox,
#[cfg(feature = "gecko")]
WebkitInlineBox,
#[cfg(feature = "gecko")]
MozBox,
#[cfg(feature = "gecko")]
MozInlineBox,
#[cfg(feature = "gecko")]
MozGrid,
#[cfg(feature = "gecko")]
MozInlineGrid,
#[cfg(feature = "gecko")]
MozGridGroup,
#[cfg(feature = "gecko")]
MozGridLine,
#[cfg(feature = "gecko")]
MozStack,
#[cfg(feature = "gecko")]
MozInlineStack,
#[cfg(feature = "gecko")]
MozDeck,
#[cfg(feature = "gecko")]
MozPopup,
#[cfg(feature = "gecko")]
MozGroupbox,
}
impl Display {
/// The initial display value.
#[inline]
pub fn inline() -> Self {
Display::Inline
}
/// Returns whether this "display" value is the display of a flex or
/// grid container.
///
/// This is used to implement various style fixups.
pub fn is_item_container(&self) -> bool {
match *self {
Display::Flex | Display::InlineFlex => true,
#[cfg(feature = "gecko")]
Display::Grid | Display::InlineGrid => true,
_ => false,
}
}
/// Returns whether an element with this display type is a line
/// participant, which means it may lay its children on the same
/// line as itself.
pub fn is_line_participant(&self) -> bool {
match *self {
Display::Inline => true,
#[cfg(feature = "gecko")]
Display::Contents |
Display::Ruby |
Display::RubyBaseContainer => true,
_ => false,
}
}
/// Whether `new_display` should be ignored, given a previous
/// `old_display` value.
///
/// This is used to ignore `display: -moz-box` declarations after an
/// equivalent `display: -webkit-box` declaration, since the former
/// has a vastly different meaning. See bug 1107378 and bug 1407701.
///
/// FIXME(emilio): This is a pretty decent hack, we should try to
/// remove it.
pub fn should_ignore_parsed_value(
_old_display: Self,
_new_display: Self,
) -> bool {
#[cfg(feature = "gecko")] {
match (_old_display, _new_display) {
(Display::WebkitBox, Display::MozBox) |
(Display::WebkitInlineBox, Display::MozInlineBox) => {
return true;
}
_ => {},
}
}
return false;
}
/// Returns whether this "display" value is one of the types for
/// ruby.
#[cfg(feature = "gecko")]
pub fn is_ruby_type(&self) -> bool {
matches!(*self,
Display::Ruby |
Display::RubyBase |
Display::RubyText |
Display::RubyBaseContainer |
Display::RubyTextContainer
)
}
/// Returns whether this "display" value is a ruby level container.
#[cfg(feature = "gecko")]
pub fn is_ruby_level_container(&self) -> bool {
matches!(*self,
Display::RubyBaseContainer |
Display::RubyTextContainer
)
}
/// Convert this display into an equivalent block display.
///
/// Also used for style adjustments.
pub fn equivalent_block_display(&self, _is_root_element: bool) -> Self {
match *self {
// Values that have a corresponding block-outside version.
Display::InlineTable => Display::Table,
Display::InlineFlex => Display::Flex,
#[cfg(feature = "gecko")]
Display::InlineGrid => Display::Grid,
#[cfg(feature = "gecko")]
Display::WebkitInlineBox => Display::WebkitBox,
// Special handling for contents and list-item on the root
// element for Gecko.
#[cfg(feature = "gecko")]
Display::Contents | Display::ListItem if _is_root_element => Display::Block,
// These are not changed by blockification.
Display::None |
Display::Block |
Display::Flex |
Display::ListItem |
Display::Table => *self,
#[cfg(feature = "gecko")]
Display::Contents |
Display::FlowRoot |
Display::Grid |
Display::WebkitBox => *self,
// Everything else becomes block.
_ => Display::Block,
}
}
/// Convert this display into an inline-outside display.
///
/// Ideally it should implement spec: https://drafts.csswg.org/css-display/#inlinify
/// but the spec isn't stable enough, so we copy what Gecko does for now.
#[cfg(feature = "gecko")]
pub fn inlinify(&self) -> Self {
match *self {
Display::Block |
Display::FlowRoot => Display::InlineBlock,
Display::Table => Display::InlineTable,
Display::Flex => Display::InlineFlex,
Display::Grid => Display::InlineGrid,
Display::MozBox => Display::MozInlineBox,
Display::MozStack => Display::MozInlineStack,
Display::WebkitBox => Display::WebkitInlineBox,
other => other,
}
}
#[cfg(feature = "servo")]
#[inline]
/// Custom cascade for the `display` property in servo
pub fn cascade_property_custom(
_declaration: &PropertyDeclaration,
context: &mut Context
) {
longhands::_servo_display_for_hypothetical_box::derive_from_display(context);
longhands::_servo_text_decorations_in_effect::derive_from_display(context);
}
}
/// A specified value for the `vertical-align` property. /// A specified value for the `vertical-align` property.
pub type VerticalAlign = GenericVerticalAlign<LengthOrPercentage>; pub type VerticalAlign = GenericVerticalAlign<LengthOrPercentage>;

Просмотреть файл

@ -34,7 +34,7 @@ pub use self::font::{FontSize, FontSizeAdjust, FontSynthesis, FontWeight, FontVa
pub use self::font::{FontFamily, FontLanguageOverride, FontVariantSettings, FontVariantEastAsian}; pub use self::font::{FontFamily, FontLanguageOverride, FontVariantSettings, FontVariantEastAsian};
pub use self::font::{FontVariantLigatures, FontVariantNumeric, FontFeatureSettings}; pub use self::font::{FontVariantLigatures, FontVariantNumeric, FontFeatureSettings};
pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, XTextZoom, XLang}; pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, XTextZoom, XLang};
pub use self::box_::{AnimationIterationCount, AnimationName, OverscrollBehavior}; pub use self::box_::{AnimationIterationCount, AnimationName, Display, OverscrollBehavior};
pub use self::box_::{OverflowClipBox, ScrollSnapType, TouchAction, VerticalAlign, WillChange}; pub use self::box_::{OverflowClipBox, ScrollSnapType, TouchAction, VerticalAlign, WillChange};
pub use self::color::{Color, ColorPropertyValue, RGBAColor}; pub use self::color::{Color, ColorPropertyValue, RGBAColor};
pub use self::effects::{BoxShadow, Filter, SimpleShadow}; pub use self::effects::{BoxShadow, Filter, SimpleShadow};