зеркало из https://github.com/mozilla/gecko-dev.git
servo: Merge #19576 - style: Move text-align outside of the mako file (from canaltinova:text-align); r=Manishearth,emilio
I will need this refactoring before my next job. I didn't actually fix the FIXME's along the way. My other PR probably will cover these. --- - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors Source-Repo: https://github.com/servo/servo Source-Revision: a9c17970c19a993920ce1ba2ff9faebd033c52b4 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 8ee32ab5b3c274a73fb1f27fe2a85c78a47ae30d
This commit is contained in:
Родитель
b0146307d8
Коммит
af3cd13ada
|
@ -654,7 +654,7 @@ impl FlowFlags {
|
|||
#[inline]
|
||||
pub fn set_text_align(&mut self, value: TextAlign) {
|
||||
*self = (*self & !FlowFlags::TEXT_ALIGN) |
|
||||
FlowFlags::from_bits(value.to_u32() << TEXT_ALIGN_SHIFT).unwrap();
|
||||
FlowFlags::from_bits((value as u32) << TEXT_ALIGN_SHIFT).unwrap();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
@ -18,7 +18,7 @@ use gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordData, CoordData
|
|||
use std::f32::consts::PI;
|
||||
use stylesheets::{Origin, RulesMutateError};
|
||||
use values::computed::{Angle, CalcLengthOrPercentage, ComputedUrl, Gradient, Image};
|
||||
use values::computed::{Integer, LengthOrPercentage, LengthOrPercentageOrAuto, Percentage};
|
||||
use values::computed::{Integer, LengthOrPercentage, LengthOrPercentageOrAuto, Percentage, TextAlign};
|
||||
use values::generics::box_::VerticalAlign;
|
||||
use values::generics::grid::{TrackListValue, TrackSize};
|
||||
use values::generics::image::{CompatMode, Image as GenericImage, GradientItem};
|
||||
|
@ -995,6 +995,26 @@ impl<L> VerticalAlign<L> {
|
|||
}
|
||||
}
|
||||
|
||||
impl TextAlign {
|
||||
/// Obtain a specified value from a Gecko keyword value
|
||||
///
|
||||
/// Intended for use with presentation attributes, not style structs
|
||||
pub fn from_gecko_keyword(kw: u32) -> Self {
|
||||
match kw {
|
||||
structs::NS_STYLE_TEXT_ALIGN_LEFT => TextAlign::Left,
|
||||
structs::NS_STYLE_TEXT_ALIGN_RIGHT => TextAlign::Right,
|
||||
structs::NS_STYLE_TEXT_ALIGN_CENTER => TextAlign::Center,
|
||||
structs::NS_STYLE_TEXT_ALIGN_JUSTIFY => TextAlign::Justify,
|
||||
structs::NS_STYLE_TEXT_ALIGN_MOZ_LEFT => TextAlign::MozLeft,
|
||||
structs::NS_STYLE_TEXT_ALIGN_MOZ_RIGHT => TextAlign::MozRight,
|
||||
structs::NS_STYLE_TEXT_ALIGN_MOZ_CENTER => TextAlign::MozCenter,
|
||||
structs::NS_STYLE_TEXT_ALIGN_CHAR => TextAlign::Char,
|
||||
structs::NS_STYLE_TEXT_ALIGN_END => TextAlign::End,
|
||||
x => panic!("Found unexpected value in style struct for text-align property: {:?}", x),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert to String from given chars pointer.
|
||||
pub unsafe fn string_from_chars_pointer(p: *const u16) -> String {
|
||||
use std::slice;
|
||||
|
|
|
@ -111,165 +111,12 @@ ${helpers.single_keyword("text-align-last",
|
|||
// TODO make this a shorthand and implement text-align-last/text-align-all
|
||||
//
|
||||
// FIXME(emilio): This can't really be that complicated.
|
||||
<%helpers:longhand name="text-align" animation_value_type="discrete"
|
||||
flags="APPLIES_TO_PLACEHOLDER"
|
||||
spec="https://drafts.csswg.org/css-text/#propdef-text-align">
|
||||
pub use self::computed_value::TextAlign;
|
||||
|
||||
pub mod computed_value {
|
||||
pub use self::TextAlign as T;
|
||||
|
||||
macro_rules! define_text_align {
|
||||
( $( $name: ident ( $string: expr ) => $discriminant: expr, )+ ) => {
|
||||
define_css_keyword_enum! { TextAlign:
|
||||
$(
|
||||
$string => $name,
|
||||
)+
|
||||
}
|
||||
|
||||
impl TextAlign {
|
||||
pub fn to_u32(self) -> u32 {
|
||||
match self {
|
||||
$(
|
||||
T::$name => $discriminant,
|
||||
)+
|
||||
}
|
||||
}
|
||||
pub fn from_u32(discriminant: u32) -> Option<T> {
|
||||
match discriminant {
|
||||
$(
|
||||
$discriminant => Some(T::$name),
|
||||
)+
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// FIXME(emilio): Why reinventing the world?
|
||||
define_text_align! {
|
||||
Start("start") => 0,
|
||||
End("end") => 1,
|
||||
Left("left") => 2,
|
||||
Right("right") => 3,
|
||||
Center("center") => 4,
|
||||
Justify("justify") => 5,
|
||||
% if product == "servo":
|
||||
ServoCenter("-servo-center") => 6,
|
||||
ServoLeft("-servo-left") => 7,
|
||||
ServoRight("-servo-right") => 8,
|
||||
% else:
|
||||
MozCenter("-moz-center") => 6,
|
||||
MozLeft("-moz-left") => 7,
|
||||
MozRight("-moz-right") => 8,
|
||||
Char("char") => 10,
|
||||
% endif
|
||||
}
|
||||
|
||||
${helpers.gecko_keyword_conversion(Keyword('text-align',
|
||||
"""left right center justify -moz-left -moz-right
|
||||
-moz-center char end""",
|
||||
gecko_strip_moz_prefix=False), type="T")}
|
||||
}
|
||||
|
||||
#[inline] pub fn get_initial_value() -> TextAlign {
|
||||
TextAlign::Start
|
||||
}
|
||||
|
||||
|
||||
% if product == "gecko":
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
|
||||
#[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
pub enum SpecifiedValue {
|
||||
Keyword(TextAlign),
|
||||
MatchParent,
|
||||
MozCenterOrInherit,
|
||||
}
|
||||
pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||
-> Result<SpecifiedValue, ParseError<'i>> {
|
||||
// MozCenterOrInherit cannot be parsed, only set directly on th elements
|
||||
if let Ok(key) = input.try(TextAlign::parse) {
|
||||
Ok(SpecifiedValue::Keyword(key))
|
||||
} else {
|
||||
input.expect_ident_matching("match-parent")?;
|
||||
Ok(SpecifiedValue::MatchParent)
|
||||
}
|
||||
}
|
||||
impl ToCss for SpecifiedValue {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
match *self {
|
||||
SpecifiedValue::Keyword(key) => key.to_css(dest),
|
||||
SpecifiedValue::MatchParent => dest.write_str("match-parent"),
|
||||
SpecifiedValue::MozCenterOrInherit => Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SpecifiedValue {
|
||||
pub fn from_gecko_keyword(kw: u32) -> Self {
|
||||
use gecko_bindings::structs::NS_STYLE_TEXT_ALIGN_MATCH_PARENT;
|
||||
if kw == NS_STYLE_TEXT_ALIGN_MATCH_PARENT {
|
||||
SpecifiedValue::MatchParent
|
||||
} else {
|
||||
SpecifiedValue::Keyword(computed_value::T::from_gecko_keyword(kw))
|
||||
}
|
||||
}
|
||||
}
|
||||
impl ToComputedValue for SpecifiedValue {
|
||||
type ComputedValue = TextAlign;
|
||||
|
||||
#[inline]
|
||||
fn to_computed_value(&self, context: &Context) -> TextAlign {
|
||||
match *self {
|
||||
SpecifiedValue::Keyword(key) => key,
|
||||
SpecifiedValue::MatchParent => {
|
||||
// on the root <html> element we should still respect the dir
|
||||
// but the parent dir of that element is LTR even if it's <html dir=rtl>
|
||||
// and will only be RTL if certain prefs have been set.
|
||||
// In that case, the default behavior here will set it to left,
|
||||
// but we want to set it to right -- instead set it to the default (`start`),
|
||||
// which will do the right thing in this case (but not the general case)
|
||||
if context.is_root_element {
|
||||
return get_initial_value();
|
||||
}
|
||||
let parent = context.builder.get_parent_inheritedtext().clone_text_align();
|
||||
let ltr = context.builder.inherited_writing_mode().is_bidi_ltr();
|
||||
match (parent, ltr) {
|
||||
(TextAlign::Start, true) => TextAlign::Left,
|
||||
(TextAlign::Start, false) => TextAlign::Right,
|
||||
(TextAlign::End, true) => TextAlign::Right,
|
||||
(TextAlign::End, false) => TextAlign::Left,
|
||||
_ => parent
|
||||
}
|
||||
}
|
||||
SpecifiedValue::MozCenterOrInherit => {
|
||||
let parent = context.builder.get_parent_inheritedtext().clone_text_align();
|
||||
if parent == TextAlign::Start {
|
||||
TextAlign::Center
|
||||
} else {
|
||||
parent
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_computed_value(computed: &computed_value::T) -> Self {
|
||||
SpecifiedValue::Keyword(*computed)
|
||||
}
|
||||
}
|
||||
% else:
|
||||
pub use self::computed_value::T as SpecifiedValue;
|
||||
add_impls_for_keyword_enum!(SpecifiedValue);
|
||||
pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||
-> Result<SpecifiedValue, ParseError<'i>> {
|
||||
computed_value::T::parse(input)
|
||||
}
|
||||
% endif
|
||||
</%helpers:longhand>
|
||||
${helpers.predefined_type("text-align",
|
||||
"TextAlign",
|
||||
"computed::TextAlign::start()",
|
||||
animation_value_type="discrete",
|
||||
flags="APPLIES_TO_PLACEHOLDER",
|
||||
spec="https://drafts.csswg.org/css-text/#propdef-text-align")}
|
||||
|
||||
${helpers.predefined_type("letter-spacing",
|
||||
"LetterSpacing",
|
||||
|
|
|
@ -60,7 +60,7 @@ pub use self::percentage::Percentage;
|
|||
pub use self::position::{Position, GridAutoFlow, GridTemplateAreas};
|
||||
pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind, SVGStrokeDashArray, SVGWidth};
|
||||
pub use self::table::XSpan;
|
||||
pub use self::text::{InitialLetter, LetterSpacing, LineHeight, TextOverflow, WordSpacing};
|
||||
pub use self::text::{InitialLetter, LetterSpacing, LineHeight, TextAlign, TextOverflow, WordSpacing};
|
||||
pub use self::time::Time;
|
||||
pub use self::transform::{TimingFunction, Transform, TransformOperation, TransformOrigin};
|
||||
pub use self::ui::MozForceBrokenImageIcon;
|
||||
|
|
|
@ -15,6 +15,8 @@ use values::generics::text::LineHeight as GenericLineHeight;
|
|||
use values::generics::text::Spacing;
|
||||
use values::specified::text::{TextOverflowSide, TextDecorationLine};
|
||||
|
||||
pub use values::specified::TextAlignKeyword as TextAlign;
|
||||
|
||||
/// A computed value for the `initial-letter` property.
|
||||
pub type InitialLetter = GenericInitialLetter<CSSFloat, CSSInteger>;
|
||||
|
||||
|
|
|
@ -56,7 +56,8 @@ pub use self::percentage::Percentage;
|
|||
pub use self::position::{Position, PositionComponent, GridAutoFlow, GridTemplateAreas};
|
||||
pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind, SVGStrokeDashArray, SVGWidth};
|
||||
pub use self::table::XSpan;
|
||||
pub use self::text::{InitialLetter, LetterSpacing, LineHeight, TextDecorationLine, TextOverflow, WordSpacing};
|
||||
pub use self::text::{InitialLetter, LetterSpacing, LineHeight, TextDecorationLine};
|
||||
pub use self::text::{TextAlign, TextAlignKeyword, TextOverflow, WordSpacing};
|
||||
pub use self::time::Time;
|
||||
pub use self::transform::{TimingFunction, Transform, TransformOrigin};
|
||||
pub use self::ui::MozForceBrokenImageIcon;
|
||||
|
|
|
@ -10,7 +10,8 @@ use parser::{Parse, ParserContext};
|
|||
use properties::{longhands, PropertyDeclaration};
|
||||
use selectors::parser::SelectorParseErrorKind;
|
||||
#[allow(unused_imports)] use std::ascii::AsciiExt;
|
||||
use style_traits::{ParseError, StyleParseErrorKind};
|
||||
use std::fmt;
|
||||
use style_traits::{ParseError, StyleParseErrorKind, ToCss};
|
||||
use values::computed::{Context, ToComputedValue};
|
||||
use values::computed::text::LineHeight as ComputedLineHeight;
|
||||
use values::computed::text::TextOverflow as ComputedTextOverflow;
|
||||
|
@ -349,3 +350,171 @@ impl Parse for TextDecorationLine {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! define_text_align_keyword {
|
||||
($($name: ident => $discriminant: expr,)+) => {
|
||||
/// Specified value of text-align keyword value.
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, ToComputedValue, ToCss)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum TextAlignKeyword {
|
||||
$(
|
||||
$name = $discriminant,
|
||||
)+
|
||||
}
|
||||
|
||||
impl TextAlignKeyword {
|
||||
/// Construct a TextAlignKeyword from u32.
|
||||
pub fn from_u32(discriminant: u32) -> Option<TextAlignKeyword> {
|
||||
match discriminant {
|
||||
$(
|
||||
$discriminant => Some(TextAlignKeyword::$name),
|
||||
)+
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(emilio): Why reinventing the world?
|
||||
#[cfg(feature = "gecko")]
|
||||
define_text_align_keyword! {
|
||||
Start => 0,
|
||||
End => 1,
|
||||
Left => 2,
|
||||
Right => 3,
|
||||
Center => 4,
|
||||
Justify => 5,
|
||||
MozCenter => 6,
|
||||
MozLeft => 7,
|
||||
MozRight => 8,
|
||||
Char => 10,
|
||||
}
|
||||
|
||||
#[cfg(feature = "servo")]
|
||||
define_text_align_keyword! {
|
||||
Start => 0,
|
||||
End => 1,
|
||||
Left => 2,
|
||||
Right => 3,
|
||||
Center => 4,
|
||||
Justify => 5,
|
||||
ServoCenter => 6,
|
||||
ServoLeft => 7,
|
||||
ServoRight => 8,
|
||||
}
|
||||
|
||||
impl TextAlignKeyword {
|
||||
/// Return the initial value of TextAlignKeyword.
|
||||
#[inline]
|
||||
pub fn start() -> TextAlignKeyword {
|
||||
TextAlignKeyword::Start
|
||||
}
|
||||
}
|
||||
|
||||
/// Specified value of text-align property.
|
||||
#[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
pub enum TextAlign {
|
||||
/// Keyword value of text-align property.
|
||||
Keyword(TextAlignKeyword),
|
||||
/// `match-parent` value of text-align property. It has a different handling
|
||||
/// unlike other keywords.
|
||||
#[cfg(feature = "gecko")]
|
||||
MatchParent,
|
||||
/// `MozCenterOrInherit` value of text-align property. It cannot be parsed,
|
||||
/// only set directly on the elements and it has a different handling
|
||||
/// unlike other values.
|
||||
#[cfg(feature = "gecko")]
|
||||
MozCenterOrInherit,
|
||||
|
||||
}
|
||||
|
||||
impl Parse for TextAlign {
|
||||
fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
// MozCenterOrInherit cannot be parsed, only set directly on the elements
|
||||
if let Ok(key) = input.try(TextAlignKeyword::parse) {
|
||||
return Ok(TextAlign::Keyword(key));
|
||||
}
|
||||
#[cfg(feature = "gecko")]
|
||||
{
|
||||
input.expect_ident_matching("match-parent")?;
|
||||
return Ok(TextAlign::MatchParent);
|
||||
}
|
||||
#[cfg(feature = "servo")]
|
||||
{
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCss for TextAlign {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
match *self {
|
||||
TextAlign::Keyword(key) => key.to_css(dest),
|
||||
#[cfg(feature = "gecko")]
|
||||
TextAlign::MatchParent => dest.write_str("match-parent"),
|
||||
#[cfg(feature = "gecko")]
|
||||
TextAlign::MozCenterOrInherit => Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TextAlign {
|
||||
/// Convert an enumerated value coming from Gecko to a `TextAlign`.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub fn from_gecko_keyword(kw: u32) -> Self {
|
||||
use gecko_bindings::structs::NS_STYLE_TEXT_ALIGN_MATCH_PARENT;
|
||||
if kw == NS_STYLE_TEXT_ALIGN_MATCH_PARENT {
|
||||
TextAlign::MatchParent
|
||||
} else {
|
||||
TextAlign::Keyword(TextAlignKeyword::from_gecko_keyword(kw))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToComputedValue for TextAlign {
|
||||
type ComputedValue = TextAlignKeyword;
|
||||
|
||||
#[inline]
|
||||
fn to_computed_value(&self, _context: &Context) -> Self::ComputedValue {
|
||||
match *self {
|
||||
TextAlign::Keyword(key) => key,
|
||||
#[cfg(feature = "gecko")]
|
||||
TextAlign::MatchParent => {
|
||||
// on the root <html> element we should still respect the dir
|
||||
// but the parent dir of that element is LTR even if it's <html dir=rtl>
|
||||
// and will only be RTL if certain prefs have been set.
|
||||
// In that case, the default behavior here will set it to left,
|
||||
// but we want to set it to right -- instead set it to the default (`start`),
|
||||
// which will do the right thing in this case (but not the general case)
|
||||
if _context.is_root_element {
|
||||
return TextAlignKeyword::start();
|
||||
}
|
||||
let parent = _context.builder.get_parent_inheritedtext().clone_text_align();
|
||||
let ltr = _context.builder.inherited_writing_mode().is_bidi_ltr();
|
||||
match (parent, ltr) {
|
||||
(TextAlignKeyword::Start, true) => TextAlignKeyword::Left,
|
||||
(TextAlignKeyword::Start, false) => TextAlignKeyword::Right,
|
||||
(TextAlignKeyword::End, true) => TextAlignKeyword::Right,
|
||||
(TextAlignKeyword::End, false) => TextAlignKeyword::Left,
|
||||
_ => parent
|
||||
}
|
||||
},
|
||||
#[cfg(feature = "gecko")]
|
||||
TextAlign::MozCenterOrInherit => {
|
||||
let parent = _context.builder.get_parent_inheritedtext().clone_text_align();
|
||||
if parent == TextAlignKeyword::Start {
|
||||
TextAlignKeyword::Center
|
||||
} else {
|
||||
parent
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
||||
TextAlign::Keyword(*computed)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,9 +20,10 @@ pub fn derive(input: DeriveInput) -> Tokens {
|
|||
);
|
||||
|
||||
let identifier = cg::to_css_identifier(variant.ident.as_ref());
|
||||
let ident = &variant.ident;
|
||||
match_body = quote! {
|
||||
#match_body
|
||||
#identifier => Ok(#name::#variant),
|
||||
#identifier => Ok(#name::#ident),
|
||||
}
|
||||
});
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче