stylo: Add support for text-align match-parent and the <th> -moz-center-or-inherit behavior

MozReview-Commit-ID: GEDM7JfJB8A
This commit is contained in:
Manish Goregaokar 2017-03-26 13:53:34 -07:00 committed by Manish Goregaokar
parent 6a67688924
commit 0392e58a2f
No known key found for this signature in database
GPG key ID: 3BBF4D3E2EF79F98
3 changed files with 123 additions and 13 deletions

View file

@ -51,7 +51,7 @@ use gecko_bindings::structs::NODE_IS_NATIVE_ANONYMOUS;
use gecko_bindings::sugar::ownership::HasArcFFI;
use parking_lot::RwLock;
use properties::{ComputedValues, parse_style_attribute};
use properties::PropertyDeclarationBlock;
use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock};
use properties::animated_properties::AnimationValueMap;
use rule_tree::CascadeLevel as ServoCascadeLevel;
use selector_parser::{ElementExt, Snapshot};
@ -624,6 +624,24 @@ impl<'le> PresentationalHintsSynthetizer for GeckoElement<'le> {
fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, hints: &mut V)
where V: Push<ApplicableDeclarationBlock>,
{
use properties::longhands::text_align::SpecifiedValue;
lazy_static! {
static ref TH_RULE: ApplicableDeclarationBlock = {
let global_style_data = &*GLOBAL_STYLE_DATA;
let pdb = PropertyDeclarationBlock::with_one(
PropertyDeclaration::TextAlign(SpecifiedValue::MozCenterOrInherit),
Importance::Normal
);
let arc = Arc::new(global_style_data.shared_lock.wrap(pdb));
ApplicableDeclarationBlock::from_declarations(arc, ServoCascadeLevel::PresHints)
};
};
// <th> elements get a default MozCenterOrInherit which may get overridden
if self.get_namespace() == &*Namespace(atom!("http://www.w3.org/1999/xhtml")) &&
self.get_local_name().as_ptr() == atom!("th").as_ptr() {
hints.push(TH_RULE.clone());
}
let declarations = unsafe { Gecko_GetHTMLPresentationAttrDeclarationBlock(self.0) };
let declarations = declarations.and_then(|s| s.as_arc_opt());
if let Some(decl) = declarations {

View file

@ -2797,8 +2797,12 @@ fn static_assert() {
-webkit-text-stroke-width text-emphasis-position -moz-tab-size -moz-text-size-adjust">
<% text_align_keyword = Keyword("text-align", "start end left right center justify -moz-center -moz-left " +
"-moz-right match-parent char") %>
"-moz-right char") %>
<% text_align_reachable_keyword = Keyword("text-align", "start end left right center justify char") %>
${impl_keyword('text_align', 'mTextAlign', text_align_keyword, need_clone=False)}
// Stable rust errors on unreachable patterns, and there is overlap, so we run with the overlapping
// constants removed
${impl_keyword_clone('text_align', 'mTextAlign', text_align_reachable_keyword)}
pub fn set_text_shadow(&mut self, v: longhands::text_shadow::computed_value::T) {
self.gecko.mTextShadow.replace_with_new(v.0.len() as u32);

View file

@ -250,11 +250,10 @@ ${helpers.single_keyword("text-align-last",
spec="https://drafts.csswg.org/css-text/#propdef-text-align-last")}
// TODO make this a shorthand and implement text-align-last/text-align-all
<%helpers:longhand name="text-align" animatable="False" spec="https://drafts.csswg.org/css-text/#propdef-text-align">
pub use self::computed_value::T as SpecifiedValue;
<%helpers:longhand name="text-align" animatable="False" need_clone="True"
spec="https://drafts.csswg.org/css-text/#propdef-text-align">
use values::computed::ComputedValueAsSpecified;
use values::HasViewportPercentage;
impl ComputedValueAsSpecified for SpecifiedValue {}
no_viewport_percentage!(SpecifiedValue);
pub mod computed_value {
use style_traits::ToCss;
@ -299,21 +298,110 @@ ${helpers.single_keyword("text-align-last",
_moz_center("-moz-center") => 6,
_moz_left("-moz-left") => 7,
_moz_right("-moz-right") => 8,
match_parent("match-parent") => 9,
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() -> computed_value::T {
computed_value::T::start
}
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
computed_value::T::parse(input)
}
${helpers.gecko_keyword_conversion(Keyword('text-align',
"""left right center justify -moz-left -moz-right
-moz-center char end match-parent""",
gecko_strip_moz_prefix=False))}
% if product == "gecko":
use std::fmt;
use style_traits::ToCss;
#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
pub enum SpecifiedValue {
Keyword(computed_value::T),
MatchParent,
MozCenterOrInherit,
}
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
// MozCenterOrInherit cannot be parsed, only set directly on th elements
if let Ok(key) = input.try(computed_value::T::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 = computed_value::T;
#[inline]
fn to_computed_value(&self, context: &Context) -> computed_value::T {
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.inherited_style().get_inheritedtext().clone_text_align();
let ltr = context.inherited_style().writing_mode.is_bidi_ltr();
match (parent, ltr) {
(computed_value::T::start, true) => computed_value::T::left,
(computed_value::T::start, false) => computed_value::T::right,
(computed_value::T::end, true) => computed_value::T::right,
(computed_value::T::end, false) => computed_value::T::left,
_ => parent
}
}
SpecifiedValue::MozCenterOrInherit => {
let parent = context.inherited_style().get_inheritedtext().clone_text_align();
if parent == computed_value::T::start {
computed_value::T::center
} else {
parent
}
}
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
SpecifiedValue::Keyword(*computed)
}
}
% else:
impl ComputedValueAsSpecified for SpecifiedValue {}
pub use self::computed_value::T as SpecifiedValue;
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
computed_value::T::parse(input)
}
% endif
</%helpers:longhand>
// FIXME: This prop should be animatable.