diff --git a/components/style/properties/data.py b/components/style/properties/data.py index 1219600a5d3..0b2debb233d 100644 --- a/components/style/properties/data.py +++ b/components/style/properties/data.py @@ -67,7 +67,7 @@ class Keyword(object): 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('-') diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 6395bb4d10c..1fd99818047 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -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()") @@ -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 { @@ -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) { diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs index c9b26aa6489..a55e7e2b153 100644 --- a/components/style/properties/helpers.mako.rs +++ b/components/style/properties/helpers.mako.rs @@ -376,7 +376,44 @@ -<%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 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', @@ -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 } @@ -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 % 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()} % 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()} % endif diff --git a/components/style/properties/longhand/border.mako.rs b/components/style/properties/longhand/border.mako.rs index 2b21214c391..7739eb4d9d2 100644 --- a/components/style/properties/longhand/border.mako.rs +++ b/components/style/properties/longhand/border.mako.rs @@ -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", @@ -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')}" diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs index 6cb2026b1d6..56ef26e603e 100644 --- a/components/style/properties/longhand/box.mako.rs +++ b/components/style/properties/longhand/box.mako.rs @@ -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, @@ -93,6 +93,9 @@ } % endif + ${helpers.gecko_keyword_conversion(Keyword('display', ' '.join(values), + gecko_enum_prefix='StyleDisplay'))} + ${helpers.single_keyword("-moz-top-layer", "none top", @@ -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" @@ -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" @@ -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 { diff --git a/components/style/properties/longhand/inherited_table.mako.rs b/components/style/properties/longhand/inherited_table.mako.rs index 21930ed0114..1a6daa55417 100644 --- a/components/style/properties/longhand/inherited_table.mako.rs +++ b/components/style/properties/longhand/inherited_table.mako.rs @@ -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")} diff --git a/components/style/properties/longhand/inherited_text.mako.rs b/components/style/properties/longhand/inherited_text.mako.rs index 3d5430aee3e..60ca0ee5194 100644 --- a/components/style/properties/longhand/inherited_text.mako.rs +++ b/components/style/properties/longhand/inherited_text.mako.rs @@ -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" @@ -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 } } @@ -260,6 +261,10 @@ ${helpers.single_keyword("text-align-last", pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { 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))} // FIXME: This prop should be animatable. @@ -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; diff --git a/components/style/properties/longhand/list.mako.rs b/components/style/properties/longhand/list.mako.rs index a5a1c30861a..5f1bf103d7f 100644 --- a/components/style/properties/longhand/list.mako.rs +++ b/components/style/properties/longhand/list.mako.rs @@ -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")} diff --git a/components/style/properties/longhand/pointing.mako.rs b/components/style/properties/longhand/pointing.mako.rs index a6219a32d1f..b661ec457eb 100644 --- a/components/style/properties/longhand/pointing.mako.rs +++ b/components/style/properties/longhand/pointing.mako.rs @@ -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)")} diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 88fdeb03b57..1ca1fb0b4b1 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -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::::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] @@ -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]