Skip to content

Commit

Permalink
WIP: Add alpha parameter to color inputs
Browse files Browse the repository at this point in the history
This is a start on whatwg/html#10456 but it
turns out that our types don't work in a way that's compatible with
this, so I'm leaving it for now.
  • Loading branch information
AtkinsSJ committed Oct 31, 2024
1 parent 76e638b commit 2d9b062
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 5 deletions.
27 changes: 27 additions & 0 deletions Userland/Libraries/LibWeb/CSS/Parser/Helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <LibWeb/CSS/CSSRuleList.h>
#include <LibWeb/CSS/CSSStyleSheet.h>
#include <LibWeb/CSS/Parser/Parser.h>
#include <LibWeb/CSS/StyleValues/CSSRGB.h>

namespace Web {

Expand Down Expand Up @@ -83,4 +84,30 @@ Optional<CSS::StyleProperty> parse_css_supports_condition(CSS::Parser::ParsingCo
return CSS::Parser::Parser::create(context, string).parse_as_supports_condition();
}

// https://drafts.csswg.org/css-color/#parse-color
RefPtr<CSS::CSSColorValue> parse_a_css_color_value(CSS::Parser::ParsingContext const& context, StringView input, Optional<DOM::Element&> element)
{
// 1. Parse input as a <color>. If the result is failure, return failure; otherwise, let color be the result.
auto color = CSS::Parser::Parser::create(context, input).parse_as_css_value(CSS::PropertyID::Color);
if (!color)
return {};

// 2. Let used color be the result of resolving color to a used color.
// If the value of other properties on the element a <color> is on is required to do the resolution (such as resolving a currentcolor or system color),
// use element if it was passed, or the initial values of the properties if not.
RefPtr<CSS::CSSColorValue> used_color;
if (color->is_color()) {
// FIXME: We should resolve things like calc(), var(), and attr() here.
used_color = color->as_color();
} else if (color->is_keyword()) {
auto layout_node = element.has_value() ? element->layout_node() : OptionalNone {};
used_color = CSS::CSSRGB::create_from_color(color->to_color(layout_node));
} else {
dbgln("Unsupported type parsed in parse_a_css_color_value(): {}", color->to_string());
}

// 3. Return used color.
return used_color;
}

}
1 change: 1 addition & 0 deletions Userland/Libraries/LibWeb/CSS/Parser/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -411,5 +411,6 @@ RefPtr<CSS::MediaQuery> parse_media_query(CSS::Parser::ParsingContext const&, St
Vector<NonnullRefPtr<CSS::MediaQuery>> parse_media_query_list(CSS::Parser::ParsingContext const&, StringView);
RefPtr<CSS::Supports> parse_css_supports(CSS::Parser::ParsingContext const&, StringView);
Optional<CSS::StyleProperty> parse_css_supports_condition(CSS::Parser::ParsingContext const&, StringView);
RefPtr<CSS::CSSColorValue> parse_a_css_color_value(CSS::Parser::ParsingContext const&, StringView, Optional<DOM::Element&>);

}
2 changes: 2 additions & 0 deletions Userland/Libraries/LibWeb/HTML/AttributeNames.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ namespace AttributeNames {
__ENUMERATE_HTML_ATTRIBUTE(alink) \
__ENUMERATE_HTML_ATTRIBUTE(allow) \
__ENUMERATE_HTML_ATTRIBUTE(allowfullscreen) \
__ENUMERATE_HTML_ATTRIBUTE(alpha) \
__ENUMERATE_HTML_ATTRIBUTE(alt) \
__ENUMERATE_HTML_ATTRIBUTE(archive) \
__ENUMERATE_HTML_ATTRIBUTE(async) \
Expand All @@ -48,6 +49,7 @@ namespace AttributeNames {
__ENUMERATE_HTML_ATTRIBUTE(codebase) \
__ENUMERATE_HTML_ATTRIBUTE(codetype) \
__ENUMERATE_HTML_ATTRIBUTE(color) \
__ENUMERATE_HTML_ATTRIBUTE(colorspace) \
__ENUMERATE_HTML_ATTRIBUTE(cols) \
__ENUMERATE_HTML_ATTRIBUTE(colspan) \
__ENUMERATE_HTML_ATTRIBUTE(compact) \
Expand Down
61 changes: 56 additions & 5 deletions Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
#include <LibJS/Runtime/Date.h>
#include <LibJS/Runtime/NativeFunction.h>
#include <LibWeb/Bindings/HTMLInputElementPrototype.h>
#include <LibWeb/CSS/Parser/Parser.h>
#include <LibWeb/CSS/StyleValues/CSSKeywordValue.h>
#include <LibWeb/CSS/StyleValues/CSSRGB.h>
#include <LibWeb/CSS/StyleValues/DisplayStyleValue.h>
#include <LibWeb/CSS/StyleValues/LengthStyleValue.h>
#include <LibWeb/DOM/Document.h>
Expand Down Expand Up @@ -964,6 +966,58 @@ void HTMLInputElement::create_color_input_shadow_tree()
set_shadow_root(shadow_root);
}

// https://html.spec.whatwg.org/multipage/input.html#update-a-color-well-control-color
void HTMLInputElement::update_a_color_well_control_color()
{
// 1. Assert: element is an input element whose type attribute is in the Color state.
VERIFY(m_type == TypeAttributeState::Color);

// 2. Let color be the result of parsing element's value.
auto color = parse_a_css_color_value(CSS::Parser::ParsingContext { realm() }, value(), *this);

// 3. If color is failure, then set color to opaque black.
if (!color)
color = CSS::CSSRGB::create_from_color(Color::Black);

// 4. Set element's value to the result of serializing a color well control color given element and color.
set_value(serialize_a_color_well_control_color(color));
}

// https://html.spec.whatwg.org/multipage/input.html#serialize-a-color-well-control-color
void HTMLInputElement::serialize_a_color_well_control_color(CSS::CSSColorValue const& color)
{
// 1. Assert: element is an input element whose type attribute is in the Color state.
VERIFY(m_type == TypeAttributeState::Color);

// 2. Let htmlCompatible be false.
auto html_compatible = false;

// 3. If element's alpha attribute is not specified, then set color's alpha component to be fully opaque.
if (!has_attribute(HTML::AttributeNames::alpha))
color.set_alpha(0xFF);

// 4. FIXME: If element's colorspace attribute is in the Limited sRGB state:
if (false) {
// 1. FIXME: Set color to color converted to the 'srgb' color space.

// 2. FIXME: Round each of color's components so they are in the range 0 to 255, inclusive. Components are to be rounded towards +∞ .

// 3. FIXME: If element's alpha attribute is not specified, then set htmlCompatible to true.

// 4. FIXME: Otherwise, set color to color converted to using the 'color()' function.
}

// 5. Otherwise:
else {
// 1. FIXME: Assert: element's colorspace attribute is in the Display P3 state.

// 2. FIXME: Set color to color converted to the 'display-p3' color space.
}

// 6. Return the result of serializing color. If htmlCompatible is true, then do so with HTML-compatible serialization requested.
return color.to_string();
}

void HTMLInputElement::update_color_well_element()
{
if (!m_color_well_element)
Expand Down Expand Up @@ -1510,11 +1564,8 @@ String HTMLInputElement::value_sanitization_algorithm(String const& value) const
}
} else if (type_state() == HTMLInputElement::TypeAttributeState::Color) {
// https://html.spec.whatwg.org/multipage/input.html#color-state-(type=color):value-sanitization-algorithm
// If the value of the element is a valid simple color, then set it to the value of the element converted to ASCII lowercase;
if (is_valid_simple_color(value))
return value.to_ascii_lowercase();
// otherwise, set it to the string "#000000".
return "#000000"_string;
// The value sanitization algorithm is as follows: Run update a color well control color for the element.
update_a_color_well_control_color();
}
return value;
}
Expand Down
2 changes: 2 additions & 0 deletions Userland/Libraries/LibWeb/HTML/HTMLInputElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,8 @@ class HTMLInputElement final
JS::GCPtr<DOM::Text> m_text_node;
bool m_checked { false };

void update_a_color_well_control_color();
void serialize_a_color_well_control_color(CSS::CSSColorValue const&);
void update_color_well_element();
JS::GCPtr<DOM::Element> m_color_well_element;

Expand Down

0 comments on commit 2d9b062

Please sign in to comment.