Title: [293987] trunk
Revision
293987
Author
n...@apple.com
Date
2022-05-09 13:37:15 -0700 (Mon, 09 May 2022)

Log Message

Implement CSS :modal pseudo class
https://bugs.webkit.org/show_bug.cgi?id=240109

Reviewed by Simon Fraser.

LayoutTests/imported/w3c:

Add and extend tests for :modal pseudo-class.

* web-platform-tests/css/selectors/invalidation/modal-pseudo-class-in-has-expected.txt: Added.
* web-platform-tests/css/selectors/invalidation/modal-pseudo-class-in-has.html: Added.
* web-platform-tests/html/semantics/interactive-elements/the-dialog-element/dialog-show-modal.html:

Source/WebCore:

Test: imported/w3c/web-platform-tests/css/selectors/invalidation/modal-pseudo-class-in-has.html

Renames :-internal-modal-dialog to :modal and adds :has() invalidation support.

* css/CSSSelector.cpp:
(WebCore::CSSSelector::selectorText const):
* css/CSSSelector.h:
* css/SelectorChecker.cpp:
(WebCore::SelectorChecker::checkOne const):
* css/SelectorCheckerTestFunctions.h:
(WebCore::matchesModalPseudoClass):
(WebCore::matchesModalDialogPseudoClass): Deleted.
* css/SelectorPseudoClassAndCompatibilityElementMap.in:
* css/dialog.css:
(dialog:modal):
(dialog:-internal-modal-dialog): Deleted.
* css/parser/CSSSelectorParser.cpp:
(WebCore::CSSSelectorParser::consumePseudo):
* cssjit/SelectorCompiler.cpp:
(WebCore::SelectorCompiler::JSC_DEFINE_JIT_OPERATION):
(WebCore::SelectorCompiler::addPseudoClassType):
* html/HTMLDialogElement.cpp:
(WebCore::HTMLDialogElement::showModal):
(WebCore::HTMLDialogElement::close):
(WebCore::HTMLDialogElement::removedFromAncestor):
(WebCore::HTMLDialogElement::setIsModal):
* html/HTMLDialogElement.h:

LayoutTests:

Removes :-internal-modal-dialog from internal pseudo classes.

* fast/css/pseudo-class-internal-expected.txt:
* fast/css/pseudo-class-internal.html:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (293986 => 293987)


--- trunk/LayoutTests/ChangeLog	2022-05-09 20:04:36 UTC (rev 293986)
+++ trunk/LayoutTests/ChangeLog	2022-05-09 20:37:15 UTC (rev 293987)
@@ -1,3 +1,15 @@
+2022-05-09  Tim Nguyen  <n...@apple.com>
+
+        Implement CSS :modal pseudo class
+        https://bugs.webkit.org/show_bug.cgi?id=240109
+
+        Reviewed by Simon Fraser.
+
+        Removes :-internal-modal-dialog from internal pseudo classes.
+
+        * fast/css/pseudo-class-internal-expected.txt:
+        * fast/css/pseudo-class-internal.html:
+
 2022-05-09  Arcady Goldmints-Orlov  <agoldmi...@igalia.com>
 
         [GLIB] Update some test expectations for known failures

Modified: trunk/LayoutTests/fast/css/pseudo-class-internal-expected.txt (293986 => 293987)


--- trunk/LayoutTests/fast/css/pseudo-class-internal-expected.txt	2022-05-09 20:04:36 UTC (rev 293986)
+++ trunk/LayoutTests/fast/css/pseudo-class-internal-expected.txt	2022-05-09 20:37:15 UTC (rev 293987)
@@ -4,7 +4,6 @@
 
 
 PASS target.matches(":-internal-direct-focus") threw exception SyntaxError: The string did not match the expected pattern..
-PASS target.matches(":-internal-modal-dialog") threw exception SyntaxError: The string did not match the expected pattern..
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/fast/css/pseudo-class-internal.html (293986 => 293987)


--- trunk/LayoutTests/fast/css/pseudo-class-internal.html	2022-05-09 20:04:36 UTC (rev 293986)
+++ trunk/LayoutTests/fast/css/pseudo-class-internal.html	2022-05-09 20:37:15 UTC (rev 293987)
@@ -10,7 +10,6 @@
 function runTest() {
     const internalPseudoClasses = [
         ':-internal-direct-focus',
-        ':-internal-modal-dialog',
     ];
     for (const pseudo of internalPseudoClasses) {
         shouldThrowErrorName('target.matches("' + pseudo + '")', 'SyntaxError');

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (293986 => 293987)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2022-05-09 20:04:36 UTC (rev 293986)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2022-05-09 20:37:15 UTC (rev 293987)
@@ -1,3 +1,16 @@
+2022-05-09  Tim Nguyen  <n...@apple.com>
+
+        Implement CSS :modal pseudo class
+        https://bugs.webkit.org/show_bug.cgi?id=240109
+
+        Reviewed by Simon Fraser.
+
+        Add and extend tests for :modal pseudo-class.
+
+        * web-platform-tests/css/selectors/invalidation/modal-pseudo-class-in-has-expected.txt: Added.
+        * web-platform-tests/css/selectors/invalidation/modal-pseudo-class-in-has.html: Added.
+        * web-platform-tests/html/semantics/interactive-elements/the-dialog-element/dialog-show-modal.html:
+
 2022-05-06  Rob Buis  <rb...@igalia.com>
 
         Use correct document as root for lazy image observer

Added: trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/modal-pseudo-class-in-has-expected.txt (0 => 293987)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/modal-pseudo-class-in-has-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/modal-pseudo-class-in-has-expected.txt	2022-05-09 20:37:15 UTC (rev 293987)
@@ -0,0 +1,6 @@
+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
+

Added: trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/modal-pseudo-class-in-has.html (0 => 293987)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/modal-pseudo-class-in-has.html	                        (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/modal-pseudo-class-in-has.html	2022-05-09 20:37:15 UTC (rev 293987)
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<title>CSS Selectors Invalidation: :modal pseudo class in :has()</title>
+<link rel="author" title="Tim Nguyen" href=""
+<link rel="help" href=""
+<script src=""
+<script src=""
+<style>
+  #subject:has(#dialog:modal) { color: green }
+</style>
+<div id="subject">
+  This is some text.
+  <dialog id="dialog">This is a dialog</dialog>
+</div>
+<script>
+  test(function() {
+    assert_equals(getComputedStyle(subject).color, "rgb(0, 0, 0)",
+                  "ancestor should be black since dialog is not modal");
+    dialog.show();
+    assert_equals(getComputedStyle(subject).color, "rgb(0, 0, 0)",
+                  "ancestor should be black since dialog is not modal");
+    dialog.close();
+  }, ":modal pseudo-class is not active with dialog.show()");
+  test(function() {
+    assert_equals(getComputedStyle(subject).color, "rgb(0, 0, 0)",
+                  "ancestor should be black");
+    dialog.showModal();
+    assert_equals(getComputedStyle(subject).color, "rgb(0, 128, 0)",
+                  "ancestor should be green since dialog is shown modally");
+    dialog.close();
+    assert_equals(getComputedStyle(subject).color, "rgb(0, 0, 0)",
+                  "ancestor should be black since dialog is closed");
+  }, ":modal pseudo-class invalidation with showModal+close");
+  test(function() {
+    assert_equals(getComputedStyle(subject).color, "rgb(0, 0, 0)",
+                  "ancestor should be black");
+    dialog.showModal();
+    assert_equals(getComputedStyle(subject).color, "rgb(0, 128, 0)",
+                  "ancestor should be green since dialog is shown modally");
+    dialog.remove();
+    assert_equals(getComputedStyle(subject).color, "rgb(0, 0, 0)",
+                  "ancestor should be black since dialog is closed");
+  }, ":modal pseudo-class invalidation with showModal+remove");
+</script>
\ No newline at end of file

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/interactive-elements/the-dialog-element/dialog-show-modal.html (293986 => 293987)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/interactive-elements/the-dialog-element/dialog-show-modal.html	2022-05-09 20:04:36 UTC (rev 293986)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/interactive-elements/the-dialog-element/dialog-show-modal.html	2022-05-09 20:37:15 UTC (rev 293987)
@@ -10,26 +10,29 @@
 
 <script>
 test(() => {
-  const dialog = document.getElementById('mydialog');
+  const dialog = document.getElementById("mydialog");
   const computedStyle = window.getComputedStyle(dialog, null);
-  assert_equals(computedStyle.display, 'none');
+  assert_equals(computedStyle.display, "none");
+  assert_false(dialog.matches(":modal"));
 
   dialog.showModal();
-  assert_equals(computedStyle.display, 'block');
+  assert_equals(computedStyle.display, "block");
+  assert_true(dialog.matches(":modal"));
 
   // The quoted texts output below are from <http://www.whatwg.org/specs/web-apps/current-work/multipage/commands.html#dom-dialog-showmodal>.
-  assert_throws_dom('InvalidStateError', () => dialog.showModal());
+  assert_throws_dom("InvalidStateError", () => dialog.showModal());
 
   dialog.close();
-  assert_equals(computedStyle.display, 'none');
+  assert_equals(computedStyle.display, "none");
+  assert_false(dialog.matches(":modal"));
 
   dialog.parentNode.removeChild(dialog);
-  assert_throws_dom('InvalidStateError', () => dialog.showModal());
+  assert_throws_dom("InvalidStateError", () => dialog.showModal());
 
   const doc = document.implementation.createHTMLDocument();
   doc.body.appendChild(dialog);
   assert_false(dialog.open);
   dialog.showModal();
-  assert_true(dialog.open, 'Although the document is not attached to any pages, showModal() should execute as normal.');
-}, 'Tests that showModal() performs the steps specified in the HTML spec.');
+  assert_true(dialog.open, "Although the document is not attached to any pages, showModal() should execute as normal.");
+}, "Tests that showModal() performs the steps specified in the HTML spec.");
 </script>

Modified: trunk/Source/WebCore/ChangeLog (293986 => 293987)


--- trunk/Source/WebCore/ChangeLog	2022-05-09 20:04:36 UTC (rev 293986)
+++ trunk/Source/WebCore/ChangeLog	2022-05-09 20:37:15 UTC (rev 293987)
@@ -1,3 +1,38 @@
+2022-05-09  Tim Nguyen  <n...@apple.com>
+
+        Implement CSS :modal pseudo class
+        https://bugs.webkit.org/show_bug.cgi?id=240109
+
+        Reviewed by Simon Fraser.
+
+        Test: imported/w3c/web-platform-tests/css/selectors/invalidation/modal-pseudo-class-in-has.html
+
+        Renames :-internal-modal-dialog to :modal and adds :has() invalidation support.
+
+        * css/CSSSelector.cpp:
+        (WebCore::CSSSelector::selectorText const):
+        * css/CSSSelector.h:
+        * css/SelectorChecker.cpp:
+        (WebCore::SelectorChecker::checkOne const):
+        * css/SelectorCheckerTestFunctions.h:
+        (WebCore::matchesModalPseudoClass):
+        (WebCore::matchesModalDialogPseudoClass): Deleted.
+        * css/SelectorPseudoClassAndCompatibilityElementMap.in:
+        * css/dialog.css:
+        (dialog:modal):
+        (dialog:-internal-modal-dialog): Deleted.
+        * css/parser/CSSSelectorParser.cpp:
+        (WebCore::CSSSelectorParser::consumePseudo):
+        * cssjit/SelectorCompiler.cpp:
+        (WebCore::SelectorCompiler::JSC_DEFINE_JIT_OPERATION):
+        (WebCore::SelectorCompiler::addPseudoClassType):
+        * html/HTMLDialogElement.cpp:
+        (WebCore::HTMLDialogElement::showModal):
+        (WebCore::HTMLDialogElement::close):
+        (WebCore::HTMLDialogElement::removedFromAncestor):
+        (WebCore::HTMLDialogElement::setIsModal):
+        * html/HTMLDialogElement.h:
+
 2022-05-09  Gabriel Nava Marino  <gnavamar...@apple.com>
 
         ASSERT in WebCore::RenderTreeUpdater::updateRenderTree

Modified: trunk/Source/WebCore/css/CSSSelector.cpp (293986 => 293987)


--- trunk/Source/WebCore/css/CSSSelector.cpp	2022-05-09 20:04:36 UTC (rev 293986)
+++ trunk/Source/WebCore/css/CSSSelector.cpp	2022-05-09 20:37:15 UTC (rev 293987)
@@ -591,8 +591,8 @@
             case CSSSelector::PseudoClassLink:
                 builder.append(":link");
                 break;
-            case CSSSelector::PseudoClassModalDialog:
-                builder.append(":-internal-modal-dialog");
+            case CSSSelector::PseudoClassModal:
+                builder.append(":modal");
                 break;
             case CSSSelector::PseudoClassNoButton:
                 builder.append(":no-button");

Modified: trunk/Source/WebCore/css/CSSSelector.h (293986 => 293987)


--- trunk/Source/WebCore/css/CSSSelector.h	2022-05-09 20:04:36 UTC (rev 293986)
+++ trunk/Source/WebCore/css/CSSSelector.h	2022-05-09 20:37:15 UTC (rev 293987)
@@ -185,7 +185,7 @@
 #if ENABLE(ATTACHMENT_ELEMENT)
             PseudoClassHasAttachment,
 #endif
-            PseudoClassModalDialog,
+            PseudoClassModal,
         };
 
         enum PseudoElementType {

Modified: trunk/Source/WebCore/css/SelectorChecker.cpp (293986 => 293987)


--- trunk/Source/WebCore/css/SelectorChecker.cpp	2022-05-09 20:04:36 UTC (rev 293986)
+++ trunk/Source/WebCore/css/SelectorChecker.cpp	2022-05-09 20:37:15 UTC (rev 293987)
@@ -1132,8 +1132,8 @@
             return hasAttachment(element);
 #endif
 
-        case CSSSelector::PseudoClassModalDialog:
-            return matchesModalDialogPseudoClass(element);
+        case CSSSelector::PseudoClassModal:
+            return matchesModalPseudoClass(element);
 
         case CSSSelector::PseudoClassUnknown:
             ASSERT_NOT_REACHED();

Modified: trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h (293986 => 293987)


--- trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h	2022-05-09 20:04:36 UTC (rev 293986)
+++ trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h	2022-05-09 20:37:15 UTC (rev 293987)
@@ -531,7 +531,7 @@
     return element.hasFocusWithin() && isFrameFocused(element);
 }
 
-ALWAYS_INLINE bool matchesModalDialogPseudoClass(const Element& element)
+ALWAYS_INLINE bool matchesModalPseudoClass(const Element& element)
 {
     if (is<HTMLDialogElement>(element))
         return downcast<HTMLDialogElement>(element).isModal();

Modified: trunk/Source/WebCore/css/SelectorPseudoClassAndCompatibilityElementMap.in (293986 => 293987)


--- trunk/Source/WebCore/css/SelectorPseudoClassAndCompatibilityElementMap.in	2022-05-09 20:04:36 UTC (rev 293986)
+++ trunk/Source/WebCore/css/SelectorPseudoClassAndCompatibilityElementMap.in	2022-05-09 20:37:15 UTC (rev 293987)
@@ -1,4 +1,3 @@
--internal-modal-dialog
 -khtml-drag
 -webkit-any
 -webkit-any-link, PseudoClassAnyLinkDeprecated, PseudoElementUnknown
@@ -50,6 +49,7 @@
 last-of-type
 link
 matches
+modal
 no-button
 not
 nth-child

Modified: trunk/Source/WebCore/css/dialog.css (293986 => 293987)


--- trunk/Source/WebCore/css/dialog.css	2022-05-09 20:04:36 UTC (rev 293986)
+++ trunk/Source/WebCore/css/dialog.css	2022-05-09 20:37:15 UTC (rev 293987)
@@ -16,7 +16,7 @@
     display: block;
 }
 
-dialog:-internal-modal-dialog {
+dialog:modal {
     position: fixed;
     overflow: auto;
     inset-block-start: 0;

Modified: trunk/Source/WebCore/css/parser/CSSSelectorParser.cpp (293986 => 293987)


--- trunk/Source/WebCore/css/parser/CSSSelectorParser.cpp	2022-05-09 20:04:36 UTC (rev 293986)
+++ trunk/Source/WebCore/css/parser/CSSSelectorParser.cpp	2022-05-09 20:37:15 UTC (rev 293987)
@@ -644,8 +644,6 @@
         if (!selector)
             return nullptr;
         if (selector->match() == CSSSelector::PseudoClass) {
-            if (m_context.mode != UASheetMode && selector->pseudoClassType() == CSSSelector::PseudoClassModalDialog)
-                return nullptr;
             if (!m_context.focusVisibleEnabled && selector->pseudoClassType() == CSSSelector::PseudoClassFocusVisible)
                 return nullptr;
             if (!m_context.hasPseudoClassEnabled && selector->pseudoClassType() == CSSSelector::PseudoClassHas)

Modified: trunk/Source/WebCore/cssjit/SelectorCompiler.cpp (293986 => 293987)


--- trunk/Source/WebCore/cssjit/SelectorCompiler.cpp	2022-05-09 20:04:36 UTC (rev 293986)
+++ trunk/Source/WebCore/cssjit/SelectorCompiler.cpp	2022-05-09 20:37:15 UTC (rev 293987)
@@ -125,7 +125,7 @@
 #if ENABLE(ATTACHMENT_ELEMENT)
 static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(operationHasAttachment, bool, (const Element&));
 #endif
-static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(operationMatchesModalDialogPseudoClass, bool, (const Element&));
+static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(operationMatchesModalPseudoClass, bool, (const Element&));
 
 static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(operationAttributeValueBeginsWithCaseSensitive, bool, (const Attribute* attribute, AtomStringImpl* expectedString));
 static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(operationAttributeValueBeginsWithCaseInsensitive, bool, (const Attribute* attribute, AtomStringImpl* expectedString));
@@ -804,9 +804,9 @@
     return matchesLangPseudoClass(element, argumentList);
 }
 
-JSC_DEFINE_JIT_OPERATION(operationMatchesModalDialogPseudoClass, bool, (const Element& element))
+JSC_DEFINE_JIT_OPERATION(operationMatchesModalPseudoClass, bool, (const Element& element))
 {
-    return matchesModalDialogPseudoClass(element);
+    return matchesModalPseudoClass(element);
 }
 
 static inline FunctionType addPseudoClassType(const CSSSelector& selector, SelectorFragment& fragment, SelectorContext selectorContext, FragmentsLevel fragmentLevel, FragmentPositionInRootFragments positionInRootFragments, bool visitedMatchEnabled, VisitedMode& visitedMode, PseudoElementMatchingBehavior pseudoElementMatchingBehavior)
@@ -945,8 +945,8 @@
         return FunctionType::SimpleSelectorChecker;
 #endif
 
-    case CSSSelector::PseudoClassModalDialog:
-        fragment.unoptimizedPseudoClasses.append(JSC::FunctionPtr<JSC::OperationPtrTag>(operationMatchesModalDialogPseudoClass));
+    case CSSSelector::PseudoClassModal:
+        fragment.unoptimizedPseudoClasses.append(JSC::FunctionPtr<JSC::OperationPtrTag>(operationMatchesModalPseudoClass));
         return FunctionType::SimpleSelectorChecker;
 
     // These pseudo-classes only have meaning with scrollbars.

Modified: trunk/Source/WebCore/html/HTMLDialogElement.cpp (293986 => 293987)


--- trunk/Source/WebCore/html/HTMLDialogElement.cpp	2022-05-09 20:04:36 UTC (rev 293986)
+++ trunk/Source/WebCore/html/HTMLDialogElement.cpp	2022-05-09 20:37:15 UTC (rev 293987)
@@ -26,11 +26,13 @@
 #include "config.h"
 #include "HTMLDialogElement.h"
 
+#include "CSSSelector.h"
 #include "DocumentInlines.h"
 #include "EventLoop.h"
 #include "EventNames.h"
 #include "FocusOptions.h"
 #include "HTMLNames.h"
+#include "PseudoClassChangeInvalidation.h"
 #include "RenderElement.h"
 #include "ScopedEventQueue.h"
 #include "TypedElementDescendantIterator.h"
@@ -75,7 +77,7 @@
     EventQueueScope scope;
     setBooleanAttribute(openAttr, true);
 
-    m_isModal = true;
+    setIsModal(true);
 
     if (!isInTopLayer())
         addToTopLayer();
@@ -94,7 +96,7 @@
 
     setBooleanAttribute(openAttr, false);
 
-    m_isModal = false;
+    setIsModal(false);
 
     if (!result.isNull())
         m_returnValue = result;
@@ -158,7 +160,15 @@
 void HTMLDialogElement::removedFromAncestor(RemovalType removalType, ContainerNode& oldParentOfRemovedTree)
 {
     HTMLElement::removedFromAncestor(removalType, oldParentOfRemovedTree);
-    m_isModal = false;
+    setIsModal(false);
 }
 
+void HTMLDialogElement::setIsModal(bool newValue)
+{
+    if (m_isModal == newValue)
+        return;
+    Style::PseudoClassChangeInvalidation styleInvalidation(*this, CSSSelector::PseudoClassModal, newValue);
+    m_isModal = newValue;
 }
+
+}

Modified: trunk/Source/WebCore/html/HTMLDialogElement.h (293986 => 293987)


--- trunk/Source/WebCore/html/HTMLDialogElement.h	2022-05-09 20:04:36 UTC (rev 293986)
+++ trunk/Source/WebCore/html/HTMLDialogElement.h	2022-05-09 20:37:15 UTC (rev 293987)
@@ -53,6 +53,7 @@
     HTMLDialogElement(const QualifiedName&, Document&);
 
     void removedFromAncestor(RemovalType, ContainerNode& oldParentOfRemovedTree) final;
+    void setIsModal(bool newValue);
 
     String m_returnValue;
     bool m_isModal { false };
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to