From 476d05caeb605826f8d5bb96b662330e54d75d18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Fri, 6 Jul 2018 05:15:34 +0200 Subject: [PATCH] Bug 1309752: Introduce PropertyDeclaration::to_physical. r=heycam MozReview-Commit-ID: FAL04K5G948 --- servo/components/style/properties/data.py | 15 +++++ .../style/properties/properties.mako.rs | 66 ++++++++++++++++++- 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/servo/components/style/properties/data.py b/servo/components/style/properties/data.py index 76713cfbcb5e..c33eeb7b39ca 100644 --- a/servo/components/style/properties/data.py +++ b/servo/components/style/properties/data.py @@ -237,6 +237,21 @@ class Longhand(object): def type(): return "longhand" + # For a given logical property return all the physical + # property names corresponding to it. + def all_physical_mapped_properties(self): + assert self.logical + logical_side = None + for s in LOGICAL_SIDES + LOGICAL_SIZES: + if s in self.name: + assert not logical_side + logical_side = s + assert logical_side + physical = PHYSICAL_SIDES if logical_side in LOGICAL_SIDES else PHYSICAL_SIZES + return [self.name.replace(logical_side, physical_side).replace("inset-", "") \ + for physical_side in physical] + + def experimental(self, product): if product == "gecko": return bool(self.gecko_pref) diff --git a/servo/components/style/properties/properties.mako.rs b/servo/components/style/properties/properties.mako.rs index a4396d0b4fd1..e884a03ae4e4 100644 --- a/servo/components/style/properties/properties.mako.rs +++ b/servo/components/style/properties/properties.mako.rs @@ -1497,7 +1497,7 @@ impl UnparsedValue { /// An identifier for a given property declaration, which can be either a /// longhand or a custom property. -#[derive(Clone, Copy, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq)] #[cfg_attr(feature = "servo", derive(MallocSizeOf))] pub enum PropertyDeclarationId<'a> { /// A longhand. @@ -1903,7 +1903,7 @@ impl PropertyDeclaration { } _ => {} } - // This is just fine because PropertyDeclarationId and LonghandId + // This is just fine because PropertyDeclaration and LonghandId // have corresponding discriminants. let id = unsafe { *(self as *const _ as *const LonghandId) }; debug_assert_eq!(id, match *self { @@ -1915,6 +1915,68 @@ impl PropertyDeclaration { PropertyDeclarationId::Longhand(id) } + /// Given a declaration, convert it into a declaration for a corresponding + /// physical property. + #[inline] + pub fn to_physical(&self, wm: WritingMode) -> Self { + match *self { + PropertyDeclaration::WithVariables(VariableDeclaration { + id, + ref value, + }) => { + return PropertyDeclaration::WithVariables(VariableDeclaration { + id: id.to_physical(wm), + value: value.clone(), + }) + } + PropertyDeclaration::CSSWideKeyword(WideKeywordDeclaration { + id, + keyword, + }) => { + return PropertyDeclaration::CSSWideKeyword(WideKeywordDeclaration { + id: id.to_physical(wm), + keyword, + }) + } + PropertyDeclaration::Custom(..) => return self.clone(), + % for prop in data.longhands: + PropertyDeclaration::${prop.camel_case}(..) => {}, + % endfor + } + + let mut ret = self.clone(); + + % for prop in data.longhands: + % if prop.logical: + % for physical_property in prop.all_physical_mapped_properties(): + % if data.longhands_by_name[physical_property].specified_type() != prop.specified_type(): + <% raise "Logical property %s should share specified value with physical property %s" % (prop.name, physical_property) %> + % endif + % endfor + % endif + % endfor + + unsafe { + let longhand_id = *(&mut ret as *mut _ as *mut LonghandId); + + debug_assert_eq!( + PropertyDeclarationId::Longhand(longhand_id), + ret.id() + ); + + // This is just fine because PropertyDeclaration and LonghandId + // have corresponding discriminants. + *(&mut ret as *mut _ as *mut LonghandId) = longhand_id.to_physical(wm); + + debug_assert_eq!( + PropertyDeclarationId::Longhand(longhand_id.to_physical(wm)), + ret.id() + ); + } + + ret + } + fn with_variables_from_shorthand(&self, shorthand: ShorthandId) -> Option< &str> { match *self { PropertyDeclaration::WithVariables(ref declaration) => {