From 56d7f894da59a5d699530cb396dbc9400f1836d1 Mon Sep 17 00:00:00 2001 From: Tim Nguyen Date: Thu, 8 Dec 2022 10:28:20 -0800 Subject: [PATCH] Make fullscreen elements match the :modal pseudo-class https://bugs.webkit.org/show_bug.cgi?id=246004 rdar://100782746 Reviewed by Antti Koivisto. https://w3c.github.io/csswg-drafts/selectors/#modal-state > For example, the dialog element is :modal when opened with the showModal() API. > Similarly, a :fullscreen element is also :modal when opened with the requestFullscreen() API, since this prevents interaction with the rest of the page. We implemented the "prevents interaction with the rest of the page" part in https://commits.webkit.org/253803@main Relevant CSSWG discussion: https://github.com/w3c/csswg-drafts/issues/7311 Also, we don't need to worry about the modal dialog in fullscreen mode case, since the fullscreen API forbids elements. * LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/css/selectors/modal-pseudo-class-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/modal-pseudo-class-in-has-expected.txt: * LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/modal-pseudo-class-in-has.html: * LayoutTests/imported/w3c/web-platform-tests/css/selectors/modal-pseudo-class-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/css/selectors/modal-pseudo-class.html: Added. * LayoutTests/imported/w3c/web-platform-tests/css/selectors/w3c-import.log: * Source/WebCore/css/SelectorCheckerTestFunctions.h: (WebCore::matchesModalPseudoClass): * Source/WebCore/dom/Element.cpp: (WebCore::Element::setFullscreenFlag): Canonical link: https://commits.webkit.org/257572@main --- .../modal-pseudo-class-in-has-expected.txt | 6 +- .../modal-pseudo-class-in-has.html | 46 +++++++++++++-- .../selectors/modal-pseudo-class-expected.txt | 5 ++ .../css/selectors/modal-pseudo-class.html | 59 +++++++++++++++++++ .../css/selectors/w3c-import.log | 1 + .../selectors/modal-pseudo-class-expected.txt | 5 ++ .../css/SelectorCheckerTestFunctions.h | 4 ++ Source/WebCore/dom/Element.cpp | 2 +- 8 files changed, 120 insertions(+), 8 deletions(-) create mode 100644 LayoutTests/imported/w3c/web-platform-tests/css/selectors/modal-pseudo-class-expected.txt create mode 100644 LayoutTests/imported/w3c/web-platform-tests/css/selectors/modal-pseudo-class.html create mode 100644 LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/css/selectors/modal-pseudo-class-expected.txt diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/modal-pseudo-class-in-has-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/modal-pseudo-class-in-has-expected.txt index 2bf24feaeb5eb..1ccf44b7ad00b 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/modal-pseudo-class-in-has-expected.txt +++ b/LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/modal-pseudo-class-in-has-expected.txt @@ -1,6 +1,8 @@ This is some text. PASS :modal pseudo-class is not active with dialog.show() -PASS :modal pseudo-class invalidation with showModal+close -PASS :modal pseudo-class invalidation with showModal+remove +PASS :modal pseudo-class invalidation with showModal + close +PASS :modal pseudo-class invalidation with showModal + remove +PASS :modal pseudo-class invalidation with requestFullscreen + exitFullscreen +PASS :modal pseudo-class invalidation with requestFullscreen + remove diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/modal-pseudo-class-in-has.html b/LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/modal-pseudo-class-in-has.html index 9c487fba16fda..1bff896d49e97 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/modal-pseudo-class-in-has.html +++ b/LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/modal-pseudo-class-in-has.html @@ -5,14 +5,19 @@ + +
This is some text. This is a dialog +
This is going to be fullscreened
\ No newline at end of file + "ancestor should be black since dialog is removed"); + }, ":modal pseudo-class invalidation with showModal + remove"); + + // Fullscreen tests + let waitForFullscreenChange = () => { + return new Promise((resolve) => { + document.addEventListener("fullscreenchange", resolve, { once: true }); + }); + }; + promise_test(async function() { + assert_equals(getComputedStyle(subject).color, "rgb(0, 0, 0)", + "ancestor should be black"); + test_driver.bless("fullscreen", () => fullscreenTarget.requestFullscreen()); + await waitForFullscreenChange(); + assert_equals(getComputedStyle(subject).color, "rgb(0, 0, 255)", + "ancestor should be blue since target is fullscreen"); + document.exitFullscreen(); + await waitForFullscreenChange(); + assert_equals(getComputedStyle(subject).color, "rgb(0, 0, 0)", + "ancestor should be black since target is no longer fullscreen"); + }, ":modal pseudo-class invalidation with requestFullscreen + exitFullscreen"); + promise_test(async function() { + assert_equals(getComputedStyle(subject).color, "rgb(0, 0, 0)", + "ancestor should be black"); + test_driver.bless("fullscreen", () => fullscreenTarget.requestFullscreen()); + await waitForFullscreenChange(); + assert_equals(getComputedStyle(subject).color, "rgb(0, 0, 255)", + "ancestor should be blue since target is fullscreen"); + fullscreenTarget.remove(); + await waitForFullscreenChange(); + assert_equals(getComputedStyle(subject).color, "rgb(0, 0, 0)", + "ancestor should be black since target is removed"); + }, ":modal pseudo-class invalidation with requestFullscreen + remove"); + diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/selectors/modal-pseudo-class-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/css/selectors/modal-pseudo-class-expected.txt new file mode 100644 index 0000000000000..fa6e2bfa1aeff --- /dev/null +++ b/LayoutTests/imported/w3c/web-platform-tests/css/selectors/modal-pseudo-class-expected.txt @@ -0,0 +1,5 @@ + + +PASS Test that :modal matches modal +PASS Test that :modal matches the fullscreen element + diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/selectors/modal-pseudo-class.html b/LayoutTests/imported/w3c/web-platform-tests/css/selectors/modal-pseudo-class.html new file mode 100644 index 0000000000000..079f4063d45c3 --- /dev/null +++ b/LayoutTests/imported/w3c/web-platform-tests/css/selectors/modal-pseudo-class.html @@ -0,0 +1,59 @@ + + +:modal pseudo-class + + + + + + + + +Just another dialog. +
+
+ + diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/selectors/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/css/selectors/w3c-import.log index 1ba0a25fb5d64..7329d8addbd68 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/css/selectors/w3c-import.log +++ b/LayoutTests/imported/w3c/web-platform-tests/css/selectors/w3c-import.log @@ -215,6 +215,7 @@ List of files: /LayoutTests/imported/w3c/web-platform-tests/css/selectors/last-child.html /LayoutTests/imported/w3c/web-platform-tests/css/selectors/last-of-type.html /LayoutTests/imported/w3c/web-platform-tests/css/selectors/missing-right-token.html +/LayoutTests/imported/w3c/web-platform-tests/css/selectors/modal-pseudo-class.html /LayoutTests/imported/w3c/web-platform-tests/css/selectors/nesting-expected.html /LayoutTests/imported/w3c/web-platform-tests/css/selectors/nesting-parsing.html /LayoutTests/imported/w3c/web-platform-tests/css/selectors/nesting-ref.html diff --git a/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/css/selectors/modal-pseudo-class-expected.txt b/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/css/selectors/modal-pseudo-class-expected.txt new file mode 100644 index 0000000000000..8303c33d81260 --- /dev/null +++ b/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/css/selectors/modal-pseudo-class-expected.txt @@ -0,0 +1,5 @@ + + +PASS Test that :modal matches modal +FAIL Test that :modal matches the fullscreen element assert_true: :fullscreen should match :modal expected true got false + diff --git a/Source/WebCore/css/SelectorCheckerTestFunctions.h b/Source/WebCore/css/SelectorCheckerTestFunctions.h index d4ea1e981b87a..0bac3a369e07d 100644 --- a/Source/WebCore/css/SelectorCheckerTestFunctions.h +++ b/Source/WebCore/css/SelectorCheckerTestFunctions.h @@ -566,7 +566,11 @@ ALWAYS_INLINE bool matchesModalPseudoClass(const Element& element) { if (is(element)) return downcast(element).isModal(); +#if ENABLE(FULLSCREEN_API) + return element.hasFullscreenFlag(); +#else return false; +#endif } } // namespace WebCore diff --git a/Source/WebCore/dom/Element.cpp b/Source/WebCore/dom/Element.cpp index 77f66d7435e0d..faf2fe5234af1 100644 --- a/Source/WebCore/dom/Element.cpp +++ b/Source/WebCore/dom/Element.cpp @@ -4169,7 +4169,7 @@ void Element::requestFullscreen(FullscreenOptions&&, RefPtr&& p void Element::setFullscreenFlag(bool flag) { - Style::PseudoClassChangeInvalidation styleInvalidation(*this, CSSSelector::PseudoClassFullscreen, flag); + Style::PseudoClassChangeInvalidation styleInvalidation(*this, { { CSSSelector::PseudoClassFullscreen, flag }, { CSSSelector::PseudoClassModal, flag } }); if (flag) setNodeFlag(NodeFlag::IsFullscreen); else