diff options
-rw-r--r-- | components/style/properties/gecko.mako.rs | 138 | ||||
-rw-r--r-- | components/style/properties/longhand/position.mako.rs | 2 |
2 files changed, 135 insertions, 5 deletions
diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index fa58b6b9c98..599605c23af 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -1053,7 +1053,7 @@ fn static_assert() { skip_longhands="${skip_position_longhands} z-index box-sizing order align-content justify-content align-self justify-self align-items justify-items grid-auto-rows grid-auto-columns grid-auto-flow - grid-template-areas"> + grid-template-areas grid-template-rows grid-template-columns"> % for side in SIDES: <% impl_split_style_coord("%s" % side.ident, "mOffset", @@ -1165,9 +1165,9 @@ fn static_assert() { let ident = v.ident.unwrap_or(String::new()); self.gecko.${value.gecko}.mLineName.assign_utf8(&ident); self.gecko.${value.gecko}.mHasSpan = v.is_span; - self.gecko.${value.gecko}.mInteger = v.integer.map(|i| { + self.gecko.${value.gecko}.mInteger = v.line_num.map(|i| { // clamping the integer between a range - cmp::max(nsStyleGridLine_kMinLine, cmp::min(i, nsStyleGridLine_kMaxLine)) + cmp::max(nsStyleGridLine_kMinLine, cmp::min(i.value(), nsStyleGridLine_kMaxLine)) }).unwrap_or(0); } @@ -1179,7 +1179,7 @@ fn static_assert() { % endfor % for kind in ["rows", "columns"]: - pub fn set_grid_auto_${kind}(&mut self, v: longhands::grid_auto_rows::computed_value::T) { + pub fn set_grid_auto_${kind}(&mut self, v: longhands::grid_auto_${kind}::computed_value::T) { use values::specified::grid::TrackSize; match v { @@ -1206,6 +1206,136 @@ fn static_assert() { 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 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::{nsCString, nsStringRepr}; + use std::usize; + use values::specified::grid::TrackListType::Auto; + use values::specified::grid::{RepeatCount, TrackSize}; + + #[inline] + fn set_bitfield(bitfield: &mut u8, pos: u8, val: bool) { + let mask = 1 << (pos - 1); + *bitfield &= !mask; + *bitfield |= (val as u8) << (pos - 1); + } + + #[inline] + fn set_line_names(servo_names: &[String], 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_utf8(&nsCString::from(&*servo_name)); + } + } + + 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; + set_bitfield(&mut ${self_grid}._bitfield_1, 1, false); // mIsAutoFill + set_bitfield(&mut ${self_grid}._bitfield_1, 2, false); // mIsSubgrid + // FIXME: mIsSubgrid is false only for <none>, but we don't support subgrid name lists at the moment. + + match v { + Either::First(track) => { + let mut auto_idx = usize::MAX; + let mut auto_track_size = None; + if let Auto(idx) = track.list_type { + auto_idx = idx as usize; + let auto_repeat = track.auto_repeat.as_ref().expect("expected <auto-track-repeat> value"); + + if auto_repeat.count == RepeatCount::AutoFill { + set_bitfield(&mut ${self_grid}._bitfield_1, 1, true); + } + + ${self_grid}.mRepeatAutoIndex = idx as i16; + // NOTE: Gecko supports only one set of values in <auto-repeat> + // i.e., it can only take repeat(auto-fill, [a] 10px [b]), and no more. + set_line_names(&auto_repeat.line_names[0], &mut ${self_grid}.mRepeatAutoLineNameListBefore); + set_line_names(&auto_repeat.line_names[1], &mut ${self_grid}.mRepeatAutoLineNameListAfter); + auto_track_size = Some(auto_repeat.track_sizes.get(0).unwrap().clone()); + } else { + unsafe { + bindings::Gecko_ResizeTArrayForStrings( + &mut ${self_grid}.mRepeatAutoLineNameListBefore, 0); + bindings::Gecko_ResizeTArrayForStrings( + &mut ${self_grid}.mRepeatAutoLineNameListAfter, 0); + } + } + + let mut num_values = track.values.len(); + if auto_track_size.is_some() { + num_values += 1; + } + + let max_lines = nsStyleGridLine_kMaxLine as usize - 1; // for accounting the final <line-names> + num_values = cmp::min(num_values, max_lines); + unsafe { + bindings::Gecko_SetStyleGridTemplateArrayLengths(&mut ${self_grid}, num_values as u32); + } + + let mut line_names = track.line_names.into_iter(); + 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); + continue + } + + let track_size = values_iter.next().expect("expected <track-size> value"); + set_track_size(track_size, gecko_min, gecko_max); + } + + let final_names = line_names.next().unwrap(); + set_line_names(&final_names, ${self_grid}.mLineNameLists.last_mut().unwrap()); + }, + Either::Second(_none) => { + unsafe { + bindings::Gecko_SetStyleGridTemplateArrayLengths(&mut ${self_grid}, 0); + bindings::Gecko_ResizeTArrayForStrings( + &mut ${self_grid}.mRepeatAutoLineNameListBefore, 0); + bindings::Gecko_ResizeTArrayForStrings( + &mut ${self_grid}.mRepeatAutoLineNameListAfter, 0); + } + }, + } + } + + pub fn copy_grid_template_${kind}_from(&mut self, other: &Self) { + unsafe { + bindings::Gecko_CopyStyleGridTemplateValues(&mut ${self_grid}, + &other.gecko.mGridTemplate${kind.title()}); + } + } % endfor pub fn set_grid_auto_flow(&mut self, v: longhands::grid_auto_flow::computed_value::T) { diff --git a/components/style/properties/longhand/position.mako.rs b/components/style/properties/longhand/position.mako.rs index 83de256d6af..0cea82301cc 100644 --- a/components/style/properties/longhand/position.mako.rs +++ b/components/style/properties/longhand/position.mako.rs @@ -325,7 +325,7 @@ ${helpers.predefined_type("object-position", ${helpers.predefined_type("grid-template-%ss" % kind, "TrackListOrNone", "Either::Second(None_)", - products="none", + products="gecko", spec="https://drafts.csswg.org/css-grid/#propdef-grid-template-%ss" % kind, boxed=True, animation_value_type="none")} |