Bug 1371115 - Part 2: implements nsStyleGridLine type properties animatable. r?hiro
In this patch, implements following properties:
* grid-column-end
* grid-column-start
* grid-row-end
* grid-row-start
MozReview-Commit-ID: 2iG6aeuFsE4
--- a/servo/components/style/gecko/conversions.rs
+++ b/servo/components/style/gecko/conversions.rs
@@ -9,20 +9,21 @@
#![allow(unsafe_code)]
use app_units::Au;
use gecko::values::{convert_rgba_to_nscolor, GeckoStyleCoordConvertible};
use gecko_bindings::bindings::{Gecko_CreateGradient, Gecko_SetGradientImageValue, Gecko_SetLayerImageImageValue};
use gecko_bindings::bindings::{Gecko_InitializeImageCropRect, Gecko_SetImageElement};
use gecko_bindings::structs::{nsCSSUnit, nsStyleCoord_CalcValue, nsStyleImage};
use gecko_bindings::structs::{nsresult, SheetType};
-use gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordDataMut};
+use gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordData, CoordDataMut};
use stylesheets::{Origin, RulesMutateError};
use values::computed::{Angle, CalcLengthOrPercentage, Gradient, Image};
use values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto};
+use values::generics::grid::TrackSize;
use values::generics::image::{CompatMode, Image as GenericImage, GradientItem};
use values::specified::length::Percentage;
impl From<CalcLengthOrPercentage> for nsStyleCoord_CalcValue {
fn from(other: CalcLengthOrPercentage) -> nsStyleCoord_CalcValue {
let has_percentage = other.percentage.is_some();
nsStyleCoord_CalcValue {
mLength: other.unclamped_length().0,
@@ -579,8 +580,58 @@ impl From<Origin> for SheetType {
fn from(other: Origin) -> Self {
match other {
Origin::UserAgent => SheetType::Agent,
Origin::Author => SheetType::Doc,
Origin::User => SheetType::User,
}
}
}
+
+impl TrackSize<LengthOrPercentage> {
+ /// Return TrackSize from given two nsStyleCoord
+ pub fn from_gecko_style_coords<T: CoordData>(gecko_min: &T, gecko_max: &T) -> Self {
+ use gecko_bindings::structs::root::nsStyleUnit;
+ use values::computed::length::LengthOrPercentage;
+ use values::generics::grid::{TrackBreadth, TrackSize};
+
+ if gecko_min.unit() == nsStyleUnit::eStyleUnit_None {
+ debug_assert!(gecko_max.unit() == nsStyleUnit::eStyleUnit_Coord ||
+ gecko_max.unit() == nsStyleUnit::eStyleUnit_Percent);
+ return TrackSize::FitContent(LengthOrPercentage::from_gecko_style_coord(gecko_max)
+ .expect("gecko_max could not convert to LengthOrPercentage"));
+ }
+
+ let min = TrackBreadth::from_gecko_style_coord(gecko_min)
+ .expect("gecko_min could not convert to TrackBreadth");
+ let max = TrackBreadth::from_gecko_style_coord(gecko_max)
+ .expect("gecko_max could not convert to TrackBreadth");
+ if min == max {
+ TrackSize::Breadth(max)
+ } else {
+ TrackSize::MinMax(min, max)
+ }
+ }
+
+ /// Save TrackSize to given gecko fields.
+ pub fn to_gecko_style_coords<T: CoordDataMut>(&self, gecko_min: &mut T, gecko_max: &mut T) {
+ use values::generics::grid::TrackSize;
+
+ match *self {
+ TrackSize::FitContent(ref lop) => {
+ // Gecko sets min value to None and max value to the actual value in fit-content
+ // https://dxr.mozilla.org/mozilla-central/rev/0eef1d5/layout/style/nsRuleNode.cpp#8221
+ gecko_min.set_value(CoordDataValue::None);
+ lop.to_gecko_style_coord(gecko_max);
+ },
+ TrackSize::Breadth(ref breadth) => {
+ // Set the value to both fields if there's one breadth value
+ // https://dxr.mozilla.org/mozilla-central/rev/0eef1d5/layout/style/nsRuleNode.cpp#8230
+ breadth.to_gecko_style_coord(gecko_min);
+ breadth.to_gecko_style_coord(gecko_max);
+ },
+ TrackSize::MinMax(ref min, ref max) => {
+ min.to_gecko_style_coord(gecko_min);
+ max.to_gecko_style_coord(gecko_max);
+ },
+ }
+ }
+}
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -1214,111 +1214,80 @@ fn static_assert() {
}).unwrap_or(0);
}
pub fn copy_${value.name}_from(&mut self, other: &Self) {
self.gecko.${value.gecko}.mHasSpan = other.gecko.${value.gecko}.mHasSpan;
self.gecko.${value.gecko}.mInteger = other.gecko.${value.gecko}.mInteger;
self.gecko.${value.gecko}.mLineName.assign(&*other.gecko.${value.gecko}.mLineName);
}
+
+ pub fn clone_${value.name}(&self) -> longhands::${value.name}::computed_value::T {
+ use gecko_bindings::structs::{nsStyleGridLine_kMinLine, nsStyleGridLine_kMaxLine};
+ use string_cache::Atom;
+ use values::specified::Integer;
+
+ longhands::${value.name}::computed_value::T {
+ is_span: self.gecko.${value.gecko}.mHasSpan,
+ ident: {
+ let name = self.gecko.${value.gecko}.mLineName.to_string();
+ if name.len() == 0 {
+ None
+ } else {
+ Some(CustomIdent(Atom::from(name)))
+ }
+ },
+ line_num:
+ if self.gecko.${value.gecko}.mInteger == 0 {
+ None
+ } else {
+ debug_assert!(nsStyleGridLine_kMinLine <= self.gecko.${value.gecko}.mInteger);
+ debug_assert!(self.gecko.${value.gecko}.mInteger <= nsStyleGridLine_kMaxLine);
+ Some(Integer::new(self.gecko.${value.gecko}.mInteger))
+ },
+ }
+ }
% endfor
% for kind in ["rows", "columns"]:
pub fn set_grid_auto_${kind}(&mut self, v: longhands::grid_auto_${kind}::computed_value::T) {
- use values::generics::grid::TrackSize;
-
- match v {
- TrackSize::FitContent(lop) => {
- // Gecko sets min value to None and max value to the actual value in fit-content
- // https://dxr.mozilla.org/mozilla-central/rev/0eef1d5/layout/style/nsRuleNode.cpp#8221
- self.gecko.mGridAuto${kind.title()}Min.set_value(CoordDataValue::None);
- lop.to_gecko_style_coord(&mut self.gecko.mGridAuto${kind.title()}Max);
- },
- TrackSize::Breadth(breadth) => {
- // Set the value to both fields if there's one breadth value
- // https://dxr.mozilla.org/mozilla-central/rev/0eef1d5/layout/style/nsRuleNode.cpp#8230
- breadth.to_gecko_style_coord(&mut self.gecko.mGridAuto${kind.title()}Min);
- breadth.to_gecko_style_coord(&mut self.gecko.mGridAuto${kind.title()}Max);
- },
- TrackSize::MinMax(min, max) => {
- min.to_gecko_style_coord(&mut self.gecko.mGridAuto${kind.title()}Min);
- max.to_gecko_style_coord(&mut self.gecko.mGridAuto${kind.title()}Max);
- },
- }
+ v.to_gecko_style_coords(&mut self.gecko.mGridAuto${kind.title()}Min,
+ &mut self.gecko.mGridAuto${kind.title()}Max)
}
pub fn copy_grid_auto_${kind}_from(&mut self, other: &Self) {
self.gecko.mGridAuto${kind.title()}Min.copy_from(&other.gecko.mGridAuto${kind.title()}Min);
self.gecko.mGridAuto${kind.title()}Max.copy_from(&other.gecko.mGridAuto${kind.title()}Max);
}
pub fn clone_grid_auto_${kind}(&self) -> longhands::grid_auto_${kind}::computed_value::T {
- use gecko_bindings::structs::root::nsStyleUnit::eStyleUnit_None;
- use values::computed::length::LengthOrPercentage;
- use values::generics::grid::{TrackSize, TrackBreadth};
-
- let ref min_gecko = self.gecko.mGridAuto${kind.title()}Min;
- let ref max_gecko = self.gecko.mGridAuto${kind.title()}Max;
- if min_gecko.unit() == eStyleUnit_None {
- debug_assert!(max_gecko.unit() != eStyleUnit_None);
- return TrackSize::FitContent(LengthOrPercentage::from_gecko_style_coord(max_gecko)
- .expect("mGridAuto${kind.title()}Max contains style coord"));
- }
-
- let min = TrackBreadth::from_gecko_style_coord(min_gecko)
- .expect("mGridAuto${kind.title()}Min contains style coord");
- let max = TrackBreadth::from_gecko_style_coord(max_gecko)
- .expect("mGridAuto${kind.title()}Max contains style coord");
- if min == max {
- TrackSize::Breadth(max)
- } else {
- TrackSize::MinMax(min, max)
- }
+ ::values::generics::grid::TrackSize::from_gecko_style_coords(&self.gecko.mGridAuto${kind.title()}Min,
+ &self.gecko.mGridAuto${kind.title()}Max)
}
pub fn set_grid_template_${kind}(&mut self, v: longhands::grid_template_${kind}::computed_value::T) {
<% self_grid = "self.gecko.mGridTemplate%s" % kind.title() %>
- use gecko::values::GeckoStyleCoordConvertible;
use gecko_bindings::structs::{nsTArray, nsStyleGridLine_kMaxLine};
use nsstring::nsStringRepr;
use std::usize;
use values::CustomIdent;
use values::generics::grid::TrackListType::Auto;
- use values::generics::grid::{GridTemplateComponent, RepeatCount, TrackSize};
+ use values::generics::grid::{GridTemplateComponent, RepeatCount};
#[inline]
fn set_line_names(servo_names: &[CustomIdent], gecko_names: &mut nsTArray<nsStringRepr>) {
unsafe {
bindings::Gecko_ResizeTArrayForStrings(gecko_names, servo_names.len() as u32);
}
for (servo_name, gecko_name) in servo_names.iter().zip(gecko_names.iter_mut()) {
gecko_name.assign(servo_name.0.as_slice());
}
}
- fn set_track_size<G, T>(value: TrackSize<T>, gecko_min: &mut G, gecko_max: &mut G)
- where G: CoordDataMut, T: GeckoStyleCoordConvertible
- {
- match value {
- TrackSize::FitContent(lop) => {
- gecko_min.set_value(CoordDataValue::None);
- lop.to_gecko_style_coord(gecko_max);
- },
- TrackSize::Breadth(breadth) => {
- breadth.to_gecko_style_coord(gecko_min);
- breadth.to_gecko_style_coord(gecko_max);
- },
- TrackSize::MinMax(min, max) => {
- min.to_gecko_style_coord(gecko_min);
- max.to_gecko_style_coord(gecko_max);
- },
- }
- }
-
// Set defaults
${self_grid}.mRepeatAutoIndex = -1;
${self_grid}.set_mIsAutoFill(false);
${self_grid}.set_mIsSubgrid(false);
let max_lines = nsStyleGridLine_kMaxLine as usize - 1; // for accounting the final <line-names>
match v {
@@ -1362,23 +1331,23 @@ fn static_assert() {
let mut values_iter = track.values.into_iter();
let min_max_iter = ${self_grid}.mMinTrackSizingFunctions.iter_mut()
.zip(${self_grid}.mMaxTrackSizingFunctions.iter_mut());
for (i, (gecko_min, gecko_max)) in min_max_iter.enumerate().take(max_lines) {
let name_list = line_names.next().expect("expected line-names");
set_line_names(&name_list, &mut ${self_grid}.mLineNameLists[i]);
if i == auto_idx {
- set_track_size(auto_track_size.take().expect("expected <track-size> for <auto-track-repeat>"),
- gecko_min, gecko_max);
+ let track_size = auto_track_size.take().expect("expected <track-size> for <auto-track-repeat>");
+ track_size.to_gecko_style_coords(gecko_min, gecko_max);
continue
}
let track_size = values_iter.next().expect("expected <track-size> value");
- set_track_size(track_size, gecko_min, gecko_max);
+ track_size.to_gecko_style_coords(gecko_min, gecko_max);
}
let final_names = line_names.next().unwrap();
set_line_names(&final_names, ${self_grid}.mLineNameLists.last_mut().unwrap());
},
GridTemplateComponent::None => {
unsafe {
bindings::Gecko_SetStyleGridTemplateArrayLengths(&mut ${self_grid}, 0);
--- a/servo/components/style/properties/longhand/position.mako.rs
+++ b/servo/components/style/properties/longhand/position.mako.rs
@@ -255,17 +255,17 @@ macro_rules! impl_align_conversions {
spec="https://drafts.csswg.org/css-grid/#propdef-grid-%s-gap" % kind,
animation_value_type="ComputedValue",
products="gecko")}
% for range in ["start", "end"]:
${helpers.predefined_type("grid-%s-%s" % (kind, range),
"GridLine",
"Default::default()",
- animation_value_type="none",
+ animation_value_type="discrete",
spec="https://drafts.csswg.org/css-grid/#propdef-grid-%s-%s" % (kind, range),
products="gecko",
boxed=True)}
% endfor
// NOTE: According to the spec, this should handle multiple values of `<track-size>`,
// but gecko supports only a single value
${helpers.predefined_type("grid-auto-%ss" % kind,