mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-12-08 06:09:58 +00:00
LibWeb: Hide stepper buttons on appearance: textfield number inputs
The spec says: > For the purpose of this specification, they all have the same effect as auto. However, the host language may also take these values into account when defining the native appearance of the element. https://drafts.csswg.org/css-ui/#typedef-appearance-compat-special Firefox at least hides the stepper buttons when this is set.
This commit is contained in:
parent
c3d23a2487
commit
d5d1b5351e
Notes:
github-actions[bot]
2025-12-01 11:11:27 +00:00
Author: https://github.com/AtkinsSJ
Commit: d5d1b5351e
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6821
Reviewed-by: https://github.com/tcl3
5 changed files with 163 additions and 23 deletions
|
|
@ -86,6 +86,8 @@ void HTMLInputElement::visit_edges(Cell::Visitor& visitor)
|
|||
visitor.visit(m_text_node);
|
||||
visitor.visit(m_placeholder_element);
|
||||
visitor.visit(m_placeholder_text_node);
|
||||
visitor.visit(m_up_button_element);
|
||||
visitor.visit(m_down_button_element);
|
||||
visitor.visit(m_color_well_element);
|
||||
visitor.visit(m_file_button);
|
||||
visitor.visit(m_file_label);
|
||||
|
|
@ -793,6 +795,31 @@ static GC::Ref<CSS::CSSStyleProperties> inner_text_style_when_hidden()
|
|||
return *style;
|
||||
}
|
||||
|
||||
static GC::Ref<CSS::CSSStyleProperties> stepper_button_style_when_visible()
|
||||
{
|
||||
static GC::Root<CSS::CSSStyleProperties> style;
|
||||
if (!style) {
|
||||
style = CSS::CSSStyleProperties::create(internal_css_realm(), {}, {});
|
||||
style->set_declarations_from_text(R"~~~(
|
||||
padding: 0;
|
||||
cursor: default;
|
||||
)~~~"sv);
|
||||
}
|
||||
return *style;
|
||||
}
|
||||
|
||||
static GC::Ref<CSS::CSSStyleProperties> stepper_button_style_when_hidden()
|
||||
{
|
||||
static GC::Root<CSS::CSSStyleProperties> style;
|
||||
if (!style) {
|
||||
style = CSS::CSSStyleProperties::create(internal_css_realm(), {}, {});
|
||||
style->set_declarations_from_text(R"~~~(
|
||||
display: none;
|
||||
)~~~"sv);
|
||||
}
|
||||
return *style;
|
||||
}
|
||||
|
||||
static GC::Ref<CSS::CSSStyleProperties> placeholder_style_when_visible()
|
||||
{
|
||||
static GC::Root<CSS::CSSStyleProperties> style;
|
||||
|
|
@ -871,6 +898,17 @@ void HTMLInputElement::update_text_input_shadow_tree()
|
|||
m_text_node->set_data(m_value);
|
||||
update_placeholder_visibility();
|
||||
}
|
||||
|
||||
if (m_type == TypeAttributeState::Number) {
|
||||
// The `textfield` appearance is used to hide the stepper buttons.
|
||||
if (auto style = computed_properties(); style && style->appearance() == CSS::Appearance::Textfield) {
|
||||
m_up_button_element->set_inline_style(stepper_button_style_when_hidden());
|
||||
m_down_button_element->set_inline_style(stepper_button_style_when_hidden());
|
||||
} else {
|
||||
m_up_button_element->set_inline_style(stepper_button_style_when_visible());
|
||||
m_down_button_element->set_inline_style(stepper_button_style_when_visible());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/input.html#the-input-element:attr-input-readonly-3
|
||||
|
|
@ -1093,29 +1131,22 @@ void HTMLInputElement::create_text_input_shadow_tree()
|
|||
m_placeholder_text_node = realm().create<DOM::Text>(document(), Utf16String::from_utf8(placeholder()));
|
||||
MUST(m_placeholder_element->append_child(*m_placeholder_text_node));
|
||||
|
||||
update_placeholder_visibility();
|
||||
|
||||
if (type_state() == TypeAttributeState::Number) {
|
||||
// Up button
|
||||
auto up_button = MUST(DOM::create_element(document(), HTML::TagNames::button, Namespace::HTML));
|
||||
// FIXME: This cursor property doesn't work
|
||||
up_button->set_attribute_value(HTML::AttributeNames::style, R"~~~(
|
||||
padding: 0;
|
||||
cursor: default;
|
||||
)~~~"_string);
|
||||
m_up_button_element = MUST(DOM::create_element(document(), HTML::TagNames::button, Namespace::HTML));
|
||||
|
||||
auto up_button_svg = MUST(DOM::create_element(document(), SVG::TagNames::svg, Namespace::SVG));
|
||||
up_button_svg->set_attribute_value(HTML::AttributeNames::style, "width: 1em; height: 1em;"_string);
|
||||
up_button_svg->set_attribute_value(SVG::AttributeNames::xmlns, Namespace::SVG.to_string());
|
||||
up_button_svg->set_attribute_value(SVG::AttributeNames::viewBox, "0 0 24 24"_string);
|
||||
MUST(up_button->append_child(up_button_svg));
|
||||
MUST(m_up_button_element->append_child(up_button_svg));
|
||||
|
||||
auto up_button_svg_path = MUST(DOM::create_element(document(), SVG::TagNames::path, Namespace::SVG));
|
||||
up_button_svg_path->set_attribute_value(SVG::AttributeNames::fill, "currentColor"_string);
|
||||
up_button_svg_path->set_attribute_value(SVG::AttributeNames::d, "M7.41,15.41L12,10.83L16.59,15.41L18,14L12,8L6,14L7.41,15.41Z"_string);
|
||||
MUST(up_button_svg->append_child(up_button_svg_path));
|
||||
|
||||
MUST(element->append_child(up_button));
|
||||
MUST(element->append_child(*m_up_button_element));
|
||||
|
||||
auto mouseup_callback_function = JS::NativeFunction::create(
|
||||
realm(), [this](JS::VM&) {
|
||||
|
|
@ -1137,28 +1168,24 @@ void HTMLInputElement::create_text_input_shadow_tree()
|
|||
},
|
||||
0, Utf16FlyString {}, &realm());
|
||||
auto step_up_callback = realm().heap().allocate<WebIDL::CallbackType>(*up_callback_function, realm());
|
||||
up_button->add_event_listener_without_options(UIEvents::EventNames::mousedown, DOM::IDLEventListener::create(realm(), step_up_callback));
|
||||
up_button->add_event_listener_without_options(UIEvents::EventNames::mouseup, DOM::IDLEventListener::create(realm(), mouseup_callback));
|
||||
m_up_button_element->add_event_listener_without_options(UIEvents::EventNames::mousedown, DOM::IDLEventListener::create(realm(), step_up_callback));
|
||||
m_up_button_element->add_event_listener_without_options(UIEvents::EventNames::mouseup, DOM::IDLEventListener::create(realm(), mouseup_callback));
|
||||
|
||||
// Down button
|
||||
auto down_button = MUST(DOM::create_element(document(), HTML::TagNames::button, Namespace::HTML));
|
||||
down_button->set_attribute_value(HTML::AttributeNames::style, R"~~~(
|
||||
padding: 0;
|
||||
cursor: default;
|
||||
)~~~"_string);
|
||||
m_down_button_element = MUST(DOM::create_element(document(), HTML::TagNames::button, Namespace::HTML));
|
||||
|
||||
auto down_button_svg = MUST(DOM::create_element(document(), SVG::TagNames::svg, Namespace::SVG));
|
||||
down_button_svg->set_attribute_value(HTML::AttributeNames::style, "width: 1em; height: 1em;"_string);
|
||||
down_button_svg->set_attribute_value(SVG::AttributeNames::xmlns, Namespace::SVG.to_string());
|
||||
down_button_svg->set_attribute_value(SVG::AttributeNames::viewBox, "0 0 24 24"_string);
|
||||
MUST(down_button->append_child(down_button_svg));
|
||||
MUST(m_down_button_element->append_child(down_button_svg));
|
||||
|
||||
auto down_button_svg_path = MUST(DOM::create_element(document(), SVG::TagNames::path, Namespace::SVG));
|
||||
down_button_svg_path->set_attribute_value(SVG::AttributeNames::fill, "currentColor"_string);
|
||||
down_button_svg_path->set_attribute_value(SVG::AttributeNames::d, "M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z"_string);
|
||||
MUST(down_button_svg->append_child(down_button_svg_path));
|
||||
|
||||
MUST(element->append_child(down_button));
|
||||
MUST(element->append_child(*m_down_button_element));
|
||||
|
||||
auto down_callback_function = JS::NativeFunction::create(
|
||||
realm(), [this](JS::VM&) {
|
||||
|
|
@ -1170,9 +1197,11 @@ void HTMLInputElement::create_text_input_shadow_tree()
|
|||
},
|
||||
0, Utf16FlyString {}, &realm());
|
||||
auto step_down_callback = realm().heap().allocate<WebIDL::CallbackType>(*down_callback_function, realm());
|
||||
down_button->add_event_listener_without_options(UIEvents::EventNames::mousedown, DOM::IDLEventListener::create(realm(), step_down_callback));
|
||||
down_button->add_event_listener_without_options(UIEvents::EventNames::mouseup, DOM::IDLEventListener::create(realm(), mouseup_callback));
|
||||
m_down_button_element->add_event_listener_without_options(UIEvents::EventNames::mousedown, DOM::IDLEventListener::create(realm(), step_down_callback));
|
||||
m_down_button_element->add_event_listener_without_options(UIEvents::EventNames::mouseup, DOM::IDLEventListener::create(realm(), mouseup_callback));
|
||||
}
|
||||
|
||||
update_text_input_shadow_tree();
|
||||
}
|
||||
|
||||
void HTMLInputElement::create_color_input_shadow_tree()
|
||||
|
|
@ -1531,6 +1560,12 @@ void HTMLInputElement::type_attribute_changed(TypeAttributeState old_state, Type
|
|||
}
|
||||
}
|
||||
|
||||
void HTMLInputElement::computed_properties_changed()
|
||||
{
|
||||
create_shadow_tree_if_needed();
|
||||
update_shadow_tree();
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/input.html#radio-button-state-(type=radio):signal-a-type-change
|
||||
void HTMLInputElement::signal_a_type_change()
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue