Skip to content

Commit

Permalink
LibWeb: Implement dialog closedby attribute
Browse files Browse the repository at this point in the history
closedby=any should add light-dismiss behavior to dialog,
this isn't implemented in this patch.
  • Loading branch information
lukewarlow committed Feb 3, 2025
1 parent 17c0d44 commit dd06a3e
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 6 deletions.
3 changes: 2 additions & 1 deletion Libraries/LibWeb/HTML/AttributeNames.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ namespace AttributeNames {
__ENUMERATE_HTML_ATTRIBUTE(cite, "cite") \
__ENUMERATE_HTML_ATTRIBUTE(class_, "class") \
__ENUMERATE_HTML_ATTRIBUTE(classid, "classid") \
__ENUMERATE_HTML_ATTRIBUTE(clear, "clear") \
__ENUMERATE_HTML_ATTRIBUTE(clear, "clear") \
__ENUMERATE_HTML_ATTRIBUTE(closedby, "closedby") \
__ENUMERATE_HTML_ATTRIBUTE(code, "code") \
__ENUMERATE_HTML_ATTRIBUTE(codebase, "codebase") \
__ENUMERATE_HTML_ATTRIBUTE(codetype, "codetype") \
Expand Down
30 changes: 26 additions & 4 deletions Libraries/LibWeb/HTML/HTMLDialogElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,9 +254,8 @@ void HTMLDialogElement::request_close(Optional<String> return_value)
m_close_watcher->request_close(false);
// 7. Set dialog's enable close watcher for requestClose() to false.
// ADHOC: Implemented slightly differently to the spec, as the spec is unnecessarily complex.
// FIXME: This should be set based on dialog closedby state, when implemented.
if (m_close_watcher)
m_close_watcher->set_enabled(m_is_modal);
m_close_watcher->set_enabled(closed_by() != "none");
}

// https://html.spec.whatwg.org/multipage/interactive-elements.html#dom-dialog-returnvalue
Expand All @@ -271,6 +270,21 @@ void HTMLDialogElement::set_return_value(String return_value)
m_return_value = move(return_value);
}

String HTMLDialogElement::closed_by() const
{
auto value = get_attribute(HTML::AttributeNames::closedby);

if (value.has_value() && (value.value() == "none" || value.value() == "closerequest" || value.value() == "any"))
return value.value();

return m_is_modal ? "closerequest"_string : "none"_string;
}

WebIDL::ExceptionOr<void> HTMLDialogElement::set_closed_by(String value)
{
return set_attribute(HTML::AttributeNames::closedby, value);
}

// https://html.spec.whatwg.org/multipage/interactive-elements.html#close-the-dialog
void HTMLDialogElement::close_the_dialog(Optional<String> result)
{
Expand Down Expand Up @@ -364,8 +378,7 @@ void HTMLDialogElement::set_close_watcher()
m_close_watcher->add_event_listener_without_options(HTML::EventNames::close, DOM::IDLEventListener::create(realm(), close_callback));
// - getEnabledState being to return true if dialog's enable close watcher for requestClose() is true or dialog's computed closed-by state is not None; otherwise false.
// ADHOC: Implemented slightly differently to the spec, as the spec is unnecessarily complex.
// FIXME: This should be set based on dialog closedby state, when implemented.
m_close_watcher->set_enabled(m_is_modal);
m_close_watcher->set_enabled(closed_by() != "none");
}

// https://html.spec.whatwg.org/multipage/interactive-elements.html#dialog-focusing-steps
Expand All @@ -385,4 +398,13 @@ void HTMLDialogElement::run_dialog_focusing_steps()
run_focusing_steps(control);
}

void HTMLDialogElement::attribute_changed(FlyString const& name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_)
{
Base::attribute_changed(name, old_value, value, namespace_);

// ADHOC: This is part of the implementation of dialog close watcher's getEnabledState.
if (name == HTML::AttributeNames::closedby && m_close_watcher && old_value != value)
m_close_watcher->set_enabled(closed_by() != "none");
}

}
6 changes: 6 additions & 0 deletions Libraries/LibWeb/HTML/HTMLDialogElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ class HTMLDialogElement final : public HTMLElement {
String return_value() const;
void set_return_value(String);

String closed_by() const;
WebIDL::ExceptionOr<void> set_closed_by(String);

WebIDL::ExceptionOr<void> show();
WebIDL::ExceptionOr<void> show_modal();
void close(Optional<String> return_value);
Expand All @@ -42,6 +45,9 @@ class HTMLDialogElement final : public HTMLElement {
virtual void initialize(JS::Realm&) override;
virtual void visit_edges(Cell::Visitor&) override;

// ^DOM::Element
virtual void attribute_changed(FlyString const& name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_) override;

void queue_a_dialog_toggle_event_task(String old_state, String new_state);

void close_the_dialog(Optional<String> result);
Expand Down
2 changes: 1 addition & 1 deletion Libraries/LibWeb/HTML/HTMLDialogElement.idl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ interface HTMLDialogElement : HTMLElement {

[CEReactions, Reflect] attribute boolean open;
attribute DOMString returnValue;
[FIXME, CEReactions] attribute DOMString closedBy;
[CEReactions] attribute DOMString closedBy;
[CEReactions] undefined show();
[CEReactions] undefined showModal();
[CEReactions] undefined close(optional DOMString returnValue);
Expand Down

0 comments on commit dd06a3e

Please sign in to comment.