Repository: LadybirdBrowser/ladybird
File: Libraries/LibWeb/CSS/StyleValues/KeywordStyleValue.cpp (C++)

Code before:
    case Keyword::Windowtext:
        return true;
    default:
        return false;
    }
}

bool KeywordStyleValue::has_color() const
{
    return is_color(keyword());
}

Optional<Color> KeywordStyleValue::to_color(ColorResolutionContext color_resolution_context) const
{
    if (keyword() == Keyword::Currentcolor) {
        return color_resolution_context.current_color.value_or(Color::Black);
    }

    PreferredColorScheme scheme = color_resolution_context.color_scheme.value_or(PreferredColorScheme::Light);

    if (keyword() == Keyword::Accentcolortext) {
        // Calculate accent_color_text based on contrast to accent_color
        auto constexpr min_contrast = 2;
        auto system_accent_text = SystemColor::accent_color_text(scheme);

        if (color_resolution_context.accent_color.value_or({}).contrast_ratio(system_accent_text) < min_contrast)
            return system_accent_text.inverted();
            
        return system_accent_text;
    }

    // First, handle <system-color>s, since they don't strictly require a node.
    // https://www.w3.org/TR/css-color-4/#css-system-colors
    // https://www.w3.org/TR/css-color-4/#deprecated-system-colors
    switch (keyword()) {
    case Keyword::Accentcolor:
        return color_resolution_context.accent_color.value_or(SystemColor::accent_color(scheme));
    case Keyword::Buttonborder:
    case Keyword::Activeborder:
    case Keyword::Inactiveborder:
    case Keyword::Threeddarkshadow:
    case Keyword::Threedhighlight:
    case Keyword::Threedlightshadow:
    case Keyword::Threedshadow:
    case Keyword::Windowframe:
        return SystemColor::button_border(scheme);
    case Keyword::Buttonface:
    case Keyword::Buttonhighlight:
    case Keyword::Buttonshadow:
    case Keyword::Threedface:
        return SystemColor::button_face(scheme);

Review comment (suggestion):
The `value_or({})` means it's assuming the accent color is transparent black if it's not passed in. It should be `color_resolution_context.accent_color.value_or(SystemColor::accent_color(scheme))` like in the code below.

Code after:
    case Keyword::Windowtext:
        return true;
    default:
        return false;
    }
}

bool KeywordStyleValue::has_color() const
{
    return is_color(keyword());
}

Optional<Color> KeywordStyleValue::to_color(ColorResolutionContext color_resolution_context) const
{
    if (keyword() == Keyword::Currentcolor) {
        return color_resolution_context.current_color.value_or(Color::Black);
    }

    PreferredColorScheme scheme = color_resolution_context.color_scheme.value_or(PreferredColorScheme::Light);

    // Calculate accent_color_text based on contrast to accent_color
    if (keyword() == Keyword::Accentcolortext) {
        // min_contrast = 10.2 is a magic number which provides the best accessibility trade-off based on:
        // 1. https://webaim.org/resources/contrastchecker/
        // 2. Current implementation of luminosity() and contrast_ratio() methods for Color instances

        // the baseline colors with the least contrast from black and white are #757575 and #767676
        // which score over 4.5 ratio for #fff and #000 accent_color_text values correspondingly
        auto constexpr min_contrast = 10.2;
        auto system_accent_text = SystemColor::accent_color_text(scheme);

        if (color_resolution_context.accent_color.value_or(SystemColor::accent_color(scheme)).contrast_ratio(system_accent_text) < min_contrast)
            return system_accent_text.inverted();

        return system_accent_text;
    }

    // First, handle <system-color>s, since they don't strictly require a node.
    // https://www.w3.org/TR/css-color-4/#css-system-colors
    // https://www.w3.org/TR/css-color-4/#deprecated-system-colors
    switch (keyword()) {
    case Keyword::Accentcolor:
        return color_resolution_context.accent_color.value_or(SystemColor::accent_color(scheme));
    case Keyword::Buttonborder:
    case Keyword::Activeborder:
    case Keyword::Inactiveborder:
    case Keyword::Threeddarkshadow:
    case Keyword::Threedhighlight:
    case Keyword::Threedlightshadow:
    case Keyword::Threedshadow:
    case Keyword::Windowframe: