<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

<%! from data import to_rust_ident %>
<%namespace name="helpers" file="/helpers.mako.rs" />
<% from data import ALL_SIZES, PHYSICAL_SIDES, LOGICAL_SIDES %>

<% data.new_style_struct("Position", inherited=False) %>

// "top" / "left" / "bottom" / "right"
% for side in PHYSICAL_SIDES:
    ${helpers.predefined_type(side, "LengthOrPercentageOrAuto",
                              "computed::LengthOrPercentageOrAuto::Auto",
                              spec="https://www.w3.org/TR/CSS2/visuren.html#propdef-%s" % side,
                              animation_value_type="ComputedValue",
                              allow_quirks=True)}
% endfor
// offset-* logical properties, map to "top" / "left" / "bottom" / "right"
% for side in LOGICAL_SIDES:
    ${helpers.predefined_type("offset-%s" % side, "LengthOrPercentageOrAuto",
                              "computed::LengthOrPercentageOrAuto::Auto",
                              spec="https://drafts.csswg.org/css-logical-props/#propdef-offset-%s" % side,
                              animation_value_type="ComputedValue", logical=True)}
% endfor

#[cfg(feature = "gecko")]
macro_rules! impl_align_conversions {
    ($name: path) => {
        impl From<u8> for $name {
            fn from(bits: u8) -> $name {
                $name(::values::specified::align::AlignFlags::from_bits(bits)
                      .expect("bits contain valid flag"))
            }
        }

        impl From<$name> for u8 {
            fn from(v: $name) -> u8 {
                v.0.bits()
            }
        }
    };
}

${helpers.predefined_type("z-index", "IntegerOrAuto",
                          "Either::Second(Auto)",
                          spec="https://www.w3.org/TR/CSS2/visuren.html#z-index",
                          flags="CREATES_STACKING_CONTEXT",
                          animation_value_type="ComputedValue")}

// CSS Flexible Box Layout Module Level 1
// http://www.w3.org/TR/css3-flexbox/

// Flex container properties
${helpers.single_keyword("flex-direction", "row row-reverse column column-reverse",
                         spec="https://drafts.csswg.org/css-flexbox/#flex-direction-property",
                         extra_prefixes="webkit", animation_value_type="discrete")}

${helpers.single_keyword("flex-wrap", "nowrap wrap wrap-reverse",
                         spec="https://drafts.csswg.org/css-flexbox/#flex-wrap-property",
                         extra_prefixes="webkit", animation_value_type="discrete")}

% if product == "servo":
    // FIXME: Update Servo to support the same Syntax as Gecko.
    ${helpers.single_keyword("justify-content", "flex-start stretch flex-end center space-between space-around",
                             extra_prefixes="webkit",
                             spec="https://drafts.csswg.org/css-align/#propdef-justify-content",
                             animation_value_type="discrete")}
% else:
    ${helpers.predefined_type(name="justify-content",
                              type="JustifyContent",
                              initial_value="specified::JustifyContent(specified::ContentDistribution::normal())",
                              spec="https://drafts.csswg.org/css-align/#propdef-justify-content",
                              extra_prefixes="webkit",
                              animation_value_type="discrete")}
% endif

% if product == "servo":
    // FIXME: Update Servo to support the same Syntax as Gecko.
    ${helpers.single_keyword("align-content", "stretch flex-start flex-end center space-between space-around",
                             extra_prefixes="webkit",
                             spec="https://drafts.csswg.org/css-align/#propdef-align-content",
                             animation_value_type="discrete")}

    ${helpers.single_keyword("align-items",
                             "stretch flex-start flex-end center baseline",
                             extra_prefixes="webkit",
                             spec="https://drafts.csswg.org/css-flexbox/#align-items-property",
                             animation_value_type="discrete")}
% else:
    ${helpers.predefined_type(name="align-content",
                              type="AlignContent",
                              initial_value="specified::AlignContent(specified::ContentDistribution::normal())",
                              spec="https://drafts.csswg.org/css-align/#propdef-align-content",
                              extra_prefixes="webkit",
                              animation_value_type="discrete")}

    ${helpers.predefined_type(name="align-items",
                              type="AlignItems",
                              initial_value="specified::AlignItems::normal()",
                              spec="https://drafts.csswg.org/css-align/#propdef-align-items",
                              extra_prefixes="webkit",
                              animation_value_type="discrete")}

    #[cfg(feature = "gecko")]
    impl_align_conversions!(::values::specified::align::AlignItems);

    ${helpers.predefined_type(name="justify-items",
                              type="JustifyItems",
                              initial_value="computed::JustifyItems::auto()",
                              spec="https://drafts.csswg.org/css-align/#propdef-justify-items",
                              animation_value_type="discrete")}

    #[cfg(feature = "gecko")]
    impl_align_conversions!(::values::specified::align::JustifyItems);
% endif

// Flex item properties
${helpers.predefined_type("flex-grow", "NonNegativeNumber",
                          "From::from(0.0)",
                          spec="https://drafts.csswg.org/css-flexbox/#flex-grow-property",
                          extra_prefixes="webkit",
                          animation_value_type="NonNegativeNumber")}

${helpers.predefined_type("flex-shrink", "NonNegativeNumber",
                          "From::from(1.0)",
                          spec="https://drafts.csswg.org/css-flexbox/#flex-shrink-property",
                          extra_prefixes="webkit",
                          animation_value_type="NonNegativeNumber")}

// https://drafts.csswg.org/css-align/#align-self-property
% if product == "servo":
    // FIXME: Update Servo to support the same syntax as Gecko.
    ${helpers.single_keyword("align-self", "auto stretch flex-start flex-end center baseline",
                             extra_prefixes="webkit",
                             spec="https://drafts.csswg.org/css-flexbox/#propdef-align-self",
                             animation_value_type="discrete")}
% else:
    ${helpers.predefined_type(name="align-self",
                              type="AlignSelf",
                              initial_value="specified::AlignSelf(specified::SelfAlignment::auto())",
                              spec="https://drafts.csswg.org/css-align/#align-self-property",
                              extra_prefixes="webkit",
                              animation_value_type="discrete")}

    ${helpers.predefined_type(name="justify-self",
                              type="JustifySelf",
                              initial_value="specified::JustifySelf(specified::SelfAlignment::auto())",
                              spec="https://drafts.csswg.org/css-align/#justify-self-property",
                              animation_value_type="discrete")}

    #[cfg(feature = "gecko")]
    impl_align_conversions!(::values::specified::align::SelfAlignment);
% endif

// https://drafts.csswg.org/css-flexbox/#propdef-order
${helpers.predefined_type("order", "Integer", "0",
                          extra_prefixes="webkit",
                          animation_value_type="ComputedValue",
                          spec="https://drafts.csswg.org/css-flexbox/#order-property")}

% if product == "gecko":
    // FIXME: Gecko doesn't support content value yet.
    //
    // FIXME(emilio): I suspect this property shouldn't allow quirks, and this
    // was just a mistake, it's kind of justificable to support it given the
    // spec grammar is just `content | <width>`, but other browsers don't...
    ${helpers.predefined_type(
        "flex-basis",
        "MozLength",
        "computed::MozLength::auto()",
        extra_prefixes="webkit",
        animation_value_type="ComputedValue",
        allow_quirks=True,
        spec="https://drafts.csswg.org/css-flexbox/#flex-basis-property"
    )}
% else:
    // FIXME: This property should be animatable.
    ${helpers.predefined_type("flex-basis",
                              "FlexBasis",
                              "computed::FlexBasis::auto()",
                              spec="https://drafts.csswg.org/css-flexbox/#flex-basis-property",
                              extra_prefixes="webkit",
                              animation_value_type="none")}
% endif
% for (size, logical) in ALL_SIZES:
    <%
        spec = "https://drafts.csswg.org/css-box/#propdef-%s"
        if logical:
            spec = "https://drafts.csswg.org/css-logical-props/#propdef-%s"
    %>
    // NOTE: Block-size doesn't support -moz-*-content keywords, since they make
    // no sense on the block axis, but it simplifies things the have that it has
    // the same type as the other properties, since otherwise we'd need to
    // handle logical props where the types are different, which looks like a
    // pain.
    % if product == "gecko":
        <%
            parse_function = "parse" if size != "block-size" else "parse_disallow_keyword"
        %>
        // width, height, block-size, inline-size
        ${helpers.predefined_type(
            size,
            "MozLength",
            "computed::MozLength::auto()",
            parse_function,
            logical=logical,
            allow_quirks=not logical,
            spec=spec % size,
            animation_value_type="ComputedValues"
        )}
        // min-width, min-height, min-block-size, min-inline-size,
        ${helpers.predefined_type(
            "min-%s" % size,
            "MozLength",
            "computed::MozLength::auto()",
            parse_function,
            logical=logical,
            allow_quirks=not logical,
            spec=spec % size,
            animation_value_type="ComputedValue"
        )}
        ${helpers.predefined_type(
            "max-%s" % size,
            "MaxLength",
            "computed::MaxLength::none()",
            parse_function,
            logical=logical,
            allow_quirks=not logical,
            spec=spec % size,
            animation_value_type="ComputedValue",
        )}
    % else:
        // servo versions (no keyword support)
        ${helpers.predefined_type(size,
                                  "LengthOrPercentageOrAuto",
                                  "computed::LengthOrPercentageOrAuto::Auto",
                                  "parse_non_negative",
                                  spec=spec % size,
                                  allow_quirks=not logical,
                                  animation_value_type="ComputedValue", logical = logical)}
        ${helpers.predefined_type("min-%s" % size,
                                  "LengthOrPercentage",
                                  "computed::LengthOrPercentage::Length(computed::Length::new(0.))",
                                  "parse_non_negative",
                                  spec=spec % ("min-%s" % size),
                                  animation_value_type="ComputedValue",
                                  logical=logical,
                                  allow_quirks=not logical)}
        ${helpers.predefined_type("max-%s" % size,
                                  "LengthOrPercentageOrNone",
                                  "computed::LengthOrPercentageOrNone::None",
                                  "parse_non_negative",
                                  spec=spec % ("min-%s" % size),
                                  animation_value_type="ComputedValue",
                                  logical=logical,
                                  allow_quirks=not logical)}
    % endif
% endfor

${helpers.single_keyword("box-sizing",
                         "content-box border-box",
                         extra_prefixes="moz webkit",
                         spec="https://drafts.csswg.org/css-ui/#propdef-box-sizing",
                         gecko_enum_prefix="StyleBoxSizing",
                         custom_consts={ "content-box": "Content", "border-box": "Border" },
                         animation_value_type="discrete")}

${helpers.single_keyword("object-fit", "fill contain cover none scale-down",
                         products="gecko", animation_value_type="discrete",
                         spec="https://drafts.csswg.org/css-images/#propdef-object-fit")}

${helpers.predefined_type("object-position",
                          "Position",
                          "computed::Position::zero()",
                          products="gecko",
                          boxed=True,
                          spec="https://drafts.csswg.org/css-images-3/#the-object-position",
                          animation_value_type="ComputedValue")}

% for kind in ["row", "column"]:
    ${helpers.predefined_type("grid-%s-gap" % kind,
                              "NonNegativeLengthOrPercentage",
                              "computed::NonNegativeLengthOrPercentage::zero()",
                              spec="https://drafts.csswg.org/css-grid/#propdef-grid-%s-gap" % kind,
                              animation_value_type="NonNegativeLengthOrPercentage",
                              products="gecko")}

    % for range in ["start", "end"]:
        ${helpers.predefined_type("grid-%s-%s" % (kind, range),
                                  "GridLine",
                                  "Default::default()",
                                  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,
                              "TrackSize",
                              "Default::default()",
                              animation_value_type="discrete",
                              spec="https://drafts.csswg.org/css-grid/#propdef-grid-auto-%ss" % kind,
                              products="gecko",
                              boxed=True)}

    ${helpers.predefined_type("grid-template-%ss" % kind,
                              "GridTemplateComponent",
                              "specified::GenericGridTemplateComponent::None",
                              products="gecko",
                              spec="https://drafts.csswg.org/css-grid/#propdef-grid-template-%ss" % kind,
                              boxed=True,
                              animation_value_type="discrete")}

% endfor

${helpers.predefined_type("grid-auto-flow",
                          "GridAutoFlow",
                          initial_value="computed::GridAutoFlow::row()",
                          products="gecko",
                          animation_value_type="discrete",
                          spec="https://drafts.csswg.org/css-grid/#propdef-grid-auto-flow")}

${helpers.predefined_type("grid-template-areas",
                          "GridTemplateAreas",
                          initial_value="computed::GridTemplateAreas::none()",
                          products="gecko",
                          animation_value_type="discrete",
                          gecko_pref="layout.css.grid.enabled",
                          spec="https://drafts.csswg.org/css-grid/#propdef-grid-template-areas")}
<commit_msg>Auto merge of #19969 - emilio:whoopsies, r=emilio<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

<%! from data import to_rust_ident %>
<%namespace name="helpers" file="/helpers.mako.rs" />
<% from data import ALL_SIZES, PHYSICAL_SIDES, LOGICAL_SIDES %>

<% data.new_style_struct("Position", inherited=False) %>

// "top" / "left" / "bottom" / "right"
% for side in PHYSICAL_SIDES:
    ${helpers.predefined_type(side, "LengthOrPercentageOrAuto",
                              "computed::LengthOrPercentageOrAuto::Auto",
                              spec="https://www.w3.org/TR/CSS2/visuren.html#propdef-%s" % side,
                              animation_value_type="ComputedValue",
                              allow_quirks=True)}
% endfor
// offset-* logical properties, map to "top" / "left" / "bottom" / "right"
% for side in LOGICAL_SIDES:
    ${helpers.predefined_type("offset-%s" % side, "LengthOrPercentageOrAuto",
                              "computed::LengthOrPercentageOrAuto::Auto",
                              spec="https://drafts.csswg.org/css-logical-props/#propdef-offset-%s" % side,
                              animation_value_type="ComputedValue", logical=True)}
% endfor

#[cfg(feature = "gecko")]
macro_rules! impl_align_conversions {
    ($name: path) => {
        impl From<u8> for $name {
            fn from(bits: u8) -> $name {
                $name(::values::specified::align::AlignFlags::from_bits(bits)
                      .expect("bits contain valid flag"))
            }
        }

        impl From<$name> for u8 {
            fn from(v: $name) -> u8 {
                v.0.bits()
            }
        }
    };
}

${helpers.predefined_type("z-index", "IntegerOrAuto",
                          "Either::Second(Auto)",
                          spec="https://www.w3.org/TR/CSS2/visuren.html#z-index",
                          flags="CREATES_STACKING_CONTEXT",
                          animation_value_type="ComputedValue")}

// CSS Flexible Box Layout Module Level 1
// http://www.w3.org/TR/css3-flexbox/

// Flex container properties
${helpers.single_keyword("flex-direction", "row row-reverse column column-reverse",
                         spec="https://drafts.csswg.org/css-flexbox/#flex-direction-property",
                         extra_prefixes="webkit", animation_value_type="discrete")}

${helpers.single_keyword("flex-wrap", "nowrap wrap wrap-reverse",
                         spec="https://drafts.csswg.org/css-flexbox/#flex-wrap-property",
                         extra_prefixes="webkit", animation_value_type="discrete")}

% if product == "servo":
    // FIXME: Update Servo to support the same Syntax as Gecko.
    ${helpers.single_keyword("justify-content", "flex-start stretch flex-end center space-between space-around",
                             extra_prefixes="webkit",
                             spec="https://drafts.csswg.org/css-align/#propdef-justify-content",
                             animation_value_type="discrete")}
% else:
    ${helpers.predefined_type(name="justify-content",
                              type="JustifyContent",
                              initial_value="specified::JustifyContent(specified::ContentDistribution::normal())",
                              spec="https://drafts.csswg.org/css-align/#propdef-justify-content",
                              extra_prefixes="webkit",
                              animation_value_type="discrete")}
% endif

% if product == "servo":
    // FIXME: Update Servo to support the same Syntax as Gecko.
    ${helpers.single_keyword("align-content", "stretch flex-start flex-end center space-between space-around",
                             extra_prefixes="webkit",
                             spec="https://drafts.csswg.org/css-align/#propdef-align-content",
                             animation_value_type="discrete")}

    ${helpers.single_keyword("align-items",
                             "stretch flex-start flex-end center baseline",
                             extra_prefixes="webkit",
                             spec="https://drafts.csswg.org/css-flexbox/#align-items-property",
                             animation_value_type="discrete")}
% else:
    ${helpers.predefined_type(name="align-content",
                              type="AlignContent",
                              initial_value="specified::AlignContent(specified::ContentDistribution::normal())",
                              spec="https://drafts.csswg.org/css-align/#propdef-align-content",
                              extra_prefixes="webkit",
                              animation_value_type="discrete")}

    ${helpers.predefined_type(name="align-items",
                              type="AlignItems",
                              initial_value="specified::AlignItems::normal()",
                              spec="https://drafts.csswg.org/css-align/#propdef-align-items",
                              extra_prefixes="webkit",
                              animation_value_type="discrete")}

    #[cfg(feature = "gecko")]
    impl_align_conversions!(::values::specified::align::AlignItems);

    ${helpers.predefined_type(name="justify-items",
                              type="JustifyItems",
                              initial_value="computed::JustifyItems::auto()",
                              spec="https://drafts.csswg.org/css-align/#propdef-justify-items",
                              animation_value_type="discrete")}

    #[cfg(feature = "gecko")]
    impl_align_conversions!(::values::specified::align::JustifyItems);
% endif

// Flex item properties
${helpers.predefined_type("flex-grow", "NonNegativeNumber",
                          "From::from(0.0)",
                          spec="https://drafts.csswg.org/css-flexbox/#flex-grow-property",
                          extra_prefixes="webkit",
                          animation_value_type="NonNegativeNumber")}

${helpers.predefined_type("flex-shrink", "NonNegativeNumber",
                          "From::from(1.0)",
                          spec="https://drafts.csswg.org/css-flexbox/#flex-shrink-property",
                          extra_prefixes="webkit",
                          animation_value_type="NonNegativeNumber")}

// https://drafts.csswg.org/css-align/#align-self-property
% if product == "servo":
    // FIXME: Update Servo to support the same syntax as Gecko.
    ${helpers.single_keyword("align-self", "auto stretch flex-start flex-end center baseline",
                             extra_prefixes="webkit",
                             spec="https://drafts.csswg.org/css-flexbox/#propdef-align-self",
                             animation_value_type="discrete")}
% else:
    ${helpers.predefined_type(name="align-self",
                              type="AlignSelf",
                              initial_value="specified::AlignSelf(specified::SelfAlignment::auto())",
                              spec="https://drafts.csswg.org/css-align/#align-self-property",
                              extra_prefixes="webkit",
                              animation_value_type="discrete")}

    ${helpers.predefined_type(name="justify-self",
                              type="JustifySelf",
                              initial_value="specified::JustifySelf(specified::SelfAlignment::auto())",
                              spec="https://drafts.csswg.org/css-align/#justify-self-property",
                              animation_value_type="discrete")}

    #[cfg(feature = "gecko")]
    impl_align_conversions!(::values::specified::align::SelfAlignment);
% endif

// https://drafts.csswg.org/css-flexbox/#propdef-order
${helpers.predefined_type("order", "Integer", "0",
                          extra_prefixes="webkit",
                          animation_value_type="ComputedValue",
                          spec="https://drafts.csswg.org/css-flexbox/#order-property")}

% if product == "gecko":
    // FIXME: Gecko doesn't support content value yet.
    //
    // FIXME(emilio): I suspect this property shouldn't allow quirks, and this
    // was just a mistake, it's kind of justificable to support it given the
    // spec grammar is just `content | <width>`, but other browsers don't...
    ${helpers.predefined_type(
        "flex-basis",
        "MozLength",
        "computed::MozLength::auto()",
        extra_prefixes="webkit",
        animation_value_type="MozLength",
        allow_quirks=True,
        spec="https://drafts.csswg.org/css-flexbox/#flex-basis-property"
    )}
% else:
    // FIXME: This property should be animatable.
    ${helpers.predefined_type("flex-basis",
                              "FlexBasis",
                              "computed::FlexBasis::auto()",
                              spec="https://drafts.csswg.org/css-flexbox/#flex-basis-property",
                              extra_prefixes="webkit",
                              animation_value_type="none")}
% endif
% for (size, logical) in ALL_SIZES:
    <%
        spec = "https://drafts.csswg.org/css-box/#propdef-%s"
        if logical:
            spec = "https://drafts.csswg.org/css-logical-props/#propdef-%s"
    %>
    // NOTE: Block-size doesn't support -moz-*-content keywords, since they make
    // no sense on the block axis, but it simplifies things the have that it has
    // the same type as the other properties, since otherwise we'd need to
    // handle logical props where the types are different, which looks like a
    // pain.
    % if product == "gecko":
        <%
            parse_function = "parse" if size != "block-size" else "parse_disallow_keyword"
        %>
        // width, height, block-size, inline-size
        ${helpers.predefined_type(
            size,
            "MozLength",
            "computed::MozLength::auto()",
            parse_function,
            logical=logical,
            allow_quirks=not logical,
            spec=spec % size,
            animation_value_type="MozLength"
        )}
        // min-width, min-height, min-block-size, min-inline-size,
        ${helpers.predefined_type(
            "min-%s" % size,
            "MozLength",
            "computed::MozLength::auto()",
            parse_function,
            logical=logical,
            allow_quirks=not logical,
            spec=spec % size,
            animation_value_type="MozLength"
        )}
        ${helpers.predefined_type(
            "max-%s" % size,
            "MaxLength",
            "computed::MaxLength::none()",
            parse_function,
            logical=logical,
            allow_quirks=not logical,
            spec=spec % size,
            animation_value_type="MaxLength",
        )}
    % else:
        // servo versions (no keyword support)
        ${helpers.predefined_type(size,
                                  "LengthOrPercentageOrAuto",
                                  "computed::LengthOrPercentageOrAuto::Auto",
                                  "parse_non_negative",
                                  spec=spec % size,
                                  allow_quirks=not logical,
                                  animation_value_type="ComputedValue", logical = logical)}
        ${helpers.predefined_type("min-%s" % size,
                                  "LengthOrPercentage",
                                  "computed::LengthOrPercentage::Length(computed::Length::new(0.))",
                                  "parse_non_negative",
                                  spec=spec % ("min-%s" % size),
                                  animation_value_type="ComputedValue",
                                  logical=logical,
                                  allow_quirks=not logical)}
        ${helpers.predefined_type("max-%s" % size,
                                  "LengthOrPercentageOrNone",
                                  "computed::LengthOrPercentageOrNone::None",
                                  "parse_non_negative",
                                  spec=spec % ("min-%s" % size),
                                  animation_value_type="ComputedValue",
                                  logical=logical,
                                  allow_quirks=not logical)}
    % endif
% endfor

${helpers.single_keyword("box-sizing",
                         "content-box border-box",
                         extra_prefixes="moz webkit",
                         spec="https://drafts.csswg.org/css-ui/#propdef-box-sizing",
                         gecko_enum_prefix="StyleBoxSizing",
                         custom_consts={ "content-box": "Content", "border-box": "Border" },
                         animation_value_type="discrete")}

${helpers.single_keyword("object-fit", "fill contain cover none scale-down",
                         products="gecko", animation_value_type="discrete",
                         spec="https://drafts.csswg.org/css-images/#propdef-object-fit")}

${helpers.predefined_type("object-position",
                          "Position",
                          "computed::Position::zero()",
                          products="gecko",
                          boxed=True,
                          spec="https://drafts.csswg.org/css-images-3/#the-object-position",
                          animation_value_type="ComputedValue")}

% for kind in ["row", "column"]:
    ${helpers.predefined_type("grid-%s-gap" % kind,
                              "NonNegativeLengthOrPercentage",
                              "computed::NonNegativeLengthOrPercentage::zero()",
                              spec="https://drafts.csswg.org/css-grid/#propdef-grid-%s-gap" % kind,
                              animation_value_type="NonNegativeLengthOrPercentage",
                              products="gecko")}

    % for range in ["start", "end"]:
        ${helpers.predefined_type("grid-%s-%s" % (kind, range),
                                  "GridLine",
                                  "Default::default()",
                                  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,
                              "TrackSize",
                              "Default::default()",
                              animation_value_type="discrete",
                              spec="https://drafts.csswg.org/css-grid/#propdef-grid-auto-%ss" % kind,
                              products="gecko",
                              boxed=True)}

    ${helpers.predefined_type("grid-template-%ss" % kind,
                              "GridTemplateComponent",
                              "specified::GenericGridTemplateComponent::None",
                              products="gecko",
                              spec="https://drafts.csswg.org/css-grid/#propdef-grid-template-%ss" % kind,
                              boxed=True,
                              animation_value_type="discrete")}

% endfor

${helpers.predefined_type("grid-auto-flow",
                          "GridAutoFlow",
                          initial_value="computed::GridAutoFlow::row()",
                          products="gecko",
                          animation_value_type="discrete",
                          spec="https://drafts.csswg.org/css-grid/#propdef-grid-auto-flow")}

${helpers.predefined_type("grid-template-areas",
                          "GridTemplateAreas",
                          initial_value="computed::GridTemplateAreas::none()",
                          products="gecko",
                          animation_value_type="discrete",
                          gecko_pref="layout.css.grid.enabled",
                          spec="https://drafts.csswg.org/css-grid/#propdef-grid-template-areas")}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

<%! from data import to_rust_ident %>
<%namespace name="helpers" file="/helpers.mako.rs" />
<% from data import ALL_SIZES, PHYSICAL_SIDES, LOGICAL_SIDES %>

<% data.new_style_struct("Position", inherited=False) %>

// "top" / "left" / "bottom" / "right"
% for side in PHYSICAL_SIDES:
    ${helpers.predefined_type(side, "LengthOrPercentageOrAuto",
                              "computed::LengthOrPercentageOrAuto::Auto",
                              spec="https://www.w3.org/TR/CSS2/visuren.html#propdef-%s" % side,
                              animation_value_type="ComputedValue",
                              allow_quirks=True, servo_restyle_damage = "reflow_out_of_flow")}
% endfor
// offset-* logical properties, map to "top" / "left" / "bottom" / "right"
% for side in LOGICAL_SIDES:
    ${helpers.predefined_type("offset-%s" % side, "LengthOrPercentageOrAuto",
                              "computed::LengthOrPercentageOrAuto::Auto",
                              spec="https://drafts.csswg.org/css-logical-props/#propdef-offset-%s" % side,
                              animation_value_type="ComputedValue", logical=True)}
% endfor

#[cfg(feature = "gecko")]
macro_rules! impl_align_conversions {
    ($name: path) => {
        impl From<u8> for $name {
            fn from(bits: u8) -> $name {
                $name(::values::specified::align::AlignFlags::from_bits(bits)
                      .expect("bits contain valid flag"))
            }
        }

        impl From<$name> for u8 {
            fn from(v: $name) -> u8 {
                v.0.bits()
            }
        }
    };
}

${helpers.predefined_type("z-index", "IntegerOrAuto",
                          "Either::Second(Auto)",
                          spec="https://www.w3.org/TR/CSS2/visuren.html#z-index",
                          flags="CREATES_STACKING_CONTEXT",
                          animation_value_type="ComputedValue")}

// CSS Flexible Box Layout Module Level 1
// http://www.w3.org/TR/css3-flexbox/

// Flex container properties
${helpers.single_keyword("flex-direction", "row row-reverse column column-reverse",
                         spec="https://drafts.csswg.org/css-flexbox/#flex-direction-property",
                         extra_prefixes="webkit", animation_value_type="discrete",
                         servo_restyle_damage = "reflow")}

${helpers.single_keyword("flex-wrap", "nowrap wrap wrap-reverse",
                         spec="https://drafts.csswg.org/css-flexbox/#flex-wrap-property",
                         extra_prefixes="webkit", animation_value_type="discrete",
                         servo_restyle_damage = "reflow")}

% if product == "servo":
    // FIXME: Update Servo to support the same Syntax as Gecko.
    ${helpers.single_keyword("justify-content", "flex-start stretch flex-end center space-between space-around",
                             extra_prefixes="webkit",
                             spec="https://drafts.csswg.org/css-align/#propdef-justify-content",
                             animation_value_type="discrete",
                             servo_restyle_damage = "reflow")}
% else:
    ${helpers.predefined_type(name="justify-content",
                              type="JustifyContent",
                              initial_value="specified::JustifyContent(specified::ContentDistribution::normal())",
                              spec="https://drafts.csswg.org/css-align/#propdef-justify-content",
                              extra_prefixes="webkit",
                              animation_value_type="discrete",
                              servo_restyle_damage = "reflow")}
% endif

% if product == "servo":
    // FIXME: Update Servo to support the same Syntax as Gecko.
    ${helpers.single_keyword("align-content", "stretch flex-start flex-end center space-between space-around",
                             extra_prefixes="webkit",
                             spec="https://drafts.csswg.org/css-align/#propdef-align-content",
                             animation_value_type="discrete",
                             servo_restyle_damage = "reflow")}

    ${helpers.single_keyword("align-items",
                             "stretch flex-start flex-end center baseline",
                             extra_prefixes="webkit",
                             spec="https://drafts.csswg.org/css-flexbox/#align-items-property",
                             animation_value_type="discrete",
                             servo_restyle_damage = "reflow")}
% else:
    ${helpers.predefined_type(name="align-content",
                              type="AlignContent",
                              initial_value="specified::AlignContent(specified::ContentDistribution::normal())",
                              spec="https://drafts.csswg.org/css-align/#propdef-align-content",
                              extra_prefixes="webkit",
                              animation_value_type="discrete",
                              servo_restyle_damage = "reflow")}

    ${helpers.predefined_type(name="align-items",
                              type="AlignItems",
                              initial_value="specified::AlignItems::normal()",
                              spec="https://drafts.csswg.org/css-align/#propdef-align-items",
                              extra_prefixes="webkit",
                              animation_value_type="discrete",
                              servo_restyle_damage = "reflow")}

    #[cfg(feature = "gecko")]
    impl_align_conversions!(::values::specified::align::AlignItems);

    ${helpers.predefined_type(name="justify-items",
                              type="JustifyItems",
                              initial_value="computed::JustifyItems::auto()",
                              spec="https://drafts.csswg.org/css-align/#propdef-justify-items",
                              animation_value_type="discrete")}

    #[cfg(feature = "gecko")]
    impl_align_conversions!(::values::specified::align::JustifyItems);
% endif

// Flex item properties
${helpers.predefined_type("flex-grow", "NonNegativeNumber",
                          "From::from(0.0)",
                          spec="https://drafts.csswg.org/css-flexbox/#flex-grow-property",
                          extra_prefixes="webkit",
                          animation_value_type="NonNegativeNumber",
                          servo_restyle_damage = "reflow")}

${helpers.predefined_type("flex-shrink", "NonNegativeNumber",
                          "From::from(1.0)",
                          spec="https://drafts.csswg.org/css-flexbox/#flex-shrink-property",
                          extra_prefixes="webkit",
                          animation_value_type="NonNegativeNumber",
                          servo_restyle_damage = "reflow")}

// https://drafts.csswg.org/css-align/#align-self-property
% if product == "servo":
    // FIXME: Update Servo to support the same syntax as Gecko.
    ${helpers.single_keyword("align-self", "auto stretch flex-start flex-end center baseline",
                             extra_prefixes="webkit",
                             spec="https://drafts.csswg.org/css-flexbox/#propdef-align-self",
                             animation_value_type="discrete",
                             servo_restyle_damage = "reflow")}
% else:
    ${helpers.predefined_type(name="align-self",
                              type="AlignSelf",
                              initial_value="specified::AlignSelf(specified::SelfAlignment::auto())",
                              spec="https://drafts.csswg.org/css-align/#align-self-property",
                              extra_prefixes="webkit",
                              animation_value_type="discrete")}

    ${helpers.predefined_type(name="justify-self",
                              type="JustifySelf",
                              initial_value="specified::JustifySelf(specified::SelfAlignment::auto())",
                              spec="https://drafts.csswg.org/css-align/#justify-self-property",
                              animation_value_type="discrete")}

    #[cfg(feature = "gecko")]
    impl_align_conversions!(::values::specified::align::SelfAlignment);
% endif

// https://drafts.csswg.org/css-flexbox/#propdef-order
${helpers.predefined_type("order", "Integer", "0",
                          extra_prefixes="webkit",
                          animation_value_type="ComputedValue",
                          spec="https://drafts.csswg.org/css-flexbox/#order-property",
                          servo_restyle_damage = "reflow")}

% if product == "gecko":
    // FIXME: Gecko doesn't support content value yet.
    //
    // FIXME(emilio): I suspect this property shouldn't allow quirks, and this
    // was just a mistake, it's kind of justificable to support it given the
    // spec grammar is just `content | <width>`, but other browsers don't...
    ${helpers.predefined_type(
        "flex-basis",
        "MozLength",
        "computed::MozLength::auto()",
        extra_prefixes="webkit",
        animation_value_type="MozLength",
        allow_quirks=True,
        spec="https://drafts.csswg.org/css-flexbox/#flex-basis-property",
        servo_restyle_damage = "reflow"
    )}
% else:
    // FIXME: This property should be animatable.
    ${helpers.predefined_type("flex-basis",
                              "FlexBasis",
                              "computed::FlexBasis::auto()",
                              spec="https://drafts.csswg.org/css-flexbox/#flex-basis-property",
                              extra_prefixes="webkit",
                              animation_value_type="none",
                              servo_restyle_damage = "reflow")}
% endif
% for (size, logical) in ALL_SIZES:
    <%
        spec = "https://drafts.csswg.org/css-box/#propdef-%s"
        if logical:
            spec = "https://drafts.csswg.org/css-logical-props/#propdef-%s"
    %>
    // NOTE: Block-size doesn't support -moz-*-content keywords, since they make
    // no sense on the block axis, but it simplifies things the have that it has
    // the same type as the other properties, since otherwise we'd need to
    // handle logical props where the types are different, which looks like a
    // pain.
    % if product == "gecko":
        <%
            parse_function = "parse" if size != "block-size" else "parse_disallow_keyword"
        %>
        // width, height, block-size, inline-size
        ${helpers.predefined_type(
            size,
            "MozLength",
            "computed::MozLength::auto()",
            parse_function,
            logical=logical,
            allow_quirks=not logical,
            spec=spec % size,
            animation_value_type="MozLength",
            servo_restyle_damage = "reflow"
        )}
        // min-width, min-height, min-block-size, min-inline-size,
        ${helpers.predefined_type(
            "min-%s" % size,
            "MozLength",
            "computed::MozLength::auto()",
            parse_function,
            logical=logical,
            allow_quirks=not logical,
            spec=spec % size,
            animation_value_type="MozLength",
        )}
        ${helpers.predefined_type(
            "max-%s" % size,
            "MaxLength",
            "computed::MaxLength::none()",
            parse_function,
            logical=logical,
            allow_quirks=not logical,
            spec=spec % size,
            animation_value_type="MaxLength",
        )}
    % else:
        // servo versions (no keyword support)
        ${helpers.predefined_type(size,
                                  "LengthOrPercentageOrAuto",
                                  "computed::LengthOrPercentageOrAuto::Auto",
                                  "parse_non_negative",
                                  spec=spec % size,
                                  allow_quirks=not logical,
                                  animation_value_type="ComputedValue", logical = logical,
                                  servo_restyle_damage = "reflow")}
        ${helpers.predefined_type("min-%s" % size,
                                  "LengthOrPercentage",
                                  "computed::LengthOrPercentage::Length(computed::Length::new(0.))",
                                  "parse_non_negative",
                                  spec=spec % ("min-%s" % size),
                                  animation_value_type="ComputedValue",
                                  logical=logical,
                                  allow_quirks=not logical)}
        ${helpers.predefined_type("max-%s" % size,
                                  "LengthOrPercentageOrNone",
                                  "computed::LengthOrPercentageOrNone::None",
                                  "parse_non_negative",
                                  spec=spec % ("min-%s" % size),
                                  animation_value_type="ComputedValue",
                                  logical=logical,
                                  allow_quirks=not logical)}
    % endif
% endfor

${helpers.single_keyword("box-sizing",
                         "content-box border-box",
                         extra_prefixes="moz webkit",
                         spec="https://drafts.csswg.org/css-ui/#propdef-box-sizing",
                         gecko_enum_prefix="StyleBoxSizing",
                         custom_consts={ "content-box": "Content", "border-box": "Border" },
                         animation_value_type="discrete")}

${helpers.single_keyword("object-fit", "fill contain cover none scale-down",
                         products="gecko", animation_value_type="discrete",
                         spec="https://drafts.csswg.org/css-images/#propdef-object-fit")}

${helpers.predefined_type("object-position",
                          "Position",
                          "computed::Position::zero()",
                          products="gecko",
                          boxed=True,
                          spec="https://drafts.csswg.org/css-images-3/#the-object-position",
                          animation_value_type="ComputedValue")}

% for kind in ["row", "column"]:
    ${helpers.predefined_type("grid-%s-gap" % kind,
                              "NonNegativeLengthOrPercentage",
                              "computed::NonNegativeLengthOrPercentage::zero()",
                              spec="https://drafts.csswg.org/css-grid/#propdef-grid-%s-gap" % kind,
                              animation_value_type="NonNegativeLengthOrPercentage",
                              products="gecko")}

    % for range in ["start", "end"]:
        ${helpers.predefined_type("grid-%s-%s" % (kind, range),
                                  "GridLine",
                                  "Default::default()",
                                  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,
                              "TrackSize",
                              "Default::default()",
                              animation_value_type="discrete",
                              spec="https://drafts.csswg.org/css-grid/#propdef-grid-auto-%ss" % kind,
                              products="gecko",
                              boxed=True)}

    ${helpers.predefined_type("grid-template-%ss" % kind,
                              "GridTemplateComponent",
                              "specified::GenericGridTemplateComponent::None",
                              products="gecko",
                              spec="https://drafts.csswg.org/css-grid/#propdef-grid-template-%ss" % kind,
                              boxed=True,
                              animation_value_type="discrete")}

% endfor

${helpers.predefined_type("grid-auto-flow",
                          "GridAutoFlow",
                          initial_value="computed::GridAutoFlow::row()",
                          products="gecko",
                          animation_value_type="discrete",
                          spec="https://drafts.csswg.org/css-grid/#propdef-grid-auto-flow")}

${helpers.predefined_type("grid-template-areas",
                          "GridTemplateAreas",
                          initial_value="computed::GridTemplateAreas::none()",
                          products="gecko",
                          animation_value_type="discrete",
                          gecko_pref="layout.css.grid.enabled",
                          spec="https://drafts.csswg.org/css-grid/#propdef-grid-template-areas")}
<commit_msg>Set damage for min/max width/height to reflow_and_bubble<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

<%! from data import to_rust_ident %>
<%namespace name="helpers" file="/helpers.mako.rs" />
<% from data import ALL_SIZES, PHYSICAL_SIDES, LOGICAL_SIDES %>

<% data.new_style_struct("Position", inherited=False) %>

// "top" / "left" / "bottom" / "right"
% for side in PHYSICAL_SIDES:
    ${helpers.predefined_type(side, "LengthOrPercentageOrAuto",
                              "computed::LengthOrPercentageOrAuto::Auto",
                              spec="https://www.w3.org/TR/CSS2/visuren.html#propdef-%s" % side,
                              animation_value_type="ComputedValue",
                              allow_quirks=True, servo_restyle_damage = "reflow_out_of_flow")}
% endfor
// offset-* logical properties, map to "top" / "left" / "bottom" / "right"
% for side in LOGICAL_SIDES:
    ${helpers.predefined_type("offset-%s" % side, "LengthOrPercentageOrAuto",
                              "computed::LengthOrPercentageOrAuto::Auto",
                              spec="https://drafts.csswg.org/css-logical-props/#propdef-offset-%s" % side,
                              animation_value_type="ComputedValue", logical=True)}
% endfor

#[cfg(feature = "gecko")]
macro_rules! impl_align_conversions {
    ($name: path) => {
        impl From<u8> for $name {
            fn from(bits: u8) -> $name {
                $name(::values::specified::align::AlignFlags::from_bits(bits)
                      .expect("bits contain valid flag"))
            }
        }

        impl From<$name> for u8 {
            fn from(v: $name) -> u8 {
                v.0.bits()
            }
        }
    };
}

${helpers.predefined_type("z-index", "IntegerOrAuto",
                          "Either::Second(Auto)",
                          spec="https://www.w3.org/TR/CSS2/visuren.html#z-index",
                          flags="CREATES_STACKING_CONTEXT",
                          animation_value_type="ComputedValue")}

// CSS Flexible Box Layout Module Level 1
// http://www.w3.org/TR/css3-flexbox/

// Flex container properties
${helpers.single_keyword("flex-direction", "row row-reverse column column-reverse",
                         spec="https://drafts.csswg.org/css-flexbox/#flex-direction-property",
                         extra_prefixes="webkit", animation_value_type="discrete",
                         servo_restyle_damage = "reflow")}

${helpers.single_keyword("flex-wrap", "nowrap wrap wrap-reverse",
                         spec="https://drafts.csswg.org/css-flexbox/#flex-wrap-property",
                         extra_prefixes="webkit", animation_value_type="discrete",
                         servo_restyle_damage = "reflow")}

% if product == "servo":
    // FIXME: Update Servo to support the same Syntax as Gecko.
    ${helpers.single_keyword("justify-content", "flex-start stretch flex-end center space-between space-around",
                             extra_prefixes="webkit",
                             spec="https://drafts.csswg.org/css-align/#propdef-justify-content",
                             animation_value_type="discrete",
                             servo_restyle_damage = "reflow")}
% else:
    ${helpers.predefined_type(name="justify-content",
                              type="JustifyContent",
                              initial_value="specified::JustifyContent(specified::ContentDistribution::normal())",
                              spec="https://drafts.csswg.org/css-align/#propdef-justify-content",
                              extra_prefixes="webkit",
                              animation_value_type="discrete",
                              servo_restyle_damage = "reflow")}
% endif

% if product == "servo":
    // FIXME: Update Servo to support the same Syntax as Gecko.
    ${helpers.single_keyword("align-content", "stretch flex-start flex-end center space-between space-around",
                             extra_prefixes="webkit",
                             spec="https://drafts.csswg.org/css-align/#propdef-align-content",
                             animation_value_type="discrete",
                             servo_restyle_damage = "reflow")}

    ${helpers.single_keyword("align-items",
                             "stretch flex-start flex-end center baseline",
                             extra_prefixes="webkit",
                             spec="https://drafts.csswg.org/css-flexbox/#align-items-property",
                             animation_value_type="discrete",
                             servo_restyle_damage = "reflow")}
% else:
    ${helpers.predefined_type(name="align-content",
                              type="AlignContent",
                              initial_value="specified::AlignContent(specified::ContentDistribution::normal())",
                              spec="https://drafts.csswg.org/css-align/#propdef-align-content",
                              extra_prefixes="webkit",
                              animation_value_type="discrete",
                              servo_restyle_damage = "reflow")}

    ${helpers.predefined_type(name="align-items",
                              type="AlignItems",
                              initial_value="specified::AlignItems::normal()",
                              spec="https://drafts.csswg.org/css-align/#propdef-align-items",
                              extra_prefixes="webkit",
                              animation_value_type="discrete",
                              servo_restyle_damage = "reflow")}

    #[cfg(feature = "gecko")]
    impl_align_conversions!(::values::specified::align::AlignItems);

    ${helpers.predefined_type(name="justify-items",
                              type="JustifyItems",
                              initial_value="computed::JustifyItems::auto()",
                              spec="https://drafts.csswg.org/css-align/#propdef-justify-items",
                              animation_value_type="discrete")}

    #[cfg(feature = "gecko")]
    impl_align_conversions!(::values::specified::align::JustifyItems);
% endif

// Flex item properties
${helpers.predefined_type("flex-grow", "NonNegativeNumber",
                          "From::from(0.0)",
                          spec="https://drafts.csswg.org/css-flexbox/#flex-grow-property",
                          extra_prefixes="webkit",
                          animation_value_type="NonNegativeNumber",
                          servo_restyle_damage = "reflow")}

${helpers.predefined_type("flex-shrink", "NonNegativeNumber",
                          "From::from(1.0)",
                          spec="https://drafts.csswg.org/css-flexbox/#flex-shrink-property",
                          extra_prefixes="webkit",
                          animation_value_type="NonNegativeNumber",
                          servo_restyle_damage = "reflow")}

// https://drafts.csswg.org/css-align/#align-self-property
% if product == "servo":
    // FIXME: Update Servo to support the same syntax as Gecko.
    ${helpers.single_keyword("align-self", "auto stretch flex-start flex-end center baseline",
                             extra_prefixes="webkit",
                             spec="https://drafts.csswg.org/css-flexbox/#propdef-align-self",
                             animation_value_type="discrete",
                             servo_restyle_damage = "reflow")}
% else:
    ${helpers.predefined_type(name="align-self",
                              type="AlignSelf",
                              initial_value="specified::AlignSelf(specified::SelfAlignment::auto())",
                              spec="https://drafts.csswg.org/css-align/#align-self-property",
                              extra_prefixes="webkit",
                              animation_value_type="discrete")}

    ${helpers.predefined_type(name="justify-self",
                              type="JustifySelf",
                              initial_value="specified::JustifySelf(specified::SelfAlignment::auto())",
                              spec="https://drafts.csswg.org/css-align/#justify-self-property",
                              animation_value_type="discrete")}

    #[cfg(feature = "gecko")]
    impl_align_conversions!(::values::specified::align::SelfAlignment);
% endif

// https://drafts.csswg.org/css-flexbox/#propdef-order
${helpers.predefined_type("order", "Integer", "0",
                          extra_prefixes="webkit",
                          animation_value_type="ComputedValue",
                          spec="https://drafts.csswg.org/css-flexbox/#order-property",
                          servo_restyle_damage = "reflow")}

% if product == "gecko":
    // FIXME: Gecko doesn't support content value yet.
    //
    // FIXME(emilio): I suspect this property shouldn't allow quirks, and this
    // was just a mistake, it's kind of justificable to support it given the
    // spec grammar is just `content | <width>`, but other browsers don't...
    ${helpers.predefined_type(
        "flex-basis",
        "MozLength",
        "computed::MozLength::auto()",
        extra_prefixes="webkit",
        animation_value_type="MozLength",
        allow_quirks=True,
        spec="https://drafts.csswg.org/css-flexbox/#flex-basis-property",
        servo_restyle_damage = "reflow"
    )}
% else:
    // FIXME: This property should be animatable.
    ${helpers.predefined_type("flex-basis",
                              "FlexBasis",
                              "computed::FlexBasis::auto()",
                              spec="https://drafts.csswg.org/css-flexbox/#flex-basis-property",
                              extra_prefixes="webkit",
                              animation_value_type="none",
                              servo_restyle_damage = "reflow")}
% endif
% for (size, logical) in ALL_SIZES:
    <%
        spec = "https://drafts.csswg.org/css-box/#propdef-%s"
        if logical:
            spec = "https://drafts.csswg.org/css-logical-props/#propdef-%s"
    %>
    // NOTE: Block-size doesn't support -moz-*-content keywords, since they make
    // no sense on the block axis, but it simplifies things the have that it has
    // the same type as the other properties, since otherwise we'd need to
    // handle logical props where the types are different, which looks like a
    // pain.
    % if product == "gecko":
        <%
            parse_function = "parse" if size != "block-size" else "parse_disallow_keyword"
        %>
        // width, height, block-size, inline-size
        ${helpers.predefined_type(
            size,
            "MozLength",
            "computed::MozLength::auto()",
            parse_function,
            logical=logical,
            allow_quirks=not logical,
            spec=spec % size,
            animation_value_type="MozLength",
            servo_restyle_damage = "reflow"
        )}
        // min-width, min-height, min-block-size, min-inline-size,
        ${helpers.predefined_type(
            "min-%s" % size,
            "MozLength",
            "computed::MozLength::auto()",
            parse_function,
            logical=logical,
            allow_quirks=not logical,
            spec=spec % size,
            animation_value_type="MozLength",
            servo_restyle_damage = "reflow"
        )}
        ${helpers.predefined_type(
            "max-%s" % size,
            "MaxLength",
            "computed::MaxLength::none()",
            parse_function,
            logical=logical,
            allow_quirks=not logical,
            spec=spec % size,
            animation_value_type="MaxLength",
            servo_restyle_damage = "reflow"
        )}
    % else:
        // servo versions (no keyword support)
        ${helpers.predefined_type(size,
                                  "LengthOrPercentageOrAuto",
                                  "computed::LengthOrPercentageOrAuto::Auto",
                                  "parse_non_negative",
                                  spec=spec % size,
                                  allow_quirks=not logical,
                                  animation_value_type="ComputedValue", logical = logical,
                                  servo_restyle_damage = "reflow")}
        ${helpers.predefined_type("min-%s" % size,
                                  "LengthOrPercentage",
                                  "computed::LengthOrPercentage::Length(computed::Length::new(0.))",
                                  "parse_non_negative",
                                  spec=spec % ("min-%s" % size),
                                  animation_value_type="ComputedValue",
                                  logical=logical,
                                  allow_quirks=not logical,
                                  servo_restyle_damage = "reflow")}
        ${helpers.predefined_type("max-%s" % size,
                                  "LengthOrPercentageOrNone",
                                  "computed::LengthOrPercentageOrNone::None",
                                  "parse_non_negative",
                                  spec=spec % ("min-%s" % size),
                                  animation_value_type="ComputedValue",
                                  logical=logical,
                                  allow_quirks=not logical,
                                  servo_restyle_damage = "reflow")}
    % endif
% endfor

${helpers.single_keyword("box-sizing",
                         "content-box border-box",
                         extra_prefixes="moz webkit",
                         spec="https://drafts.csswg.org/css-ui/#propdef-box-sizing",
                         gecko_enum_prefix="StyleBoxSizing",
                         custom_consts={ "content-box": "Content", "border-box": "Border" },
                         animation_value_type="discrete")}

${helpers.single_keyword("object-fit", "fill contain cover none scale-down",
                         products="gecko", animation_value_type="discrete",
                         spec="https://drafts.csswg.org/css-images/#propdef-object-fit")}

${helpers.predefined_type("object-position",
                          "Position",
                          "computed::Position::zero()",
                          products="gecko",
                          boxed=True,
                          spec="https://drafts.csswg.org/css-images-3/#the-object-position",
                          animation_value_type="ComputedValue")}

% for kind in ["row", "column"]:
    ${helpers.predefined_type("grid-%s-gap" % kind,
                              "NonNegativeLengthOrPercentage",
                              "computed::NonNegativeLengthOrPercentage::zero()",
                              spec="https://drafts.csswg.org/css-grid/#propdef-grid-%s-gap" % kind,
                              animation_value_type="NonNegativeLengthOrPercentage",
                              products="gecko")}

    % for range in ["start", "end"]:
        ${helpers.predefined_type("grid-%s-%s" % (kind, range),
                                  "GridLine",
                                  "Default::default()",
                                  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,
                              "TrackSize",
                              "Default::default()",
                              animation_value_type="discrete",
                              spec="https://drafts.csswg.org/css-grid/#propdef-grid-auto-%ss" % kind,
                              products="gecko",
                              boxed=True)}

    ${helpers.predefined_type("grid-template-%ss" % kind,
                              "GridTemplateComponent",
                              "specified::GenericGridTemplateComponent::None",
                              products="gecko",
                              spec="https://drafts.csswg.org/css-grid/#propdef-grid-template-%ss" % kind,
                              boxed=True,
                              animation_value_type="discrete")}

% endfor

${helpers.predefined_type("grid-auto-flow",
                          "GridAutoFlow",
                          initial_value="computed::GridAutoFlow::row()",
                          products="gecko",
                          animation_value_type="discrete",
                          spec="https://drafts.csswg.org/css-grid/#propdef-grid-auto-flow")}

${helpers.predefined_type("grid-template-areas",
                          "GridTemplateAreas",
                          initial_value="computed::GridTemplateAreas::none()",
                          products="gecko",
                          animation_value_type="discrete",
                          gecko_pref="layout.css.grid.enabled",
                          spec="https://drafts.csswg.org/css-grid/#propdef-grid-template-areas")}
<|endoftext|>


<commit_before>// See LICENSE file for copyright and license details.

use extra::json;
use serialize::Decodable;
use glfw;
use gl;
use gl::types::{
  GLfloat,
  GLint,
  GLuint,
};
use cgmath::vector::{
  Vec3,
  Vec2,
};
use glh = gl_helpers;
use camera::Camera;
use map::TileIterator;
use geom::Geom;
use tile_picker::TilePicker;
use obj;
use mesh::Mesh;
use misc::read_file;

fn build_hex_mesh(&geom: &Geom) -> ~[Vec3<GLfloat>] {
  let mut vertex_data = ~[];
  for tile_pos in TileIterator::new() {
    let pos3d = geom.map_pos_to_world_pos(tile_pos);
    for num in range(0, 6) {
      let vertex = geom.index_to_hex_vertex(num);
      let next_vertex = geom.index_to_hex_vertex(num + 1);
      vertex_data.push(pos3d + vertex);
      vertex_data.push(pos3d + next_vertex);
      vertex_data.push(pos3d + Vec3::zero());
    }
  }
  vertex_data
}

fn build_hex_tex_coord() -> ~[Vec2<GLfloat>] {
  let mut vertex_data = ~[];
  for _ in TileIterator::new() {
    for _ in range(0, 6) {
      vertex_data.push(Vec2{x: 0.0, y: 0.0});
      vertex_data.push(Vec2{x: 1.0, y: 0.0});
      vertex_data.push(Vec2{x: 0.5, y: 0.5});
    }
  }
  vertex_data
}

pub struct Visualizer {
  program: GLuint,
  map_mesh: Mesh,
  unit_mesh: Mesh,
  mat_id: GLint,
  win: Option<glfw::Window>,
  mouse_pos: Vec2<f32>,
  camera: Camera,
  picker: TilePicker,
  selected_tile_pos: Option<Vec2<i32>>,
  geom: Geom,
  unit_texture_id: GLuint,
  floor_texture_id: GLuint,
}

fn init_win(win_size: Vec2<int>) -> glfw::Window {
  glfw::set_error_callback(~glfw::LogErrorHandler);
  let init_status = glfw::init();
  if !init_status.is_ok() {
    fail!("Failed to initialize GLFW");
  }
  let win = glfw::Window::create(
    win_size.x as u32,
    win_size.y as u32,
    "Marauder",
    glfw::Windowed,
  ).unwrap();
  win.make_context_current();
  win.set_all_polling(true);
  win
}

#[deriving(Decodable)]
struct Size2<T> {
  x: T,
  y: T,
}

fn read_win_size(config_path: &str) -> Vec2<int> {
  let path = Path::new(config_path);
  let json = json::from_str(read_file(&path)).unwrap();
  let mut decoder = json::Decoder::new(json);
  let size: Size2<int> = Decodable::decode(&mut decoder);
  Vec2{x: size.x, y: size.y}
}

impl Visualizer {
  pub fn new() -> ~Visualizer {
    let win_size = read_win_size("config.json");
    let win = init_win(win_size);
    let geom = Geom::new();
    let mut vis = ~Visualizer {
      program: 0,
      map_mesh: Mesh::new(),
      unit_mesh: Mesh::new(),
      mat_id: 0,
      win: Some(win),
      mouse_pos: Vec2::zero(),
      camera: Camera::new(),
      picker: TilePicker::new(),
      selected_tile_pos: None,
      geom: geom,
      unit_texture_id: 0,
      floor_texture_id: 0,
    };
    vis.init_opengl();
    vis.picker.init(&geom);
    vis.init_models();
    vis.init_textures();
    vis
  }

  fn init_textures(&mut self) {
    self.unit_texture_id = glh::load_texture(~"data/tank.png");
    self.floor_texture_id = glh::load_texture(~"data/floor.png");
  }

  fn win<'a>(&'a self) -> &'a glfw::Window {
    self.win.get_ref()
  }

  fn init_models(&mut self) {
    self.program = glh::compile_program(
      read_file(&Path::new("normal.vs.glsl")),
      read_file(&Path::new("normal.fs.glsl")),
    );
    gl::UseProgram(self.program);
    self.mat_id = glh::get_uniform(self.program, "mvp_mat");
    let position_attr = glh::get_attr(self.program, "position");
    gl::EnableVertexAttribArray(position_attr);
    glh::vertex_attrib_pointer(position_attr, 3);
    let vt_attr = glh::get_attr(self.program, "vt");
    gl::EnableVertexAttribArray(vt_attr);
    glh::vertex_attrib_pointer(vt_attr, 3);
    let map_vertex_data = build_hex_mesh(&self.geom);
    self.map_mesh.init(map_vertex_data);
    self.map_mesh.set_vt(build_hex_tex_coord());
    let unit_obj = obj::Model::new("data/tank.obj");
    self.unit_mesh.init(unit_obj.build());
    self.unit_mesh.set_vt(unit_obj.build_tex_coord());
  }

  fn init_opengl(&mut self) {
    gl::load_with(glfw::get_proc_address);
    gl::Enable(gl::DEPTH_TEST);
  }

  fn cleanup_opengl(&self) {
    gl::DeleteProgram(self.program);
  }

  fn draw_unit_at(&self, pos: Vec2<i32>) {
    let world_pos = self.geom.map_pos_to_world_pos(pos);
    let m = glh::tr(self.camera.mat(), world_pos);
    glh::uniform_mat4f(self.mat_id, &m);
    self.unit_mesh.draw(self.program);
  }

  fn draw_units(&self) {
    gl::UseProgram(self.program);
    let baic_texture_loc = glh::get_uniform(self.program, "basic_texture!");
    gl::Uniform1ui(baic_texture_loc, 0);
    gl::ActiveTexture(gl::TEXTURE0);
    gl::BindTexture(gl::TEXTURE_2D, self.unit_texture_id);
    self.draw_unit_at(Vec2{x: 0, y: 0});
    self.draw_unit_at(Vec2{x: 1, y: 0});
    self.draw_unit_at(Vec2{x: 2, y: 0});
    self.draw_unit_at(Vec2{x: 1, y: 1});
    if !self.selected_tile_pos.is_none() {
      let p = self.selected_tile_pos.unwrap();
      self.draw_unit_at(p);
    }
  }

  fn draw_map(&self) {
    let baic_texture_loc = glh::get_uniform(self.program, "basic_texture!");
    gl::Uniform1ui(baic_texture_loc, 0);
    gl::ActiveTexture(gl::TEXTURE0);
    gl::BindTexture(gl::TEXTURE_2D, self.floor_texture_id);
    glh::uniform_mat4f(self.mat_id, &self.camera.mat());
    self.map_mesh.draw(self.program);
  }

  fn draw(&self) {
    gl::ClearColor(0.3, 0.3, 0.3, 1.0);
    gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
    gl::UseProgram(self.program);
    self.draw_units();
    self.draw_map();
    self.win().swap_buffers();
  }

  pub fn is_running(&self) -> bool {
    return !self.win().should_close()
  }

  fn handle_key_event(&mut self, key: glfw::Key) {
    match key {
      glfw::KeyEscape | glfw::KeyQ => {
        self.win().set_should_close(true);
      },
      glfw::KeySpace => println!("space"),
      glfw::KeyUp => self.camera.move(270.0),
      glfw::KeyDown => self.camera.move(90.0),
      glfw::KeyRight => self.camera.move(0.0),
      glfw::KeyLeft => self.camera.move(180.0),
      glfw::KeyMinus => self.camera.zoom += 1.0,
      glfw::KeyEqual => self.camera.zoom -= 1.0,
      _ => {},
    }
  }

  fn handle_cursor_pos_event(&mut self, pos: Vec2<f32>) {
    let button = self.win().get_mouse_button(glfw::MouseButtonRight);
    if button == glfw::Press {
      self.camera.z_angle += (self.mouse_pos.x - pos.x) / 2.0;
      self.camera.x_angle += (self.mouse_pos.y - pos.y) / 2.0;
    }
    self.mouse_pos = pos;
  }

  fn get_events(&mut self) -> ~[glfw::WindowEvent]{
    glfw::poll_events();
    let mut events = ~[];
    for (_, event) in self.win().flush_events() {
      events.push(event);
    }
    events
  }

  fn handle_event(&mut self, event: glfw::WindowEvent) {
    match event {
      glfw::KeyEvent(key, _, glfw::Press, _) => {
        self.handle_key_event(key);
      },
      glfw::CursorPosEvent(x, y) => {
        let p = Vec2{x: x as f32, y: y as f32};
        self.handle_cursor_pos_event(p);
      },
      glfw::SizeEvent(w, h) => {
        gl::Viewport(0, 0, w, h);
      },
      _ => {},
    }
  }

  fn handle_events(&mut self) {
    for event in self.get_events().iter() {
      self.handle_event(*event);
    }
  }

  fn pick_tile(&mut self) {
    let mouse_pos = Vec2 {
      x: self.mouse_pos.x as i32,
      y: self.mouse_pos.y as i32,
    };
    let win_size = self.win().get_size();
    self.selected_tile_pos = self.picker.pick_tile(
      win_size, &self.camera, mouse_pos);
  }

  pub fn tick(&mut self) {
    self.handle_events();
    self.pick_tile();
    self.draw();
  }
}

impl Drop for Visualizer {
  fn drop(&mut self) {
    self.cleanup_opengl();
  }
}

// vim: set tabstop=2 shiftwidth=2 softtabstop=2 expandtab:
<commit_msg>Visualizer: fixed typo<commit_after>// See LICENSE file for copyright and license details.

use extra::json;
use serialize::Decodable;
use glfw;
use gl;
use gl::types::{
  GLfloat,
  GLint,
  GLuint,
};
use cgmath::vector::{
  Vec3,
  Vec2,
};
use glh = gl_helpers;
use camera::Camera;
use map::TileIterator;
use geom::Geom;
use tile_picker::TilePicker;
use obj;
use mesh::Mesh;
use misc::read_file;

fn build_hex_mesh(&geom: &Geom) -> ~[Vec3<GLfloat>] {
  let mut vertex_data = ~[];
  for tile_pos in TileIterator::new() {
    let pos3d = geom.map_pos_to_world_pos(tile_pos);
    for num in range(0, 6) {
      let vertex = geom.index_to_hex_vertex(num);
      let next_vertex = geom.index_to_hex_vertex(num + 1);
      vertex_data.push(pos3d + vertex);
      vertex_data.push(pos3d + next_vertex);
      vertex_data.push(pos3d + Vec3::zero());
    }
  }
  vertex_data
}

fn build_hex_tex_coord() -> ~[Vec2<GLfloat>] {
  let mut vertex_data = ~[];
  for _ in TileIterator::new() {
    for _ in range(0, 6) {
      vertex_data.push(Vec2{x: 0.0, y: 0.0});
      vertex_data.push(Vec2{x: 1.0, y: 0.0});
      vertex_data.push(Vec2{x: 0.5, y: 0.5});
    }
  }
  vertex_data
}

pub struct Visualizer {
  program: GLuint,
  map_mesh: Mesh,
  unit_mesh: Mesh,
  mat_id: GLint,
  win: Option<glfw::Window>,
  mouse_pos: Vec2<f32>,
  camera: Camera,
  picker: TilePicker,
  selected_tile_pos: Option<Vec2<i32>>,
  geom: Geom,
  unit_texture_id: GLuint,
  floor_texture_id: GLuint,
}

fn init_win(win_size: Vec2<int>) -> glfw::Window {
  glfw::set_error_callback(~glfw::LogErrorHandler);
  let init_status = glfw::init();
  if !init_status.is_ok() {
    fail!("Failed to initialize GLFW");
  }
  let win = glfw::Window::create(
    win_size.x as u32,
    win_size.y as u32,
    "Marauder",
    glfw::Windowed,
  ).unwrap();
  win.make_context_current();
  win.set_all_polling(true);
  win
}

#[deriving(Decodable)]
struct Size2<T> {
  x: T,
  y: T,
}

fn read_win_size(config_path: &str) -> Vec2<int> {
  let path = Path::new(config_path);
  let json = json::from_str(read_file(&path)).unwrap();
  let mut decoder = json::Decoder::new(json);
  let size: Size2<int> = Decodable::decode(&mut decoder);
  Vec2{x: size.x, y: size.y}
}

impl Visualizer {
  pub fn new() -> ~Visualizer {
    let win_size = read_win_size("config.json");
    let win = init_win(win_size);
    let geom = Geom::new();
    let mut vis = ~Visualizer {
      program: 0,
      map_mesh: Mesh::new(),
      unit_mesh: Mesh::new(),
      mat_id: 0,
      win: Some(win),
      mouse_pos: Vec2::zero(),
      camera: Camera::new(),
      picker: TilePicker::new(),
      selected_tile_pos: None,
      geom: geom,
      unit_texture_id: 0,
      floor_texture_id: 0,
    };
    vis.init_opengl();
    vis.picker.init(&geom);
    vis.init_models();
    vis.init_textures();
    vis
  }

  fn init_textures(&mut self) {
    self.unit_texture_id = glh::load_texture(~"data/tank.png");
    self.floor_texture_id = glh::load_texture(~"data/floor.png");
  }

  fn win<'a>(&'a self) -> &'a glfw::Window {
    self.win.get_ref()
  }

  fn init_models(&mut self) {
    self.program = glh::compile_program(
      read_file(&Path::new("normal.vs.glsl")),
      read_file(&Path::new("normal.fs.glsl")),
    );
    gl::UseProgram(self.program);
    self.mat_id = glh::get_uniform(self.program, "mvp_mat");
    let position_attr = glh::get_attr(self.program, "position");
    gl::EnableVertexAttribArray(position_attr);
    glh::vertex_attrib_pointer(position_attr, 3);
    let vt_attr = glh::get_attr(self.program, "vt");
    gl::EnableVertexAttribArray(vt_attr);
    glh::vertex_attrib_pointer(vt_attr, 3);
    let map_vertex_data = build_hex_mesh(&self.geom);
    self.map_mesh.init(map_vertex_data);
    self.map_mesh.set_vt(build_hex_tex_coord());
    let unit_obj = obj::Model::new("data/tank.obj");
    self.unit_mesh.init(unit_obj.build());
    self.unit_mesh.set_vt(unit_obj.build_tex_coord());
  }

  fn init_opengl(&mut self) {
    gl::load_with(glfw::get_proc_address);
    gl::Enable(gl::DEPTH_TEST);
  }

  fn cleanup_opengl(&self) {
    gl::DeleteProgram(self.program);
  }

  fn draw_unit_at(&self, pos: Vec2<i32>) {
    let world_pos = self.geom.map_pos_to_world_pos(pos);
    let m = glh::tr(self.camera.mat(), world_pos);
    glh::uniform_mat4f(self.mat_id, &m);
    self.unit_mesh.draw(self.program);
  }

  fn draw_units(&self) {
    gl::UseProgram(self.program);
    let basic_texture_loc = glh::get_uniform(self.program, "basic_texture!");
    gl::Uniform1ui(basic_texture_loc, 0);
    gl::ActiveTexture(gl::TEXTURE0);
    gl::BindTexture(gl::TEXTURE_2D, self.unit_texture_id);
    self.draw_unit_at(Vec2{x: 0, y: 0});
    self.draw_unit_at(Vec2{x: 1, y: 0});
    self.draw_unit_at(Vec2{x: 2, y: 0});
    self.draw_unit_at(Vec2{x: 1, y: 1});
    if !self.selected_tile_pos.is_none() {
      let p = self.selected_tile_pos.unwrap();
      self.draw_unit_at(p);
    }
  }

  fn draw_map(&self) {
    let basic_texture_loc = glh::get_uniform(self.program, "basic_texture!");
    gl::Uniform1ui(basic_texture_loc, 0);
    gl::ActiveTexture(gl::TEXTURE0);
    gl::BindTexture(gl::TEXTURE_2D, self.floor_texture_id);
    glh::uniform_mat4f(self.mat_id, &self.camera.mat());
    self.map_mesh.draw(self.program);
  }

  fn draw(&self) {
    gl::ClearColor(0.3, 0.3, 0.3, 1.0);
    gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
    gl::UseProgram(self.program);
    self.draw_units();
    self.draw_map();
    self.win().swap_buffers();
  }

  pub fn is_running(&self) -> bool {
    return !self.win().should_close()
  }

  fn handle_key_event(&mut self, key: glfw::Key) {
    match key {
      glfw::KeyEscape | glfw::KeyQ => {
        self.win().set_should_close(true);
      },
      glfw::KeySpace => println!("space"),
      glfw::KeyUp => self.camera.move(270.0),
      glfw::KeyDown => self.camera.move(90.0),
      glfw::KeyRight => self.camera.move(0.0),
      glfw::KeyLeft => self.camera.move(180.0),
      glfw::KeyMinus => self.camera.zoom += 1.0,
      glfw::KeyEqual => self.camera.zoom -= 1.0,
      _ => {},
    }
  }

  fn handle_cursor_pos_event(&mut self, pos: Vec2<f32>) {
    let button = self.win().get_mouse_button(glfw::MouseButtonRight);
    if button == glfw::Press {
      self.camera.z_angle += (self.mouse_pos.x - pos.x) / 2.0;
      self.camera.x_angle += (self.mouse_pos.y - pos.y) / 2.0;
    }
    self.mouse_pos = pos;
  }

  fn get_events(&mut self) -> ~[glfw::WindowEvent]{
    glfw::poll_events();
    let mut events = ~[];
    for (_, event) in self.win().flush_events() {
      events.push(event);
    }
    events
  }

  fn handle_event(&mut self, event: glfw::WindowEvent) {
    match event {
      glfw::KeyEvent(key, _, glfw::Press, _) => {
        self.handle_key_event(key);
      },
      glfw::CursorPosEvent(x, y) => {
        let p = Vec2{x: x as f32, y: y as f32};
        self.handle_cursor_pos_event(p);
      },
      glfw::SizeEvent(w, h) => {
        gl::Viewport(0, 0, w, h);
      },
      _ => {},
    }
  }

  fn handle_events(&mut self) {
    for event in self.get_events().iter() {
      self.handle_event(*event);
    }
  }

  fn pick_tile(&mut self) {
    let mouse_pos = Vec2 {
      x: self.mouse_pos.x as i32,
      y: self.mouse_pos.y as i32,
    };
    let win_size = self.win().get_size();
    self.selected_tile_pos = self.picker.pick_tile(
      win_size, &self.camera, mouse_pos);
  }

  pub fn tick(&mut self) {
    self.handle_events();
    self.pick_tile();
    self.draw();
  }
}

impl Drop for Visualizer {
  fn drop(&mut self) {
    self.cleanup_opengl();
  }
}

// vim: set tabstop=2 shiftwidth=2 softtabstop=2 expandtab:
<|endoftext|>