Repository: LadybirdBrowser/ladybird
File: Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp (C++)

Code before:
    switch (property_id) {
    case PropertyID::Border:
        color_property = PropertyID::BorderColor;
        style_property = PropertyID::BorderStyle;
        width_property = PropertyID::BorderWidth;
        break;
    case PropertyID::BorderBlock:
        color_property = PropertyID::BorderBlockColor;
        style_property = PropertyID::BorderBlockStyle;
        width_property = PropertyID::BorderBlockWidth;
        break;
    case PropertyID::BorderInline:
        color_property = PropertyID::BorderInlineColor;
        style_property = PropertyID::BorderInlineStyle;
        width_property = PropertyID::BorderInlineWidth;
        break;

    default:
        VERIFY_NOT_REACHED();
    }

    auto const make_single_value_shorthand = [&](PropertyID property_id, Vector<PropertyID> const& longhands, ValueComparingNonnullRefPtr<StyleValue const> const& value) {
        Vector<ValueComparingNonnullRefPtr<StyleValue const>> longhand_values;

        for (size_t i = 0; i < longhands.size(); i++)
            longhand_values.append(value);

        return ShorthandStyleValue::create(property_id, longhands, longhand_values);
    };

    auto remaining_longhands = Vector { width_property, color_property, style_property };
    auto transaction = tokens.begin_transaction();

    while (tokens.has_next_token()) {
        auto property_and_value = parse_css_value_for_properties(remaining_longhands, tokens);
        if (!property_and_value.has_value())
            return nullptr;
        auto& value = property_and_value->style_value;
        remove_property(remaining_longhands, property_and_value->property);

        if (property_and_value->property == width_property) {
            VERIFY(!border_width);
            border_width = make_single_value_shorthand(width_property, longhands_for_shorthand(width_property), value.release_nonnull());
        } else if (property_and_value->property == color_property) {
            VERIFY(!border_color);
            border_color = make_single_value_shorthand(color_property, longhands_for_shorthand(color_property), value.release_nonnull());
        } else if (property_and_value->property == style_property) {
            VERIFY(!border_style);
            border_style = make_single_value_shorthand(style_property, longhands_for_shorthand(style_property), value.release_nonnull());
        } else {
            VERIFY_NOT_REACHED();

Review comment (suggestion):
I think you should be able to do `longhand_values.resize_with_default_value(longhands.size(), value);` here

Code after:
        if (style_value.is_length())
            return LengthPercentage { style_value.as_length().length() };
        if (style_value.is_calculated())
            return LengthPercentage { style_value.as_calculated() };
        return {};
    };

    auto maybe_x_value = parse_css_value_for_property(property, tokens);
    if (!maybe_x_value)
        return nullptr;
    auto x_value = maybe_x_value.release_nonnull();

    if (x_value->to_keyword() == Keyword::Cover || x_value->to_keyword() == Keyword::Contain) {
        transaction.commit();
        return x_value;
    }

    auto maybe_y_value = parse_css_value_for_property(property, tokens);
    if (!maybe_y_value) {
        auto y_value = LengthPercentageOrAuto::make_auto();
        auto x_size = get_length_percentage_or_auto(*x_value);
        if (!x_size.has_value())
            return nullptr;

        transaction.commit();
        return BackgroundSizeStyleValue::create(x_size.value(), y_value);
    }

    auto y_value = maybe_y_value.release_nonnull();
    auto x_size = get_length_percentage_or_auto(*x_value);
    auto y_size = get_length_percentage_or_auto(*y_value);

    if (!x_size.has_value() || !y_size.has_value())
        return nullptr;

    transaction.commit();
    return BackgroundSizeStyleValue::create(x_size.release_value(), y_size.release_value());
}

RefPtr<StyleValue const> Parser::parse_border_value(PropertyID property_id, TokenStream<ComponentValue>& tokens)
{
    RefPtr<StyleValue const> border_width;
    RefPtr<StyleValue const> border_color;
    RefPtr<StyleValue const> border_style;

    auto color_property = PropertyID::Invalid;
    auto style_property = PropertyID::Invalid;
    auto width_property = PropertyID::Invalid;

    switch (property_id) {
    case PropertyID::Border: