Skip to content

Commit

Permalink
Auto merge of #16488 - heycam:wm, r=Manishearth
Browse files Browse the repository at this point in the history
style: add Gecko-only support for sideways-{lr,rl} and deprecated SVG 1.1 writing-mode values

From https://bugzilla.mozilla.org/show_bug.cgi?id=1356510.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/16488)
<!-- Reviewable:end -->
  • Loading branch information
bors-servo committed Apr 17, 2017
2 parents 533853f + 221aa87 commit 3f0b661
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 59 deletions.
13 changes: 10 additions & 3 deletions components/style/logical_geometry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,12 @@ bitflags!(
const FLAG_RTL = 1 << 0,
const FLAG_VERTICAL = 1 << 1,
const FLAG_VERTICAL_LR = 1 << 2,
const FLAG_SIDEWAYS = 1 << 3,
const FLAG_UPRIGHT = 1 << 4,
/// For vertical writing modes only. When set, line-over/line-under
/// sides are inverted from block-start/block-end. This flag is
/// set when sideways-lr is used.
const FLAG_LINE_INVERTED = 1 << 3,
const FLAG_SIDEWAYS = 1 << 4,
const FLAG_UPRIGHT = 1 << 5,
}
);

Expand All @@ -50,7 +54,7 @@ impl WritingMode {
#[inline]
pub fn is_inline_tb(&self) -> bool {
// https://drafts.csswg.org/css-writing-modes-3/#logical-to-physical
!self.intersects(FLAG_RTL)
self.intersects(FLAG_RTL) == self.intersects(FLAG_LINE_INVERTED)
}

#[inline]
Expand Down Expand Up @@ -145,6 +149,9 @@ impl fmt::Display for WritingMode {
if self.intersects(FLAG_SIDEWAYS) {
try!(write!(formatter, " Sideways"));
}
if self.intersects(FLAG_LINE_INVERTED) {
try!(write!(formatter, " Inverted"));
}
} else {
try!(write!(formatter, "H"));
}
Expand Down
31 changes: 31 additions & 0 deletions components/style/properties/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,20 @@ def to_camel_case(ident):
return re.sub("(^|_|-)([a-z])", lambda m: m.group(2).upper(), ident.strip("_").strip("-"))


def parse_aliases(value):
aliases = {}
for pair in value.split():
[a, v] = pair.split("=")
aliases[a] = v
return aliases


class Keyword(object):
def __init__(self, name, values, gecko_constant_prefix=None,
gecko_enum_prefix=None, custom_consts=None,
extra_gecko_values=None, extra_servo_values=None,
aliases=None,
extra_gecko_aliases=None, extra_servo_aliases=None,
gecko_strip_moz_prefix=True,
gecko_inexhaustive=None):
self.name = name
Expand All @@ -48,6 +58,9 @@ def __init__(self, name, values, gecko_constant_prefix=None,
self.gecko_enum_prefix = gecko_enum_prefix
self.extra_gecko_values = (extra_gecko_values or "").split()
self.extra_servo_values = (extra_servo_values or "").split()
self.aliases = parse_aliases(aliases or "")
self.extra_gecko_aliases = parse_aliases(extra_gecko_aliases or "")
self.extra_servo_aliases = parse_aliases(extra_servo_aliases or "")
self.consts_map = {} if custom_consts is None else custom_consts
self.gecko_strip_moz_prefix = gecko_strip_moz_prefix
self.gecko_inexhaustive = gecko_inexhaustive or (gecko_enum_prefix is None)
Expand All @@ -58,6 +71,16 @@ def gecko_values(self):
def servo_values(self):
return self.values + self.extra_servo_values

def gecko_aliases(self):
aliases = self.aliases.copy()
aliases.update(self.extra_gecko_aliases)
return aliases

def servo_aliases(self):
aliases = self.aliases.copy()
aliases.update(self.extra_servo_aliases)
return aliases

def values_for(self, product):
if product == "gecko":
return self.gecko_values()
Expand All @@ -66,6 +89,14 @@ def values_for(self, product):
else:
raise Exception("Bad product: " + product)

def aliases_for(self, product):
if product == "gecko":
return self.gecko_aliases()
elif product == "servo":
return self.servo_aliases()
else:
raise Exception("Bad product: " + product)

def gecko_constant(self, value):
moz_stripped = value.replace("-moz-", '') if self.gecko_strip_moz_prefix else value.replace("-moz-", 'moz-')
mapped = self.consts_map.get(value)
Expand Down
45 changes: 39 additions & 6 deletions components/style/properties/helpers.mako.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,9 +395,33 @@

<%def name="single_keyword(name, values, vector=False, **kwargs)">
<%call expr="single_keyword_computed(name, values, vector, **kwargs)">
use values::computed::ComputedValueAsSpecified;
% if not "extra_specified" in kwargs and ("aliases" in kwargs or (("extra_%s_aliases" % product) in kwargs)):
impl ToComputedValue for SpecifiedValue {
type ComputedValue = computed_value::T;

#[inline]
fn to_computed_value(&self, _context: &Context) -> computed_value::T {
match *self {
% for value in data.longhands_by_name[name].keyword.values_for(product):
SpecifiedValue::${to_rust_ident(value)} => computed_value::T::${to_rust_ident(value)},
% endfor
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
match *computed {
% for value in data.longhands_by_name[name].keyword.values_for(product):
computed_value::T::${to_rust_ident(value)} => SpecifiedValue::${to_rust_ident(value)},
% endfor
}
}
}
% else:
use values::computed::ComputedValueAsSpecified;
impl ComputedValueAsSpecified for SpecifiedValue {}
% endif

use values::HasViewportPercentage;
impl ComputedValueAsSpecified for SpecifiedValue {}
no_viewport_percentage!(SpecifiedValue);
</%call>
</%def>
Expand Down Expand Up @@ -444,17 +468,25 @@
keyword_kwargs = {a: kwargs.pop(a, None) for a in [
'gecko_constant_prefix', 'gecko_enum_prefix',
'extra_gecko_values', 'extra_servo_values',
'aliases', 'extra_gecko_aliases', 'extra_servo_aliases',
'custom_consts', 'gecko_inexhaustive',
]}
%>

<%def name="inner_body(keyword, extra_specified=None, needs_conversion=False)">
% if extra_specified:
% if extra_specified or keyword.aliases_for(product):
use style_traits::ToCss;
define_css_keyword_enum! { SpecifiedValue:
% for value in keyword.values_for(product) + extra_specified.split():
"${value}" => ${to_rust_ident(value)},
% endfor
values {
% for value in keyword.values_for(product) + (extra_specified or "").split():
"${value}" => ${to_rust_ident(value)},
% endfor
}
aliases {
% for alias, value in keyword.aliases_for(product).iteritems():
"${alias}" => ${to_rust_ident(value)},
% endfor
}
}
% else:
pub use self::computed_value::T as SpecifiedValue;
Expand Down Expand Up @@ -493,6 +525,7 @@
conversion_values = keyword.values_for(product)
if extra_specified:
conversion_values += extra_specified.split()
conversion_values += keyword.aliases_for(product).keys()
%>
${gecko_keyword_conversion(keyword, values=conversion_values)}
% endif
Expand Down
47 changes: 11 additions & 36 deletions components/style/properties/longhand/inherited_box.mako.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ ${helpers.single_keyword("visibility",
// https://drafts.csswg.org/css-writing-modes-3
${helpers.single_keyword("writing-mode",
"horizontal-tb vertical-rl vertical-lr",
extra_gecko_values="sideways-rl sideways-lr",
extra_gecko_aliases="lr=horizontal-tb lr-tb=horizontal-tb \
rl=horizontal-tb rl-tb=horizontal-tb \
tb=vertical-rl tb-rl=vertical-rl",
experimental=True,
need_clone=True,
animation_type="none",
Expand All @@ -27,42 +31,13 @@ ${helpers.single_keyword("direction", "ltr rtl", need_clone=True, animation_type
spec="https://drafts.csswg.org/css-writing-modes/#propdef-direction",
needs_conversion=True)}

<%helpers:single_keyword_computed
name="text-orientation"
values="mixed upright sideways"
extra_specified="sideways-right"
products="gecko"
need_clone="True"
animation_type="none"
spec="https://drafts.csswg.org/css-writing-modes/#propdef-text-orientation"
>
use values::HasViewportPercentage;
no_viewport_percentage!(SpecifiedValue);

impl ToComputedValue for SpecifiedValue {
type ComputedValue = computed_value::T;

#[inline]
fn to_computed_value(&self, _: &Context) -> computed_value::T {
match *self {
% for value in "mixed upright sideways".split():
SpecifiedValue::${value} => computed_value::T::${value},
% endfor
// https://drafts.csswg.org/css-writing-modes-3/#valdef-text-orientation-sideways-right
SpecifiedValue::sideways_right => computed_value::T::sideways,
}
}

#[inline]
fn from_computed_value(computed: &computed_value::T) -> SpecifiedValue {
match *computed {
% for value in "mixed upright sideways".split():
computed_value::T::${value} => SpecifiedValue::${value},
% endfor
}
}
}
</%helpers:single_keyword_computed>
${helpers.single_keyword("text-orientation",
"mixed upright sideways",
extra_gecko_aliases="sideways-right=sideways",
products="gecko",
need_clone=True,
animation_type="none",
spec="https://drafts.csswg.org/css-writing-modes/#propdef-text-orientation")}

// CSS Color Module Level 4
// https://drafts.csswg.org/css-color/
Expand Down
31 changes: 24 additions & 7 deletions components/style/properties/properties.mako.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1936,16 +1936,33 @@ pub fn get_writing_mode(inheritedbox_style: &style_structs::InheritedBox) -> Wri
flags.insert(logical_geometry::FLAG_VERTICAL);
flags.insert(logical_geometry::FLAG_VERTICAL_LR);
},
}
% if product == "gecko":
match inheritedbox_style.clone_text_orientation() {
computed_values::text_orientation::T::mixed => {},
computed_values::text_orientation::T::upright => {
flags.insert(logical_geometry::FLAG_UPRIGHT);
% if product == "gecko":
computed_values::writing_mode::T::sideways_rl => {
flags.insert(logical_geometry::FLAG_VERTICAL);
flags.insert(logical_geometry::FLAG_SIDEWAYS);
},
computed_values::text_orientation::T::sideways => {
computed_values::writing_mode::T::sideways_lr => {
flags.insert(logical_geometry::FLAG_VERTICAL);
flags.insert(logical_geometry::FLAG_VERTICAL_LR);
flags.insert(logical_geometry::FLAG_LINE_INVERTED);
flags.insert(logical_geometry::FLAG_SIDEWAYS);
},
% endif
}
% if product == "gecko":
// If FLAG_SIDEWAYS is already set, this means writing-mode is either
// sideways-rl or sideways-lr, and for both of these values,
// text-orientation has no effect.
if !flags.intersects(logical_geometry::FLAG_SIDEWAYS) {
match inheritedbox_style.clone_text_orientation() {
computed_values::text_orientation::T::mixed => {},
computed_values::text_orientation::T::upright => {
flags.insert(logical_geometry::FLAG_UPRIGHT);
},
computed_values::text_orientation::T::sideways => {
flags.insert(logical_geometry::FLAG_SIDEWAYS);
},
}
}
% endif
flags
Expand Down
40 changes: 33 additions & 7 deletions components/style_traits/values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,37 +82,62 @@ impl_to_css_for_predefined_type!(::cssparser::UnicodeRange);

#[macro_export]
macro_rules! define_css_keyword_enum {
($name: ident: values { $( $css: expr => $variant: ident),+, }
aliases { $( $alias: expr => $alias_variant: ident ),+, }) => {
__define_css_keyword_enum__add_optional_traits!($name [ $( $css => $variant ),+ ]
[ $( $alias => $alias_variant ),+ ]);
};
($name: ident: values { $( $css: expr => $variant: ident),+, }
aliases { $( $alias: expr => $alias_variant: ident ),* }) => {
__define_css_keyword_enum__add_optional_traits!($name [ $( $css => $variant ),+ ]
[ $( $alias => $alias_variant ),* ]);
};
($name: ident: values { $( $css: expr => $variant: ident),+ }
aliases { $( $alias: expr => $alias_variant: ident ),+, }) => {
__define_css_keyword_enum__add_optional_traits!($name [ $( $css => $variant ),+ ]
[ $( $alias => $alias_variant ),+ ]);
};
($name: ident: values { $( $css: expr => $variant: ident),+ }
aliases { $( $alias: expr => $alias_variant: ident ),* }) => {
__define_css_keyword_enum__add_optional_traits!($name [ $( $css => $variant ),+ ]
[ $( $alias => $alias_variant ),* ]);
};
($name: ident: $( $css: expr => $variant: ident ),+,) => {
__define_css_keyword_enum__add_optional_traits!($name [ $( $css => $variant ),+ ]);
__define_css_keyword_enum__add_optional_traits!($name [ $( $css => $variant ),+ ] []);
};
($name: ident: $( $css: expr => $variant: ident ),+) => {
__define_css_keyword_enum__add_optional_traits!($name [ $( $css => $variant ),+ ]);
__define_css_keyword_enum__add_optional_traits!($name [ $( $css => $variant ),+ ] []);
};
}

#[cfg(feature = "servo")]
#[macro_export]
macro_rules! __define_css_keyword_enum__add_optional_traits {
($name: ident [ $( $css: expr => $variant: ident ),+ ]) => {
($name: ident [ $( $css: expr => $variant: ident ),+ ]
[ $( $alias: expr => $alias_variant: ident),* ]) => {
__define_css_keyword_enum__actual! {
$name [ Deserialize, Serialize, HeapSizeOf ] [ $( $css => $variant ),+ ]
$name [ Deserialize, Serialize, HeapSizeOf ]
[ $( $css => $variant ),+ ]
[ $( $alias => $alias_variant ),* ]
}
};
}

#[cfg(not(feature = "servo"))]
#[macro_export]
macro_rules! __define_css_keyword_enum__add_optional_traits {
($name: ident [ $( $css: expr => $variant: ident ),+ ]) => {
($name: ident [ $( $css: expr => $variant: ident ),+ ] [ $( $alias: expr => $alias_variant: ident),* ]) => {
__define_css_keyword_enum__actual! {
$name [] [ $( $css => $variant ),+ ]
$name [] [ $( $css => $variant ),+ ] [ $( $alias => $alias_variant ),* ]
}
};
}

#[macro_export]
macro_rules! __define_css_keyword_enum__actual {
($name: ident [ $( $derived_trait: ident),* ] [ $( $css: expr => $variant: ident ),+ ]) => {
($name: ident [ $( $derived_trait: ident),* ]
[ $( $css: expr => $variant: ident ),+ ]
[ $( $alias: expr => $alias_variant: ident ),* ]) => {
#[allow(non_camel_case_types, missing_docs)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq $(, $derived_trait )* )]
pub enum $name {
Expand All @@ -130,6 +155,7 @@ macro_rules! __define_css_keyword_enum__actual {
pub fn from_ident(ident: &str) -> Result<$name, ()> {
match_ignore_ascii_case! { ident,
$( $css => Ok($name::$variant), )+
$( $alias => Ok($name::$alias_variant), )*
_ => Err(())
}
}
Expand Down

0 comments on commit 3f0b661

Please sign in to comment.