Procházet zdrojové kódy

LibWeb: Create BlockContainer layout node for `<input type="button">`

...and shadow tree with TextNode for "value" attribute is created.
This means InlineFormattingContext is used, and button's text now
respects CSS text-decoration properties and unicode-ranges.
Aliaksandr Kalenik před 1 rokem
rodič
revize
8feaecd5c8

+ 0 - 1
Meta/gn/secondary/Userland/Libraries/LibWeb/Layout/BUILD.gn

@@ -12,7 +12,6 @@ source_set("Layout") {
     "Box.cpp",
     "Box.cpp",
     "BoxModelMetrics.cpp",
     "BoxModelMetrics.cpp",
     "BreakNode.cpp",
     "BreakNode.cpp",
-    "ButtonBox.cpp",
     "CanvasBox.cpp",
     "CanvasBox.cpp",
     "CheckBox.cpp",
     "CheckBox.cpp",
     "FlexFormattingContext.cpp",
     "FlexFormattingContext.cpp",

+ 0 - 1
Meta/gn/secondary/Userland/Libraries/LibWeb/Painting/BUILD.gn

@@ -12,7 +12,6 @@ source_set("Painting") {
     "BorderRadiiData.cpp",
     "BorderRadiiData.cpp",
     "BorderRadiusCornerClipper.cpp",
     "BorderRadiusCornerClipper.cpp",
     "BordersData.cpp",
     "BordersData.cpp",
-    "ButtonPaintable.cpp",
     "CanvasPaintable.cpp",
     "CanvasPaintable.cpp",
     "CheckBoxPaintable.cpp",
     "CheckBoxPaintable.cpp",
     "ClippableAndScrollable.cpp",
     "ClippableAndScrollable.cpp",

+ 1 - 1
Tests/LibWeb/Text/expected/HTML/form-implicit-submission.txt

@@ -1,4 +1,4 @@
- wfh :^) PASS   wfh :^)    wfh :^) FAIL PASS FAIL   wfh :^) FAIL FAIL PASS  PASS  wfh :^)   wfh :^)  PASS  PASSwfh :^) FAIL   wfh :^) FAIL   wfh :^)   wfh :^) FAIL   wfh :^)    wfh :^)     defaultButton: click button=PASS
+ wfh :^) PASS   wfh :^) PASS   wfh :^) FAIL PASS FAIL   wfh :^) FAIL FAIL PASS  PASS  wfh :^)   wfh :^)  PASS  PASSwfh :^) FAIL   wfh :^) FAIL   wfh :^)   wfh :^) FAIL   wfh :^)    wfh :^)     defaultButton: click button=PASS
 defaultButton: submit
 defaultButton: submit
 defaultButton: handledEvent=true
 defaultButton: handledEvent=true
 defaultButtonAsInput: click button=PASS
 defaultButtonAsInput: click button=PASS

+ 1 - 1
Tests/LibWeb/Text/expected/input-value.txt

@@ -1,4 +1,4 @@
-pass    Select file...No file selected.   text: "pass"
+pass  pass  Select file...No file selected.   text: "pass"
 hidden: "pass"
 hidden: "pass"
 button: "pass"
 button: "pass"
 checkbox: "pass"
 checkbox: "pass"

+ 0 - 2
Userland/Libraries/LibWeb/CMakeLists.txt

@@ -471,7 +471,6 @@ set(SOURCES
     Layout/Box.cpp
     Layout/Box.cpp
     Layout/BoxModelMetrics.cpp
     Layout/BoxModelMetrics.cpp
     Layout/BreakNode.cpp
     Layout/BreakNode.cpp
-    Layout/ButtonBox.cpp
     Layout/CanvasBox.cpp
     Layout/CanvasBox.cpp
     Layout/CheckBox.cpp
     Layout/CheckBox.cpp
     Layout/FlexFormattingContext.cpp
     Layout/FlexFormattingContext.cpp
@@ -537,7 +536,6 @@ set(SOURCES
     Painting/BorderPainting.cpp
     Painting/BorderPainting.cpp
     Painting/BorderRadiusCornerClipper.cpp
     Painting/BorderRadiusCornerClipper.cpp
     Painting/BordersData.cpp
     Painting/BordersData.cpp
-    Painting/ButtonPaintable.cpp
     Painting/CanvasPaintable.cpp
     Painting/CanvasPaintable.cpp
     Painting/Command.cpp
     Painting/Command.cpp
     Painting/CommandExecutorCPU.cpp
     Painting/CommandExecutorCPU.cpp

+ 14 - 3
Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp

@@ -27,17 +27,16 @@
 #include <LibWeb/HTML/HTMLDivElement.h>
 #include <LibWeb/HTML/HTMLDivElement.h>
 #include <LibWeb/HTML/HTMLFormElement.h>
 #include <LibWeb/HTML/HTMLFormElement.h>
 #include <LibWeb/HTML/HTMLInputElement.h>
 #include <LibWeb/HTML/HTMLInputElement.h>
-#include <LibWeb/HTML/ValidityState.h>
 #include <LibWeb/HTML/Numbers.h>
 #include <LibWeb/HTML/Numbers.h>
 #include <LibWeb/HTML/Parser/HTMLParser.h>
 #include <LibWeb/HTML/Parser/HTMLParser.h>
 #include <LibWeb/HTML/Scripting/Environments.h>
 #include <LibWeb/HTML/Scripting/Environments.h>
 #include <LibWeb/HTML/SelectedFile.h>
 #include <LibWeb/HTML/SelectedFile.h>
 #include <LibWeb/HTML/SharedImageRequest.h>
 #include <LibWeb/HTML/SharedImageRequest.h>
+#include <LibWeb/HTML/ValidityState.h>
 #include <LibWeb/HTML/Window.h>
 #include <LibWeb/HTML/Window.h>
 #include <LibWeb/Infra/CharacterTypes.h>
 #include <LibWeb/Infra/CharacterTypes.h>
 #include <LibWeb/Infra/Strings.h>
 #include <LibWeb/Infra/Strings.h>
 #include <LibWeb/Layout/BlockContainer.h>
 #include <LibWeb/Layout/BlockContainer.h>
-#include <LibWeb/Layout/ButtonBox.h>
 #include <LibWeb/Layout/CheckBox.h>
 #include <LibWeb/Layout/CheckBox.h>
 #include <LibWeb/Layout/ImageBox.h>
 #include <LibWeb/Layout/ImageBox.h>
 #include <LibWeb/Layout/RadioButton.h>
 #include <LibWeb/Layout/RadioButton.h>
@@ -100,7 +99,7 @@ JS::GCPtr<Layout::Node> HTMLInputElement::create_layout_node(NonnullRefPtr<CSS::
         return nullptr;
         return nullptr;
 
 
     if (type_state() == TypeAttributeState::SubmitButton || type_state() == TypeAttributeState::Button || type_state() == TypeAttributeState::ResetButton)
     if (type_state() == TypeAttributeState::SubmitButton || type_state() == TypeAttributeState::Button || type_state() == TypeAttributeState::ResetButton)
-        return heap().allocate_without_realm<Layout::ButtonBox>(document(), *this, move(style));
+        return heap().allocate_without_realm<Layout::BlockContainer>(document(), this, move(style));
 
 
     if (type_state() == TypeAttributeState::ImageButton)
     if (type_state() == TypeAttributeState::ImageButton)
         return heap().allocate_without_realm<Layout::ImageBox>(document(), *this, move(style), *this);
         return heap().allocate_without_realm<Layout::ImageBox>(document(), *this, move(style), *this);
@@ -740,9 +739,12 @@ void HTMLInputElement::create_shadow_tree_if_needed()
     case TypeAttributeState::Hidden:
     case TypeAttributeState::Hidden:
     case TypeAttributeState::RadioButton:
     case TypeAttributeState::RadioButton:
     case TypeAttributeState::Checkbox:
     case TypeAttributeState::Checkbox:
+        break;
     case TypeAttributeState::Button:
     case TypeAttributeState::Button:
     case TypeAttributeState::SubmitButton:
     case TypeAttributeState::SubmitButton:
     case TypeAttributeState::ResetButton:
     case TypeAttributeState::ResetButton:
+        create_button_input_shadow_tree();
+        break;
     case TypeAttributeState::ImageButton:
     case TypeAttributeState::ImageButton:
         break;
         break;
     case TypeAttributeState::Color:
     case TypeAttributeState::Color:
@@ -779,6 +781,15 @@ void HTMLInputElement::update_shadow_tree()
     }
     }
 }
 }
 
 
+void HTMLInputElement::create_button_input_shadow_tree()
+{
+    auto shadow_root = heap().allocate<DOM::ShadowRoot>(realm(), document(), *this, Bindings::ShadowRootMode::Closed);
+    set_shadow_root(shadow_root);
+
+    m_text_node = heap().allocate<DOM::Text>(realm(), document(), value());
+    MUST(shadow_root->append_child(*m_text_node));
+}
+
 void HTMLInputElement::create_text_input_shadow_tree()
 void HTMLInputElement::create_text_input_shadow_tree()
 {
 {
     auto shadow_root = heap().allocate<DOM::ShadowRoot>(realm(), document(), *this, Bindings::ShadowRootMode::Closed);
     auto shadow_root = heap().allocate<DOM::ShadowRoot>(realm(), document(), *this, Bindings::ShadowRootMode::Closed);

+ 1 - 0
Userland/Libraries/LibWeb/HTML/HTMLInputElement.h

@@ -243,6 +243,7 @@ private:
     static TypeAttributeState parse_type_attribute(StringView);
     static TypeAttributeState parse_type_attribute(StringView);
     void create_shadow_tree_if_needed();
     void create_shadow_tree_if_needed();
     void update_shadow_tree();
     void update_shadow_tree();
+    void create_button_input_shadow_tree();
     void create_text_input_shadow_tree();
     void create_text_input_shadow_tree();
     void create_color_input_shadow_tree();
     void create_color_input_shadow_tree();
     void create_file_input_shadow_tree();
     void create_file_input_shadow_tree();

+ 0 - 40
Userland/Libraries/LibWeb/Layout/ButtonBox.cpp

@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
-
-#include <LibGfx/Font/Font.h>
-#include <LibWeb/DOM/Document.h>
-#include <LibWeb/Layout/ButtonBox.h>
-#include <LibWeb/Painting/ButtonPaintable.h>
-
-namespace Web::Layout {
-
-JS_DEFINE_ALLOCATOR(ButtonBox);
-
-ButtonBox::ButtonBox(DOM::Document& document, HTML::HTMLInputElement& element, NonnullRefPtr<CSS::StyleProperties> style)
-    : FormAssociatedLabelableNode(document, element, move(style))
-{
-}
-
-ButtonBox::~ButtonBox() = default;
-
-void ButtonBox::prepare_for_replaced_layout()
-{
-    // For <input type="submit" /> and <input type="button" />, the contents of
-    // the button does not appear as the contents of the element but as the
-    // value attribute. This is not the case with <button />, which contains
-    // its contents normally.
-    if (is<HTML::HTMLInputElement>(dom_node())) {
-        set_natural_width(CSSPixels::nearest_value_for(first_available_font().width(static_cast<HTML::HTMLInputElement&>(dom_node()).value())));
-        set_natural_height(first_available_font().pixel_size_rounded_up());
-    }
-}
-
-JS::GCPtr<Painting::Paintable> ButtonBox::create_paintable() const
-{
-    return Painting::ButtonPaintable::create(*this);
-}
-
-}

+ 0 - 28
Userland/Libraries/LibWeb/Layout/ButtonBox.h

@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
-
-#pragma once
-
-#include <LibWeb/HTML/HTMLInputElement.h>
-#include <LibWeb/Layout/FormAssociatedLabelableNode.h>
-
-namespace Web::Layout {
-
-class ButtonBox final : public FormAssociatedLabelableNode {
-    JS_CELL(ButtonBox, FormAssociatedLabelableNode);
-    JS_DECLARE_ALLOCATOR(ButtonBox);
-
-public:
-    ButtonBox(DOM::Document&, HTML::HTMLInputElement&, NonnullRefPtr<CSS::StyleProperties>);
-    virtual ~ButtonBox() override;
-
-    virtual void prepare_for_replaced_layout() override;
-
-private:
-    virtual JS::GCPtr<Painting::Paintable> create_paintable() const override;
-};
-
-}

+ 0 - 77
Userland/Libraries/LibWeb/Painting/ButtonPaintable.cpp

@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2018-2022, Andreas Kling <kling@serenityos.org>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
-
-#include <LibWeb/HTML/BrowsingContext.h>
-#include <LibWeb/HTML/HTMLImageElement.h>
-#include <LibWeb/Layout/ButtonBox.h>
-#include <LibWeb/Layout/Label.h>
-#include <LibWeb/Painting/ButtonPaintable.h>
-
-namespace Web::Painting {
-
-JS_DEFINE_ALLOCATOR(ButtonPaintable);
-
-JS::NonnullGCPtr<ButtonPaintable> ButtonPaintable::create(Layout::ButtonBox const& layout_box)
-{
-    return layout_box.heap().allocate_without_realm<ButtonPaintable>(layout_box);
-}
-
-ButtonPaintable::ButtonPaintable(Layout::ButtonBox const& layout_box)
-    : LabelablePaintable(layout_box)
-{
-}
-
-Layout::ButtonBox const& ButtonPaintable::layout_box() const
-{
-    return static_cast<Layout::ButtonBox const&>(layout_node());
-}
-
-Layout::ButtonBox& ButtonPaintable::layout_box()
-{
-    return static_cast<Layout::ButtonBox&>(layout_node());
-}
-
-void ButtonPaintable::paint(PaintContext& context, PaintPhase phase) const
-{
-    if (!is_visible())
-        return;
-
-    PaintableBox::paint(context, phase);
-
-    auto const& dom_node = layout_box().dom_node();
-    if (is<HTML::HTMLInputElement>(dom_node) && phase == PaintPhase::Foreground) {
-        auto button_rect = context.enclosing_device_rect(absolute_rect());
-        auto text_rect = button_rect;
-
-        // Apply CSS text-indent property to text rect
-        // FIXME: The second parameter to to_px() needs to be the block container’s own inline-axis inner size:
-        //        https://drafts.csswg.org/css-text-3/#propdef-text-indent
-        auto text_indent = computed_values().text_indent().to_px(layout_box(), CSSPixels());
-        text_rect.translate_by(context.rounded_device_pixels(text_indent), 0);
-
-        // Apply button pressed state offset
-        if (being_pressed()) {
-            auto offset = context.rounded_device_pixels(1);
-            text_rect.translate_by(offset, offset);
-        }
-
-        // Paint button text clipped to button rect
-        auto& painter = context.recording_painter();
-        painter.save();
-        auto clip_rect = absolute_rect();
-        clip_rect.translate_by(enclosing_scroll_frame_offset().value_or({}));
-        painter.add_clip_rect(context.enclosing_device_rect(clip_rect).to_type<int>());
-        painter.draw_text(
-            text_rect.to_type<int>(),
-            static_cast<HTML::HTMLInputElement const&>(dom_node).value(),
-            layout_box().scaled_font(context.device_pixels_per_css_pixel()),
-            Gfx::TextAlignment::Center,
-            computed_values().color());
-        painter.restore();
-    }
-}
-
-}

+ 0 - 30
Userland/Libraries/LibWeb/Painting/ButtonPaintable.h

@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
-
-#pragma once
-
-#include <LibWeb/Layout/ButtonBox.h>
-#include <LibWeb/Painting/LabelablePaintable.h>
-
-namespace Web::Painting {
-
-class ButtonPaintable final : public LabelablePaintable {
-    JS_CELL(ButtonPaintable, LabelablePaintable);
-    JS_DECLARE_ALLOCATOR(ButtonPaintable);
-
-public:
-    static JS::NonnullGCPtr<ButtonPaintable> create(Layout::ButtonBox const&);
-
-    virtual void paint(PaintContext&, PaintPhase) const override;
-
-    Layout::ButtonBox const& layout_box() const;
-    Layout::ButtonBox& layout_box();
-
-private:
-    ButtonPaintable(Layout::ButtonBox const&);
-};
-
-}