From 87cb00bafb54a61bc5e15994600a7a4626b7f62d Mon Sep 17 00:00:00 2001 From: Luke Warlow Date: Tue, 25 Feb 2025 14:48:00 +0000 Subject: [PATCH] Implement request-close command for dialogs https://bugs.webkit.org/show_bug.cgi?id=288476 Reviewed by NOBODY (OOPS!). Spec PR: https://github.com/whatwg/html/pull/11045 This patch implements the request-close command for dialog, this maps to the requestClose() method. * LayoutTests/TestExpectations: * LayoutTests/imported/w3c/web-platform-tests/html/semantics/the-button-element/command-and-commandfor/on-dialog-behavior-request-close.tentative-expected.txt: Added. * Source/WebCore/dom/Element.h: * Source/WebCore/html/HTMLButtonElement.cpp: (WebCore::HTMLButtonElement::commandType const): * Source/WebCore/html/HTMLDialogElement.cpp: (WebCore::HTMLDialogElement::isValidCommandType): (WebCore::HTMLDialogElement::handleCommandInternal): --- LayoutTests/TestExpectations | 1 - ...avior-request-close.tentative-expected.txt | 33 +++++++++++++++++++ Source/WebCore/dom/Element.h | 1 + Source/WebCore/html/HTMLButtonElement.cpp | 4 +++ Source/WebCore/html/HTMLDialogElement.cpp | 7 +++- 5 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 LayoutTests/imported/w3c/web-platform-tests/html/semantics/the-button-element/command-and-commandfor/on-dialog-behavior-request-close.tentative-expected.txt diff --git a/LayoutTests/TestExpectations b/LayoutTests/TestExpectations index 49b5d36022090..c93c2167c46c4 100644 --- a/LayoutTests/TestExpectations +++ b/LayoutTests/TestExpectations @@ -2952,7 +2952,6 @@ http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-css-i imported/w3c/web-platform-tests/css/css-text/text-spacing-trim [ Skip ] # command/commandfor future: These tests cover additions to the command invokers API which aren't specced yet -imported/w3c/web-platform-tests/html/semantics/the-button-element/command-and-commandfor/on-dialog-behavior-request-close.tentative.html [ Skip ] imported/w3c/web-platform-tests/html/semantics/the-button-element/command-and-commandfor/fullscreen-behavior.tentative.html [ Skip ] imported/w3c/web-platform-tests/html/semantics/the-button-element/command-and-commandfor/on-audio-behavior.tentative.html [ Skip ] imported/w3c/web-platform-tests/html/semantics/the-button-element/command-and-commandfor/on-audio-invalid-behavior.tentative.html [ Skip ] diff --git a/LayoutTests/imported/w3c/web-platform-tests/html/semantics/the-button-element/command-and-commandfor/on-dialog-behavior-request-close.tentative-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/html/semantics/the-button-element/command-and-commandfor/on-dialog-behavior-request-close.tentative-expected.txt new file mode 100644 index 0000000000000..cb56fcd4743d7 --- /dev/null +++ b/LayoutTests/imported/w3c/web-platform-tests/html/semantics/the-button-element/command-and-commandfor/on-dialog-behavior-request-close.tentative-expected.txt @@ -0,0 +1,33 @@ + + +PASS invoking to request-close (with command property as request-close) open dialog closes +PASS invoking to request-close with value (with command property as request-close) open dialog closes and sets returnValue +PASS invoking to request-close (with command property as request-close) open dialog with preventDefault is no-op +PASS invoking to request-close (with command property as request-close) open modal dialog with preventDefault is no-op +PASS invoking to request-close (with command property as request-close) open dialog while changing command still closes +PASS invoking to request-close (with command property as request-close) open modal dialog while changing command still closes +PASS invoking to request-close (with command attribute as request-close) open dialog closes +PASS invoking to request-close with value (with command attribute as request-close) open dialog closes and sets returnValue +PASS invoking to request-close (with command attribute as request-close) open dialog with preventDefault is no-op +PASS invoking to request-close (with command attribute as request-close) open modal dialog with preventDefault is no-op +PASS invoking to request-close (with command attribute as request-close) open dialog while changing command still closes +PASS invoking to request-close (with command attribute as request-close) open modal dialog while changing command still closes +PASS invoking to request-close (with command property as reQuEst-Close) open dialog closes +PASS invoking to request-close with value (with command property as reQuEst-Close) open dialog closes and sets returnValue +PASS invoking to request-close (with command property as reQuEst-Close) open dialog with preventDefault is no-op +PASS invoking to request-close (with command property as reQuEst-Close) open modal dialog with preventDefault is no-op +PASS invoking to request-close (with command property as reQuEst-Close) open dialog while changing command still closes +PASS invoking to request-close (with command property as reQuEst-Close) open modal dialog while changing command still closes +PASS invoking to request-close (with command attribute as reQuEst-Close) open dialog closes +PASS invoking to request-close with value (with command attribute as reQuEst-Close) open dialog closes and sets returnValue +PASS invoking to request-close (with command attribute as reQuEst-Close) open dialog with preventDefault is no-op +PASS invoking to request-close (with command attribute as reQuEst-Close) open modal dialog with preventDefault is no-op +PASS invoking to request-close (with command attribute as reQuEst-Close) open dialog while changing command still closes +PASS invoking to request-close (with command attribute as reQuEst-Close) open modal dialog while changing command still closes +PASS invoking (as request-close) already closed dialog is noop +PASS invoking (as request-close) dialog as open popover=manual is noop +PASS invoking (as request-close) dialog as open popover=auto is noop +PASS invoking (as request-close) dialog that is removed is noop +PASS invoking (as request-close) dialog from a detached invoker +PASS invoking (as request-close) detached dialog from a detached invoker + diff --git a/Source/WebCore/dom/Element.h b/Source/WebCore/dom/Element.h index a05cabe46ecef..b55c40e3fe4d7 100644 --- a/Source/WebCore/dom/Element.h +++ b/Source/WebCore/dom/Element.h @@ -121,6 +121,7 @@ enum class CommandType: uint8_t { ShowModal, Close, + RequestClose, }; struct CheckVisibilityOptions; diff --git a/Source/WebCore/html/HTMLButtonElement.cpp b/Source/WebCore/html/HTMLButtonElement.cpp index b9c3c9249c66f..0c72bbebe06c0 100644 --- a/Source/WebCore/html/HTMLButtonElement.cpp +++ b/Source/WebCore/html/HTMLButtonElement.cpp @@ -154,6 +154,7 @@ constexpr ASCIILiteral showPopoverLiteral = "show-popover"_s; constexpr ASCIILiteral hidePopoverLiteral = "hide-popover"_s; constexpr ASCIILiteral showModalLiteral = "show-modal"_s; constexpr ASCIILiteral closeLiteral = "close"_s; +constexpr ASCIILiteral requestCloseLiteral = "request-close"_s; CommandType HTMLButtonElement::commandType() const { auto action = attributeWithoutSynchronization(HTMLNames::commandAttr); @@ -175,6 +176,9 @@ CommandType HTMLButtonElement::commandType() const if (equalLettersIgnoringASCIICase(action, closeLiteral)) return CommandType::Close; + if (equalLettersIgnoringASCIICase(action, requestCloseLiteral)) + return CommandType::RequestClose; + if (action.startsWith("--"_s)) return CommandType::Custom; diff --git a/Source/WebCore/html/HTMLDialogElement.cpp b/Source/WebCore/html/HTMLDialogElement.cpp index 41044468cd11a..b1f9f6c72a39b 100644 --- a/Source/WebCore/html/HTMLDialogElement.cpp +++ b/Source/WebCore/html/HTMLDialogElement.cpp @@ -195,7 +195,8 @@ void HTMLDialogElement::requestClose(const String& returnValue) bool HTMLDialogElement::isValidCommandType(const CommandType command) { - return HTMLElement::isValidCommandType(command) || command == CommandType::ShowModal || command == CommandType::Close; + return HTMLElement::isValidCommandType(command) || command == CommandType::ShowModal || command == CommandType::Close + || command == CommandType::RequestClose; } bool HTMLDialogElement::handleCommandInternal(const HTMLButtonElement& invoker, const CommandType& command) @@ -211,6 +212,10 @@ bool HTMLDialogElement::handleCommandInternal(const HTMLButtonElement& invoker, close(invoker.value().string()); return true; } + if (command == CommandType::RequestClose) { + requestClose(invoker.value().string()); + return true; + } } else { if (command == CommandType::ShowModal) { showModal();