2020-08-01 03:04:26 +01:00
/*
2021-04-28 22:46:44 +02:00
* Copyright ( c ) 2020 , the SerenityOS developers .
2020-08-01 03:04:26 +01:00
*
2021-04-22 01:24:48 -07:00
* SPDX - License - Identifier : BSD - 2 - Clause
2020-08-01 03:04:26 +01:00
*/
2024-04-27 12:09:58 +12:00
# include <LibWeb/Bindings/HTMLButtonElementPrototype.h>
2022-03-01 21:12:32 +00:00
# include <LibWeb/DOM/Document.h>
2025-01-14 15:15:38 +11:00
# include <LibWeb/DOM/Event.h>
2020-08-01 03:04:26 +01:00
# include <LibWeb/HTML/HTMLButtonElement.h>
2022-03-01 21:12:32 +00:00
# include <LibWeb/HTML/HTMLFormElement.h>
2020-08-01 03:04:26 +01:00
namespace Web : : HTML {
2024-11-15 04:01:23 +13:00
GC_DEFINE_ALLOCATOR ( HTMLButtonElement ) ;
2023-11-19 19:47:52 +01:00
2022-02-18 21:00:52 +01:00
HTMLButtonElement : : HTMLButtonElement ( DOM : : Document & document , DOM : : QualifiedName qualified_name )
2022-03-23 18:55:54 -04:00
: HTMLElement ( document , move ( qualified_name ) )
2020-08-01 03:04:26 +01:00
{
}
2022-03-14 13:21:51 -06:00
HTMLButtonElement : : ~ HTMLButtonElement ( ) = default ;
2020-08-01 03:04:26 +01:00
2023-08-07 08:41:28 +02:00
void HTMLButtonElement : : initialize ( JS : : Realm & realm )
2023-01-10 06:28:20 -05:00
{
2023-08-07 08:41:28 +02:00
Base : : initialize ( realm ) ;
2024-03-16 13:13:08 +01:00
WEB_SET_PROTOTYPE_FOR_INTERFACE ( HTMLButtonElement ) ;
2023-01-10 06:28:20 -05:00
}
2022-03-01 21:06:29 +00:00
HTMLButtonElement : : TypeAttributeState HTMLButtonElement : : type_state ( ) const
{
2024-01-16 19:04:45 +01:00
auto value = get_attribute_value ( HTML : : AttributeNames : : type ) ;
2022-03-01 21:06:29 +00:00
# define __ENUMERATE_HTML_BUTTON_TYPE_ATTRIBUTE(keyword, state) \
2023-03-10 08:48:54 +01:00
if ( value . equals_ignoring_ascii_case ( # keyword # # sv ) ) \
2022-03-01 21:06:29 +00:00
return HTMLButtonElement : : TypeAttributeState : : state ;
ENUMERATE_HTML_BUTTON_TYPE_ATTRIBUTES
# undef __ENUMERATE_HTML_BUTTON_TYPE_ATTRIBUTE
2025-02-20 17:01:28 +00:00
// The attribute's missing value default and invalid value default are both the Auto state.
// https://html.spec.whatwg.org/multipage/form-elements.html#attr-button-type-auto-state
return HTMLButtonElement : : TypeAttributeState : : Auto ;
2022-03-01 21:06:29 +00:00
}
2025-02-20 17:01:28 +00:00
// https://html.spec.whatwg.org/multipage/form-elements.html#dom-button-type
String HTMLButtonElement : : type_for_bindings ( ) const
2022-03-01 21:06:29 +00:00
{
2025-02-20 17:01:28 +00:00
// The type getter steps are:
// 1. If this is a submit button, then return "submit".
if ( is_submit_button ( ) )
return " submit " _string ;
// 2. Let state be this's type attribute.
auto state = type_state ( ) ;
// 3. Assert: state is not in the Submit Button state.
VERIFY ( state ! = TypeAttributeState : : Submit ) ;
// 4. If state is in the Auto state, then return "button".
if ( state = = TypeAttributeState : : Auto )
return " button " _string ;
// 5. Return the keyword value corresponding to state.
switch ( state ) {
# define __ENUMERATE_HTML_BUTTON_TYPE_ATTRIBUTE(keyword, state) \
case TypeAttributeState : : state : \
return # keyword # # _string ;
ENUMERATE_HTML_BUTTON_TYPE_ATTRIBUTES
# undef __ENUMERATE_HTML_BUTTON_TYPE_ATTRIBUTE
}
VERIFY_NOT_REACHED ( ) ;
}
// https://html.spec.whatwg.org/multipage/form-elements.html#dom-button-type
WebIDL : : ExceptionOr < void > HTMLButtonElement : : set_type_for_bindings ( String const & type )
{
// The type setter steps are to set the type content attribute to the given value.
2023-05-25 20:37:57 +01:00
return set_attribute ( HTML : : AttributeNames : : type , type ) ;
2022-03-01 21:06:29 +00:00
}
2024-12-12 19:53:04 +00:00
void HTMLButtonElement : : form_associated_element_attribute_changed ( FlyString const & name , Optional < String > const & value , Optional < FlyString > const & namespace_ )
{
PopoverInvokerElement : : associated_attribute_changed ( name , value , namespace_ ) ;
}
2024-11-23 23:06:06 +01:00
void HTMLButtonElement : : visit_edges ( Visitor & visitor )
{
Base : : visit_edges ( visitor ) ;
PopoverInvokerElement : : visit_edges ( visitor ) ;
}
2022-11-05 03:58:14 +00:00
// https://html.spec.whatwg.org/multipage/interaction.html#dom-tabindex
i32 HTMLButtonElement : : default_tab_index_value ( ) const
{
// See the base function for the spec comments.
return 0 ;
}
2023-06-18 15:08:15 +01:00
// https://html.spec.whatwg.org/multipage/forms.html#concept-submit-button
// https://html.spec.whatwg.org/multipage/form-elements.html#the-button-element:concept-submit-button
bool HTMLButtonElement : : is_submit_button ( ) const
{
2025-02-20 17:01:28 +00:00
// A button element is said to be a submit button if any of the following are true:
switch ( type_state ( ) ) {
// - the type attribute is in the Auto state and both the command and commandfor content attributes are not present; or
case TypeAttributeState : : Auto :
return ! has_attribute ( AttributeNames : : command ) & & ! has_attribute ( AttributeNames : : commandfor ) ;
// - the type attribute is in the Submit Button state.
case TypeAttributeState : : Submit :
return true ;
default :
return false ;
}
2023-06-18 15:08:15 +01:00
}
// https://html.spec.whatwg.org/multipage/form-elements.html#the-button-element:concept-fe-value
2023-11-20 20:32:40 +13:00
String HTMLButtonElement : : value ( ) const
2023-06-18 15:08:15 +01:00
{
2023-11-20 20:32:40 +13:00
return attribute ( AttributeNames : : value ) . value_or ( String { } ) ;
2023-06-18 15:08:15 +01:00
}
2023-11-18 10:48:09 +01:00
bool HTMLButtonElement : : has_activation_behavior ( ) const
{
return true ;
}
2024-01-18 12:58:22 -07:00
void HTMLButtonElement : : activation_behavior ( DOM : : Event const & event )
2023-11-18 10:48:09 +01:00
{
// https://html.spec.whatwg.org/multipage/form-elements.html#the-button-element:activation-behaviour
// 1. If element is disabled, then return.
if ( ! enabled ( ) )
return ;
2024-01-18 12:58:22 -07:00
// 2. If element's node document is not fully active, then return.
2023-11-18 10:48:09 +01:00
if ( ! this - > document ( ) . is_fully_active ( ) )
return ;
2025-02-12 16:58:03 +00:00
// 3. If element has a form owner:
2024-01-18 12:58:22 -07:00
if ( form ( ) ! = nullptr ) {
2025-02-27 10:53:48 +11:00
// 1. If element is a submit button, then submit element's form owner from element with userInvolvement set to event's user navigation involvement, and return.
2025-02-12 16:58:03 +00:00
if ( is_submit_button ( ) ) {
2024-01-18 12:58:22 -07:00
form ( ) - > submit_form ( * this , { . user_involvement = user_navigation_involvement ( event ) } ) . release_value_but_fixme_should_propagate_errors ( ) ;
2025-02-27 10:53:48 +11:00
return ;
2025-02-12 16:58:03 +00:00
}
2025-02-27 10:53:48 +11:00
// 2. If element's type attribute is in the Reset Button state, then reset element's form owner, and return.
2025-02-12 16:58:03 +00:00
if ( type_state ( ) = = TypeAttributeState : : Reset ) {
2024-01-18 12:58:22 -07:00
form ( ) - > reset_form ( ) ;
2025-02-27 10:53:48 +11:00
return ;
2024-01-18 12:58:22 -07:00
}
2025-02-27 10:53:48 +11:00
// 3. If element's type attribute is in the Auto state, then return.
if ( type_state ( ) = = TypeAttributeState : : Auto )
return ;
2023-11-18 10:48:09 +01:00
}
2024-01-18 12:58:22 -07:00
2025-02-20 17:01:28 +00:00
// FIXME: 4. Let target be the result of running element's get the commandfor associated element.
// FIXME: 5. If target is not null:
// ...
// 6. Otherwise, run the popover target attribute activation behavior given element and event's target.
2025-01-14 15:15:38 +11:00
if ( event . target ( ) & & event . target ( ) - > is_dom_node ( ) )
PopoverInvokerElement : : popover_target_activation_behaviour ( * this , as < DOM : : Node > ( * event . target ( ) ) ) ;
2023-11-18 10:48:09 +01:00
}
2025-02-25 17:43:11 +09:00
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-cva-willvalidate
bool HTMLButtonElement : : will_validate ( )
{
// The willValidate attribute's getter must return true, if this element is a candidate for constraint validation
return is_candidate_for_constraint_validation ( ) ;
}
2024-11-02 19:17:20 +01:00
bool HTMLButtonElement : : is_focusable ( ) const
{
return enabled ( ) ;
}
2020-08-01 03:04:26 +01:00
}