diff --git a/Userland/Libraries/LibWeb/DOM/Element.cpp b/Userland/Libraries/LibWeb/DOM/Element.cpp index 1662b2bbf0..d0ed35d371 100644 --- a/Userland/Libraries/LibWeb/DOM/Element.cpp +++ b/Userland/Libraries/LibWeb/DOM/Element.cpp @@ -227,9 +227,7 @@ WebIDL::ExceptionOr> Element::set_attribute_node_ns(Attr& attr) void Element::remove_attribute(DeprecatedFlyString const& name) { m_attributes->remove_attribute(name); - - did_remove_attribute(name); - + attribute_changed(name, {}); invalidate_style_after_attribute_change(name); } @@ -275,9 +273,7 @@ WebIDL::ExceptionOr Element::toggle_attribute(DeprecatedFlyString const& n // 5. Otherwise, if force is not given or is false, remove an attribute given qualifiedName and this, and then return false. if (!force.has_value() || !force.value()) { m_attributes->remove_attribute(name); - - did_remove_attribute(name); - + attribute_changed(name, {}); invalidate_style_after_attribute_change(name); } @@ -373,19 +369,16 @@ void Element::attribute_changed(DeprecatedFlyString const& name, DeprecatedStrin if (m_class_list) m_class_list->associated_attribute_changed(value); } else if (name == HTML::AttributeNames::style) { - // https://drafts.csswg.org/cssom/#ref-for-cssstyledeclaration-updating-flag - if (m_inline_style && m_inline_style->is_updating()) - return; - m_inline_style = parse_css_style_attribute(CSS::Parser::ParsingContext(document()), value, *this); - set_needs_style_update(true); - } -} - -void Element::did_remove_attribute(DeprecatedFlyString const& name) -{ - if (name == HTML::AttributeNames::style) { - if (m_inline_style) { - m_inline_style = nullptr; + if (value.is_null()) { + if (!m_inline_style) { + m_inline_style = nullptr; + set_needs_style_update(true); + } + } else { + // https://drafts.csswg.org/cssom/#ref-for-cssstyledeclaration-updating-flag + if (m_inline_style && m_inline_style->is_updating()) + return; + m_inline_style = parse_css_style_attribute(CSS::Parser::ParsingContext(document()), value, *this); set_needs_style_update(true); } } diff --git a/Userland/Libraries/LibWeb/DOM/Element.h b/Userland/Libraries/LibWeb/DOM/Element.h index 6b2daff957..455eedfd69 100644 --- a/Userland/Libraries/LibWeb/DOM/Element.h +++ b/Userland/Libraries/LibWeb/DOM/Element.h @@ -122,7 +122,6 @@ public: virtual void apply_presentational_hints(CSS::StyleProperties&) const { } virtual void attribute_changed(DeprecatedFlyString const& name, DeprecatedString const& value); - virtual void did_remove_attribute(DeprecatedFlyString const&); struct [[nodiscard]] RequiredInvalidationAfterStyleChange { bool repaint { false }; diff --git a/Userland/Libraries/LibWeb/HTML/HTMLElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLElement.cpp index b5ed7767bb..9c6908c940 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLElement.cpp @@ -233,15 +233,19 @@ void HTMLElement::attribute_changed(DeprecatedFlyString const& name, DeprecatedS Element::attribute_changed(name, value); if (name == HTML::AttributeNames::contenteditable) { - if ((!value.is_null() && value.is_empty()) || value.equals_ignoring_ascii_case("true"sv)) { - // "true", an empty string or a missing value map to the "true" state. - m_content_editable_state = ContentEditableState::True; - } else if (value.equals_ignoring_ascii_case("false"sv)) { - // "false" maps to the "false" state. - m_content_editable_state = ContentEditableState::False; - } else { - // Having no such attribute or an invalid value maps to the "inherit" state. + if (value.is_null()) { m_content_editable_state = ContentEditableState::Inherit; + } else { + if (value.is_empty() || value.equals_ignoring_ascii_case("true"sv)) { + // "true", an empty string or a missing value map to the "true" state. + m_content_editable_state = ContentEditableState::True; + } else if (value.equals_ignoring_ascii_case("false"sv)) { + // "false" maps to the "false" state. + m_content_editable_state = ContentEditableState::False; + } else { + // Having no such attribute or an invalid value maps to the "inherit" state. + m_content_editable_state = ContentEditableState::Inherit; + } } } @@ -256,14 +260,6 @@ void HTMLElement::attribute_changed(DeprecatedFlyString const& name, DeprecatedS #undef __ENUMERATE } -void HTMLElement::did_remove_attribute(DeprecatedFlyString const& name) -{ - Base::did_remove_attribute(name); - if (name == HTML::AttributeNames::contenteditable) { - m_content_editable_state = ContentEditableState::Inherit; - } -} - // https://html.spec.whatwg.org/multipage/interaction.html#dom-focus void HTMLElement::focus() { diff --git a/Userland/Libraries/LibWeb/HTML/HTMLElement.h b/Userland/Libraries/LibWeb/HTML/HTMLElement.h index 7964c1bae2..52b7b200f1 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLElement.h @@ -71,7 +71,6 @@ protected: virtual JS::ThrowCompletionOr initialize(JS::Realm&) override; virtual void attribute_changed(DeprecatedFlyString const& name, DeprecatedString const& value) override; - virtual void did_remove_attribute(DeprecatedFlyString const& name) override; virtual void visit_edges(Cell::Visitor&) override; diff --git a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp index 05fe1408e7..8d6e257834 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp @@ -80,7 +80,11 @@ void HTMLImageElement::attribute_changed(DeprecatedFlyString const& name, Deprec HTMLElement::attribute_changed(name, value); if (name == HTML::AttributeNames::crossorigin) { - m_cors_setting = cors_setting_attribute_from_keyword(String::from_deprecated_string(value).release_value_but_fixme_should_propagate_errors()); + if (value.is_null()) { + m_cors_setting = CORSSettingAttribute::NoCORS; + } else { + m_cors_setting = cors_setting_attribute_from_keyword(String::from_deprecated_string(value).release_value_but_fixme_should_propagate_errors()); + } } if (name.is_one_of(HTML::AttributeNames::src, HTML::AttributeNames::srcset)) { @@ -93,15 +97,6 @@ void HTMLImageElement::attribute_changed(DeprecatedFlyString const& name, Deprec } } -void HTMLImageElement::did_remove_attribute(DeprecatedFlyString const& name) -{ - Base::did_remove_attribute(name); - - if (name == HTML::AttributeNames::crossorigin) { - m_cors_setting = CORSSettingAttribute::NoCORS; - } -} - JS::GCPtr HTMLImageElement::create_layout_node(NonnullRefPtr style) { return heap().allocate_without_realm(document(), *this, move(style), *this); diff --git a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.h b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.h index 22cb06ac80..8b8e33c2b4 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.h @@ -29,7 +29,6 @@ public: virtual ~HTMLImageElement() override; virtual void attribute_changed(DeprecatedFlyString const& name, DeprecatedString const& value) override; - virtual void did_remove_attribute(DeprecatedFlyString const& name) override; DeprecatedString alt() const { return attribute(HTML::AttributeNames::alt); } DeprecatedString src() const { return attribute(HTML::AttributeNames::src); } diff --git a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp index 60f0e64aae..99309bab65 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp @@ -497,16 +497,30 @@ void HTMLInputElement::attribute_changed(DeprecatedFlyString const& name, Deprec { HTMLElement::attribute_changed(name, value); if (name == HTML::AttributeNames::checked) { - // When the checked content attribute is added, if the control does not have dirty checkedness, - // the user agent must set the checkedness of the element to true - if (!m_dirty_checkedness) - set_checked(true, ChangeSource::Programmatic); + if (value.is_null()) { + // When the checked content attribute is removed, if the control does not have dirty checkedness, + // the user agent must set the checkedness of the element to false. + if (!m_dirty_checkedness) + set_checked(false, ChangeSource::Programmatic); + } else { + // When the checked content attribute is added, if the control does not have dirty checkedness, + // the user agent must set the checkedness of the element to true + if (!m_dirty_checkedness) + set_checked(true, ChangeSource::Programmatic); + } } else if (name == HTML::AttributeNames::type) { m_type = parse_type_attribute(value); } else if (name == HTML::AttributeNames::value) { - if (!m_dirty_value) { - m_value = value_sanitization_algorithm(value); - update_placeholder_visibility(); + if (value.is_null()) { + if (!m_dirty_value) { + m_value = DeprecatedString::empty(); + update_placeholder_visibility(); + } + } else { + if (!m_dirty_value) { + m_value = value_sanitization_algorithm(value); + update_placeholder_visibility(); + } } } else if (name == HTML::AttributeNames::placeholder) { if (m_placeholder_text_node) @@ -528,25 +542,6 @@ HTMLInputElement::TypeAttributeState HTMLInputElement::parse_type_attribute(Stri return HTMLInputElement::TypeAttributeState::Text; } -void HTMLInputElement::did_remove_attribute(DeprecatedFlyString const& name) -{ - HTMLElement::did_remove_attribute(name); - if (name == HTML::AttributeNames::checked) { - // When the checked content attribute is removed, if the control does not have dirty checkedness, - // the user agent must set the checkedness of the element to false. - if (!m_dirty_checkedness) - set_checked(false, ChangeSource::Programmatic); - } else if (name == HTML::AttributeNames::value) { - if (!m_dirty_value) { - m_value = DeprecatedString::empty(); - update_placeholder_visibility(); - } - } else if (name == HTML::AttributeNames::placeholder) { - if (m_placeholder_text_node) - m_placeholder_text_node->set_data({}); - } -} - DeprecatedString HTMLInputElement::type() const { switch (m_type) { @@ -1104,5 +1099,4 @@ bool HTMLInputElement::is_submit_button() const return type_state() == TypeAttributeState::SubmitButton || type_state() == TypeAttributeState::ImageButton; } - } diff --git a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h index 32bb601bce..89bddb5979 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h @@ -105,7 +105,6 @@ public: // ^HTMLElement virtual void attribute_changed(DeprecatedFlyString const&, DeprecatedString const&) override; - virtual void did_remove_attribute(DeprecatedFlyString const&) override; // ^FormAssociatedElement // https://html.spec.whatwg.org/multipage/forms.html#category-listed diff --git a/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp index bab284d995..d4512833b7 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp @@ -149,25 +149,6 @@ void HTMLLinkElement::resource_did_load() } } -void HTMLLinkElement::did_remove_attribute(DeprecatedFlyString const& attr) -{ - if (m_relationship & Relationship::Stylesheet) { - // https://html.spec.whatwg.org/multipage/links.html#link-type-stylesheet:fetch-and-process-the-linked-resource - // The appropriate times to fetch and process this type of link are: - if ( - // - When the href attribute of the link element of an external resource link that is already browsing-context connected is changed. - attr == AttributeNames::href || - // - When the disabled attribute of the link element of an external resource link that is already browsing-context connected is set, changed, or removed. - attr == AttributeNames::disabled || - // - When the crossorigin attribute of the link element of an external resource link that is already browsing-context connected is set, changed, or removed. - attr == AttributeNames::crossorigin - // FIXME: - When the type attribute of the link element of an external resource link that is already browsing-context connected, but was previously not obtained due to the type attribute specifying an unsupported type, is removed or changed. - ) { - fetch_and_process_linked_resource(); - } - } -} - // https://html.spec.whatwg.org/multipage/semantics.html#create-link-options-from-element HTMLLinkElement::LinkProcessingOptions HTMLLinkElement::create_link_options() { diff --git a/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.h b/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.h index 9f42f3432e..44c5087161 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.h @@ -46,7 +46,6 @@ private: virtual void resource_did_load() override; // ^ HTMLElement - virtual void did_remove_attribute(DeprecatedFlyString const&) override; virtual void visit_edges(Cell::Visitor&) override; struct LinkProcessingOptions { diff --git a/Userland/Libraries/LibWeb/HTML/HTMLMediaElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLMediaElement.cpp index 93f1e36086..d7d9e8b3cb 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLMediaElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLMediaElement.cpp @@ -88,20 +88,16 @@ void HTMLMediaElement::attribute_changed(DeprecatedFlyString const& name, Deprec { Base::attribute_changed(name, value); - if (name == HTML::AttributeNames::src) + if (name == HTML::AttributeNames::src) { load_element().release_value_but_fixme_should_propagate_errors(); - else if (name == HTML::AttributeNames::crossorigin) - m_crossorigin = cors_setting_attribute_from_keyword(String::from_deprecated_string(value).release_value_but_fixme_should_propagate_errors()); - else if (name == HTML::AttributeNames::muted) + } else if (name == HTML::AttributeNames::crossorigin) { + if (value.is_null()) + m_crossorigin = cors_setting_attribute_from_keyword({}); + else + m_crossorigin = cors_setting_attribute_from_keyword(String::from_deprecated_string(value).release_value_but_fixme_should_propagate_errors()); + } else if (name == HTML::AttributeNames::muted) { set_muted(true); -} - -void HTMLMediaElement::did_remove_attribute(DeprecatedFlyString const& name) -{ - Base::did_remove_attribute(name); - - if (name == HTML::AttributeNames::crossorigin) - m_crossorigin = cors_setting_attribute_from_keyword({}); + } } // https://html.spec.whatwg.org/multipage/media.html#playing-the-media-resource:media-element-83 diff --git a/Userland/Libraries/LibWeb/HTML/HTMLMediaElement.h b/Userland/Libraries/LibWeb/HTML/HTMLMediaElement.h index b5fe74636a..f3b3fc560e 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLMediaElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLMediaElement.h @@ -125,7 +125,6 @@ protected: virtual void visit_edges(Cell::Visitor&) override; virtual void attribute_changed(DeprecatedFlyString const& name, DeprecatedString const& value) override; - virtual void did_remove_attribute(DeprecatedFlyString const&) override; virtual void removed_from(DOM::Node*) override; virtual void children_changed() override; diff --git a/Userland/Libraries/LibWeb/HTML/HTMLOptionElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLOptionElement.cpp index 2c6c8d3d03..9b349aaf10 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLOptionElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLOptionElement.cpp @@ -38,22 +38,17 @@ void HTMLOptionElement::attribute_changed(DeprecatedFlyString const& name, Depre HTMLElement::attribute_changed(name, value); if (name == HTML::AttributeNames::selected) { - // Except where otherwise specified, when the element is created, its selectedness must be set to true - // if the element has a selected attribute. Whenever an option element's selected attribute is added, - // if its dirtiness is false, its selectedness must be set to true. - if (!m_dirty) - m_selected = true; - } -} - -void HTMLOptionElement::did_remove_attribute(DeprecatedFlyString const& name) -{ - HTMLElement::did_remove_attribute(name); - - if (name == HTML::AttributeNames::selected) { - // Whenever an option element's selected attribute is removed, if its dirtiness is false, its selectedness must be set to false. - if (!m_dirty) - m_selected = false; + if (value.is_null()) { + // Whenever an option element's selected attribute is removed, if its dirtiness is false, its selectedness must be set to false. + if (!m_dirty) + m_selected = false; + } else { + // Except where otherwise specified, when the element is created, its selectedness must be set to true + // if the element has a selected attribute. Whenever an option element's selected attribute is added, + // if its dirtiness is false, its selectedness must be set to true. + if (!m_dirty) + m_selected = true; + } } } diff --git a/Userland/Libraries/LibWeb/HTML/HTMLOptionElement.h b/Userland/Libraries/LibWeb/HTML/HTMLOptionElement.h index 402caeb84b..853e665010 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLOptionElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLOptionElement.h @@ -41,7 +41,6 @@ private: virtual JS::ThrowCompletionOr initialize(JS::Realm&) override; void attribute_changed(DeprecatedFlyString const& name, DeprecatedString const& value) override; - void did_remove_attribute(DeprecatedFlyString const& name) override; void ask_for_a_reset(); diff --git a/Userland/Libraries/LibWeb/HTML/HTMLScriptElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLScriptElement.cpp index ce978ecd5e..ff7b60d544 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLScriptElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLScriptElement.cpp @@ -51,20 +51,17 @@ void HTMLScriptElement::attribute_changed(DeprecatedFlyString const& name, Depre { Base::attribute_changed(name, value); - if (name == HTML::AttributeNames::crossorigin) - m_crossorigin = cors_setting_attribute_from_keyword(String::from_deprecated_string(value).release_value_but_fixme_should_propagate_errors()); - else if (name == HTML::AttributeNames::referrerpolicy) - m_referrer_policy = ReferrerPolicy::from_string(value); -} - -void HTMLScriptElement::did_remove_attribute(DeprecatedFlyString const& name) -{ - Base::did_remove_attribute(name); - - if (name == HTML::AttributeNames::crossorigin) - m_crossorigin = cors_setting_attribute_from_keyword({}); - else if (name == HTML::AttributeNames::referrerpolicy) - m_referrer_policy.clear(); + if (name == HTML::AttributeNames::crossorigin) { + if (value.is_null()) + m_crossorigin = cors_setting_attribute_from_keyword({}); + else + m_crossorigin = cors_setting_attribute_from_keyword(String::from_deprecated_string(value).release_value_but_fixme_should_propagate_errors()); + } else if (name == HTML::AttributeNames::referrerpolicy) { + if (value.is_null()) + m_referrer_policy.clear(); + else + m_referrer_policy = ReferrerPolicy::from_string(value); + } } void HTMLScriptElement::begin_delaying_document_load_event(DOM::Document& document) diff --git a/Userland/Libraries/LibWeb/HTML/HTMLScriptElement.h b/Userland/Libraries/LibWeb/HTML/HTMLScriptElement.h index 49a74be78b..cef831052b 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLScriptElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLScriptElement.h @@ -63,7 +63,6 @@ private: virtual void visit_edges(Cell::Visitor&) override; virtual void attribute_changed(DeprecatedFlyString const& name, DeprecatedString const& value) override; - virtual void did_remove_attribute(DeprecatedFlyString const&) override; // https://html.spec.whatwg.org/multipage/scripting.html#prepare-the-script-element void prepare_script(); diff --git a/Userland/Libraries/LibWeb/HTML/HTMLVideoElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLVideoElement.cpp index 1c2e9a018f..0149cae791 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLVideoElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLVideoElement.cpp @@ -46,16 +46,12 @@ void HTMLVideoElement::attribute_changed(DeprecatedFlyString const& name, Deprec { Base::attribute_changed(name, value); - if (name == HTML::AttributeNames::poster) - determine_element_poster_frame(value).release_value_but_fixme_should_propagate_errors(); -} - -void HTMLVideoElement::did_remove_attribute(DeprecatedFlyString const& name) -{ - Base::did_remove_attribute(name); - - if (name == HTML::AttributeNames::poster) - determine_element_poster_frame({}).release_value_but_fixme_should_propagate_errors(); + if (name == HTML::AttributeNames::poster) { + if (value.is_null()) + determine_element_poster_frame({}).release_value_but_fixme_should_propagate_errors(); + else + determine_element_poster_frame(value).release_value_but_fixme_should_propagate_errors(); + } } JS::GCPtr HTMLVideoElement::create_layout_node(NonnullRefPtr style) diff --git a/Userland/Libraries/LibWeb/HTML/HTMLVideoElement.h b/Userland/Libraries/LibWeb/HTML/HTMLVideoElement.h index ae676b8f0c..4ef7ce490a 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLVideoElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLVideoElement.h @@ -48,7 +48,6 @@ private: virtual void visit_edges(Cell::Visitor&) override; virtual void attribute_changed(DeprecatedFlyString const& name, DeprecatedString const& value) override; - virtual void did_remove_attribute(DeprecatedFlyString const&) override; virtual JS::GCPtr create_layout_node(NonnullRefPtr) override;