Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stylo: Add support for grid-template-{rows,columns} #16067

Merged
merged 12 commits into from May 18, 2017
@@ -662,7 +662,8 @@ mod bindings {
.header(add_include("mozilla/ServoBindings.h"))
.hide_type("nsACString_internal")
.hide_type("nsAString_internal")
.raw_line("pub use nsstring::{nsACString, nsAString, nsString};")
.raw_line("pub use nsstring::{nsACString, nsAString, nsString, nsStringRepr};")
.raw_line("use gecko_bindings::structs::nsTArray;")
.raw_line("type nsACString_internal = nsACString;")
.raw_line("type nsAString_internal = nsAString;")
.whitelisted_function("Servo_.*")
@@ -859,7 +860,13 @@ mod bindings {
// type with zero_size_type. If we ever introduce immutable borrow types
// which _do_ need to be opaque, we'll need a separate mode.
}
write_binding_file(builder, BINDINGS_FILE, &Vec::new());
let fixups = vec![
Fixup { // hack for gecko-owned string
pat: "<nsString".into(),
rep: "<nsStringRepr".into()
},
];
write_binding_file(builder, BINDINGS_FILE, &fixups);
}

fn generate_atoms() {
@@ -1,6 +1,7 @@
/* automatically generated by rust-bindgen */

pub use nsstring::{nsACString, nsAString, nsString};
pub use nsstring::{nsACString, nsAString, nsString, nsStringRepr};
use gecko_bindings::structs::nsTArray;
type nsACString_internal = nsACString;
type nsAString_internal = nsAString;
use gecko_bindings::structs::mozilla::css::GridTemplateAreasValue;
@@ -943,6 +944,15 @@ extern "C" {
extern "C" {
pub fn Gecko_DropElementSnapshot(snapshot: ServoElementSnapshotOwned);
}
extern "C" {
pub fn Gecko_ResizeTArrayForStrings(array: *mut nsTArray<nsStringRepr>,
length: u32);
}
extern "C" {
pub fn Gecko_SetStyleGridTemplateArrayLengths(grid_template:
*mut nsStyleGridTemplate,
track_sizes: u32);
}
extern "C" {
pub fn Gecko_CopyStyleGridTemplateValues(grid_template:
*mut nsStyleGridTemplate,
@@ -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) {
@@ -319,6 +319,17 @@ ${helpers.predefined_type("object-position",
spec="https://drafts.csswg.org/css-grid/#propdef-grid-auto-%ss" % kind,
products="gecko",
boxed=True)}

// NOTE: The spec lists only `none | <track-list> | <auto-track-list>`, but gecko seems to support
// `subgrid <line-name-list>?` in addition to this (probably old spec). We should support it soon.
${helpers.predefined_type("grid-template-%ss" % kind,
"TrackListOrNone",
"Either::Second(None_)",
products="gecko",
spec="https://drafts.csswg.org/css-grid/#propdef-grid-template-%ss" % kind,
boxed=True,
animation_value_type="none")}

% endfor

<%helpers:longhand name="grid-auto-flow"
@@ -154,7 +154,7 @@
GridLine::parse(context, input)?
} else {
let mut line = GridLine::default();
if start.integer.is_none() && !start.is_span {
if start.line_num.is_none() && !start.is_span {
line.ident = start.ident.clone(); // ident from start value should be taken
}

@@ -188,7 +188,7 @@
pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> {
fn line_with_ident_from(other: &GridLine) -> GridLine {
let mut this = GridLine::default();
if other.integer.is_none() && !other.is_span {
if other.line_num.is_none() && !other.is_span {
this.ident = other.ident.clone();
}

@@ -19,6 +19,7 @@ use super::{CSSFloat, CSSInteger, RGBA};
use super::generics::BorderRadiusSize as GenericBorderRadiusSize;
use super::specified;
use super::specified::grid::{TrackBreadth as GenericTrackBreadth, TrackSize as GenericTrackSize};
use super::specified::grid::TrackList as GenericTrackList;

pub use app_units::Au;
pub use cssparser::Color as CSSColor;
@@ -595,6 +596,13 @@ pub type TrackBreadth = GenericTrackBreadth<LengthOrPercentage>;
/// The computed value of a grid `<track-size>`
pub type TrackSize = GenericTrackSize<LengthOrPercentage>;

/// The computed value of a grid `<track-list>`
/// (could also be `<auto-track-list>` or `<explicit-track-list>`)
pub type TrackList = GenericTrackList<TrackSize>;

/// `<track-list> | none`
pub type TrackListOrNone = Either<TrackList, None_>;

impl ClipRectOrAuto {
/// Return an auto (default for clip-rect and image-region) value
pub fn auto() -> Self {
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.