Skip to content

Commit

Permalink
stylo: Add helpers for converting Gecko keywords to Servo, use to sup…
Browse files Browse the repository at this point in the history
…port keyword pres attrs
  • Loading branch information
Manishearth committed Feb 19, 2017
1 parent afccbf4 commit b85e1f5
Show file tree
Hide file tree
Showing 10 changed files with 145 additions and 21 deletions.
2 changes: 1 addition & 1 deletion components/style/properties/data.py
Expand Up @@ -67,7 +67,7 @@ def values_for(self, product):
raise Exception("Bad product: " + product)

def gecko_constant(self, value):
moz_stripped = value.replace("-moz-", '') if self.gecko_strip_moz_prefix else value
moz_stripped = value.replace("-moz-", '') if self.gecko_strip_moz_prefix else value.replace("-moz-", 'moz-')
mapped = self.consts_map.get(value)
if self.gecko_enum_prefix:
parts = moz_stripped.split('-')
Expand Down
32 changes: 27 additions & 5 deletions components/style/properties/gecko.mako.rs
Expand Up @@ -233,8 +233,6 @@ def get_gecko_property(ffi_name, self_param = "self"):
return "%s.gecko.%s" % (self_param, ffi_name)

def set_gecko_property(ffi_name, expr):
if ffi_name == "__LIST_STYLE_TYPE__":
return "unsafe { Gecko_SetListStyleType(&mut self.gecko, %s as u32); }" % expr
if "mBorderColor" in ffi_name:
ffi_name = ffi_name.replace("mBorderColor",
"*self.gecko.__bindgen_anon_1.mBorderColor.as_mut()")
Expand Down Expand Up @@ -2154,8 +2152,32 @@ fn static_assert() {
unsafe { Gecko_CopyListStyleImageFrom(&mut self.gecko, &other.gecko); }
}

${impl_keyword_setter("list_style_type", "__LIST_STYLE_TYPE__",
data.longhands_by_name["list-style-type"].keyword)}
pub fn set_list_style_type(&mut self, v: longhands::list_style_type::computed_value::T) {
use properties::longhands::list_style_type::computed_value::T as Keyword;
<%
keyword = data.longhands_by_name["list-style-type"].keyword
# The first four are @counter-styles
# The rest have special fallback behavior
special = """upper-roman lower-roman upper-alpha lower-alpha
japanese-informal japanese-formal korean-hangul-formal korean-hanja-informal
korean-hanja-formal simp-chinese-informal simp-chinese-formal
trad-chinese-informal trad-chinese-formal""".split()
%>
let result = match v {
% for value in keyword.values_for('gecko'):
% if value in special:
// Special keywords are implemented as @counter-styles
// and need to be manually set as strings
Keyword::${to_rust_ident(value)} => structs::${keyword.gecko_constant("none")},
% else:
Keyword::${to_rust_ident(value)} =>
structs::${keyword.gecko_constant(value)},
% endif
% endfor
};
unsafe { Gecko_SetListStyleType(&mut self.gecko, result as u32); }
}


pub fn copy_list_style_type_from(&mut self, other: &Self) {
unsafe {
Expand Down Expand Up @@ -2379,7 +2401,7 @@ fn static_assert() {
-webkit-text-stroke-width text-emphasis-position -moz-tab-size">

<% text_align_keyword = Keyword("text-align", "start end left right center justify -moz-center -moz-left " +
"-moz-right match-parent") %>
"-moz-right match-parent char") %>
${impl_keyword('text_align', 'mTextAlign', text_align_keyword, need_clone=False)}

pub fn set_text_shadow(&mut self, v: longhands::text_shadow::computed_value::T) {
Expand Down
57 changes: 52 additions & 5 deletions components/style/properties/helpers.mako.rs
Expand Up @@ -376,7 +376,44 @@
</%call>
</%def>

<%def name="single_keyword_computed(name, values, vector=False, extra_specified=None, **kwargs)">
<%def name="gecko_keyword_conversion(keyword, values=None, type='SpecifiedValue')">
<%
if not values:
values = keyword.values_for(product)
%>
#[cfg(feature = "gecko")]
impl ${type} {
/// 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 {
use gecko_bindings::structs;
% if keyword.gecko_enum_prefix:
% for value in values:
// We can't match on enum values if we're matching on a u32
const ${to_rust_ident(value).upper()}: u32
= structs::${keyword.gecko_enum_prefix}::${to_camel_case(value)} as u32;
% endfor
match kw {
% for value in values:
${to_rust_ident(value).upper()} => ${type}::${to_rust_ident(value)},
% endfor
x => panic!("Found unexpected value in style struct for ${keyword.name} property: {:?}", x),
}
% else:
match kw {
% for value in values:
structs::${keyword.gecko_constant(value)} => ${type}::${to_rust_ident(value)},
% endfor
x => panic!("Found unexpected value in style struct for ${keyword.name} property: {:?}", x),
}
% endif
}
}
</%def>

<%def name="single_keyword_computed(name, values, vector=False,
extra_specified=None, needs_conversion=False, **kwargs)">
<%
keyword_kwargs = {a: kwargs.pop(a, None) for a in [
'gecko_constant_prefix', 'gecko_enum_prefix',
Expand All @@ -385,11 +422,11 @@
]}
%>

<%def name="inner_body()">
<%def name="inner_body(keyword, extra_specified=None, needs_conversion=False)">
% if extra_specified:
use style_traits::ToCss;
define_css_keyword_enum! { SpecifiedValue:
% for value in data.longhands_by_name[name].keyword.values_for(product) + extra_specified.split():
% for value in keyword.values_for(product) + extra_specified.split():
"${value}" => ${to_rust_ident(value)},
% endfor
}
Expand Down Expand Up @@ -424,15 +461,25 @@
SpecifiedValue::parse(input)
}
}

% if needs_conversion:
<%
conversion_values = keyword.values_for(product)
if extra_specified:
conversion_values += extra_specified.split()
%>
${gecko_keyword_conversion(keyword, values=conversion_values)}
% endif
</%def>
% if vector:
<%call expr="vector_longhand(name, keyword=Keyword(name, values, **keyword_kwargs), **kwargs)">
${inner_body()}
${inner_body(Keyword(name, values, **keyword_kwargs))}
${caller.body()}
</%call>
% else:
<%call expr="longhand(name, keyword=Keyword(name, values, **keyword_kwargs), **kwargs)">
${inner_body()}
${inner_body(Keyword(name, values, **keyword_kwargs),
extra_specified=extra_specified, needs_conversion=needs_conversion)}
${caller.body()}
</%call>
% endif
Expand Down
5 changes: 4 additions & 1 deletion components/style/properties/longhand/border.mako.rs
Expand Up @@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

<%namespace name="helpers" file="/helpers.mako.rs" />
<% from data import Method, PHYSICAL_SIDES, ALL_SIDES, maybe_moz_logical_alias %>
<% from data import Keyword, Method, PHYSICAL_SIDES, ALL_SIDES, maybe_moz_logical_alias %>

<% data.new_style_struct("Border", inherited=False,
additional_methods=[Method("border_" + side + "_has_nonzero_width",
Expand Down Expand Up @@ -32,6 +32,9 @@
animatable=False, logical = side[1])}
% endfor

${helpers.gecko_keyword_conversion(Keyword('border-style',
"none solid double dotted dashed hidden groove ridge inset outset"),
type="::values::specified::BorderStyle")}
% for side in ALL_SIDES:
<%helpers:longhand name="border-${side[0]}-width" animatable="True" logical="${side[1]}"
alias="${maybe_moz_logical_alias(product, side, '-moz-border-%s-width')}"
Expand Down
9 changes: 8 additions & 1 deletion components/style/properties/longhand/box.mako.rs
Expand Up @@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

<%namespace name="helpers" file="/helpers.mako.rs" />
<% from data import Keyword, Method, to_rust_ident %>
<% from data import Keyword, Method, to_rust_ident, to_camel_case%>

<% data.new_style_struct("Box",
inherited=False,
Expand Down Expand Up @@ -93,6 +93,9 @@
}
% endif
${helpers.gecko_keyword_conversion(Keyword('display', ' '.join(values),
gecko_enum_prefix='StyleDisplay'))}
</%helpers:longhand>
${helpers.single_keyword("-moz-top-layer", "none top",
Expand Down Expand Up @@ -146,6 +149,7 @@ ${helpers.single_keyword("-moz-top-layer", "none top",
values="none left right"
// https://drafts.csswg.org/css-logical-props/#float-clear
extra_specified="inline-start inline-end"
needs_conversion="True"
animatable="False"
need_clone="True"
gecko_enum_prefix="StyleFloat"
Expand Down Expand Up @@ -190,6 +194,7 @@ ${helpers.single_keyword("-moz-top-layer", "none top",
values="none left right both"
// https://drafts.csswg.org/css-logical-props/#float-clear
extra_specified="inline-start inline-end"
needs_conversion="True"
animatable="False"
gecko_enum_prefix="StyleClear"
gecko_ffi_name="mBreakType"
Expand Down Expand Up @@ -256,6 +261,8 @@ ${helpers.single_keyword("-moz-top-layer", "none top",
extra_gecko_values="middle-with-baseline") %>
<% vertical_align_keywords = vertical_align.keyword.values_for(product) %>

${helpers.gecko_keyword_conversion(vertical_align.keyword)}

impl HasViewportPercentage for SpecifiedValue {
fn has_viewport_percentage(&self) -> bool {
match *self {
Expand Down
Expand Up @@ -16,6 +16,7 @@ ${helpers.single_keyword("empty-cells", "show hide",
spec="https://drafts.csswg.org/css-tables/#propdef-empty-cells")}
${helpers.single_keyword("caption-side", "top bottom",
extra_gecko_values="right left top-outside bottom-outside",
needs_conversion="True",
animatable=False,
spec="https://drafts.csswg.org/css-tables/#propdef-caption-side")}

Expand Down
8 changes: 7 additions & 1 deletion components/style/properties/longhand/inherited_text.mako.rs
Expand Up @@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

<%namespace name="helpers" file="/helpers.mako.rs" />

<% from data import Keyword %>
<% data.new_style_struct("InheritedText", inherited=True, gecko_name="Text") %>

<%helpers:longhand name="line-height" animatable="True"
Expand Down Expand Up @@ -251,6 +251,7 @@ ${helpers.single_keyword("text-align-last",
_moz_left("-moz-left") => 7,
_moz_right("-moz-right") => 8,
match_parent("match-parent") => 9,
char("char") => 10,
% endif
}
}
Expand All @@ -260,6 +261,10 @@ ${helpers.single_keyword("text-align-last",
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))}
</%helpers:longhand>

// FIXME: This prop should be animatable.
Expand Down Expand Up @@ -515,6 +520,7 @@ ${helpers.single_keyword("text-align-last",
<%helpers:single_keyword_computed name="white-space"
values="normal pre nowrap pre-wrap pre-line"
gecko_constant_prefix="NS_STYLE_WHITESPACE"
needs_conversion="True"
animatable="False"
spec="https://drafts.csswg.org/css-text/#propdef-white-space">
use values::computed::ComputedValueAsSpecified;
Expand Down
13 changes: 11 additions & 2 deletions components/style/properties/longhand/list.mako.rs
Expand Up @@ -16,15 +16,24 @@ ${helpers.single_keyword("list-style-position", "outside inside", animatable=Fal
//
// TODO(bholley): Missing quite a few gecko properties here as well.
//
// In gecko, {upper,lower}-{roman,alpha} are implemented as @counter-styles in the
// UA, however they can also be set from pres attrs. When @counter-style is supported
// we may need to look into this and handle these differently.
//
// [1]: http://dev.w3.org/csswg/css-counter-styles/
${helpers.single_keyword("list-style-type", """
disc none circle square decimal disclosure-open disclosure-closed
disc none circle square decimal disclosure-open disclosure-closed lower-alpha upper-alpha
""", extra_servo_values="""arabic-indic bengali cambodian cjk-decimal devanagari
gujarati gurmukhi kannada khmer lao malayalam mongolian
myanmar oriya persian telugu thai tibetan cjk-earthly-branch
cjk-heavenly-stem lower-greek hiragana hiragana-iroha katakana
katakana-iroha lower-alpha upper-alpha""",
katakana-iroha""",
extra_gecko_values="""japanese-informal japanese-formal korean-hangul-formal
korean-hanja-formal korean-hanja-informal simp-chinese-informal simp-chinese-formal
trad-chinese-informal trad-chinese-formal ethiopic-numeric upper-roman lower-roman
""",
gecko_constant_prefix="NS_STYLE_LIST_STYLE",
needs_conversion="True",
animatable=False,
spec="https://drafts.csswg.org/css-lists/#propdef-list-style-type")}

Expand Down
2 changes: 1 addition & 1 deletion components/style/properties/longhand/pointing.mako.rs
Expand Up @@ -159,7 +159,7 @@ ${helpers.single_keyword("-moz-user-input", "auto none enabled disabled",
${helpers.single_keyword("-moz-user-modify", "read-only read-write write-only",
products="gecko", gecko_ffi_name="mUserModify",
gecko_enum_prefix="StyleUserModify",
gecko_inexhaustive=True,
needs_conversion=True,
animatable=False,
spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-user-modify)")}

Expand Down
37 changes: 33 additions & 4 deletions ports/geckolib/glue.rs
Expand Up @@ -1004,11 +1004,40 @@ pub extern "C" fn Servo_DeclarationBlock_SetIdentStringValue(_:
}

#[no_mangle]
pub extern "C" fn Servo_DeclarationBlock_SetKeywordValue(_:
#[allow(unreachable_code)]
pub extern "C" fn Servo_DeclarationBlock_SetKeywordValue(declarations:
RawServoDeclarationBlockBorrowed,
_: nsCSSPropertyID,
_: i32) {
property: nsCSSPropertyID,
value: i32) {
use style::properties::{DeclaredValue, PropertyDeclaration, LonghandId};
use style::properties::longhands;
use style::values::specified::{BorderStyle, NoCalcLength};

let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
let long = get_longhand_from_id!(property);
let value = value as u32;

let prop = match_wrap_declared! { long,
MozUserModify => longhands::_moz_user_modify::SpecifiedValue::from_gecko_keyword(value),
// TextEmphasisPosition => FIXME implement text-emphasis-position
Display => longhands::display::SpecifiedValue::from_gecko_keyword(value),
Float => longhands::float::SpecifiedValue::from_gecko_keyword(value),
VerticalAlign => longhands::vertical_align::SpecifiedValue::from_gecko_keyword(value),
TextAlign => longhands::text_align::SpecifiedValue::from_gecko_keyword(value),
Clear => longhands::clear::SpecifiedValue::from_gecko_keyword(value),
FontSize => {
// We rely on Gecko passing in font-size values (0...7) here.
longhands::font_size::SpecifiedValue(NoCalcLength::from_font_size_int(value as u8).into())
},
ListStyleType => longhands::list_style_type::SpecifiedValue::from_gecko_keyword(value),
WhiteSpace => longhands::white_space::SpecifiedValue::from_gecko_keyword(value),
CaptionSide => longhands::caption_side::SpecifiedValue::from_gecko_keyword(value),
BorderTopStyle => BorderStyle::from_gecko_keyword(value),
BorderRightStyle => BorderStyle::from_gecko_keyword(value),
BorderBottomStyle => BorderStyle::from_gecko_keyword(value),
BorderLeftStyle => BorderStyle::from_gecko_keyword(value),
};
declarations.write().declarations.push((prop, Default::default()));
}

#[no_mangle]
Expand Down Expand Up @@ -1171,7 +1200,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetFontFamily(declarations:
#[no_mangle]
pub extern "C" fn Servo_DeclarationBlock_SetTextDecorationColorOverride(_:
RawServoDeclarationBlockBorrowed) {

error!("stylo: Don't know how to handle quirks-mode text-decoration color overrides");
}

#[no_mangle]
Expand Down

0 comments on commit b85e1f5

Please sign in to comment.