LibWeb: Honor appearance: none when creating input element layout node

Per css-ui-4, setting `appearance: none` is supposed to suppress the
creation of a native-looking widget for stuff like checkboxes, radio
buttons, etc.

This patch implements this behavior by simply falling back to creating
a layout node based on the CSS `display` property in such cases.

This fixes an issue on the hey.com imbox page where we were rendering
checkboxes on top of sender profile photos.

(cherry picked from commit 58c523ae46af90ab17d6b98966d97fa776ae2bf4)
This commit is contained in:
Andreas Kling
2024-10-20 18:20:42 +02:00
committed by Nico Weber
parent 36a2826cd2
commit b3e8e67ca3
3 changed files with 98 additions and 3 deletions

View File

@@ -99,12 +99,23 @@ JS::GCPtr<Layout::Node> HTMLInputElement::create_layout_node(NonnullRefPtr<CSS::
if (type_state() == TypeAttributeState::Hidden)
return nullptr;
// NOTE: Image inputs are `appearance: none` per the default UA style,
// but we still need to create an ImageBox for them, or no image will get loaded.
if (type_state() == TypeAttributeState::ImageButton) {
return heap().allocate_without_realm<Layout::ImageBox>(document(), *this, move(style), *this);
}
// https://drafts.csswg.org/css-ui/#appearance-switching
// This specification introduces the appearance property to provide some control over this behavior.
// In particular, using appearance: none allows authors to suppress the native appearance of widgets,
// giving them a primitive appearance where CSS can be used to restyle them.
if (style->appearance() == CSS::Appearance::None) {
return Element::create_layout_node_for_display_type(document(), style->display(), style, this);
}
if (type_state() == TypeAttributeState::SubmitButton || type_state() == TypeAttributeState::Button || type_state() == TypeAttributeState::ResetButton)
return heap().allocate_without_realm<Layout::BlockContainer>(document(), this, move(style));
if (type_state() == TypeAttributeState::ImageButton)
return heap().allocate_without_realm<Layout::ImageBox>(document(), *this, move(style), *this);
if (type_state() == TypeAttributeState::Checkbox)
return heap().allocate_without_realm<Layout::CheckBox>(document(), *this, move(style));