Add a pseudoclass that matches img elements that are backed by an attachment
authormitz@apple.com <mitz@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 Nov 2018 19:33:54 +0000 (19:33 +0000)
committermitz@apple.com <mitz@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 Nov 2018 19:33:54 +0000 (19:33 +0000)
https://bugs.webkit.org/show_bug.cgi?id=191286
<rdar://problem/45823554>

Reviewed by Dean Jackson.

Source/WebCore:

Test: fast/css/has-attachment.html

Added a :has-attachment pseudoclass, enabled only when the attachment element is enabled at
runtime, that matches elements (currently only img elements qualify) that have an attachment
element in their shadow DOM.

* css/CSSSelector.cpp:
(WebCore::CSSSelector::selectorText const): Handle the new PseudoClassHasAttachment value.
* css/CSSSelector.h: Added a new value to the PseudoClassType enum.

* css/SelectorChecker.cpp:
(WebCore::SelectorChecker::checkOne const): Check the new PseudoClassHasAttachment value
  using the new hasAttachment test function.

* css/SelectorCheckerTestFunctions.h:
(WebCore::hasAttachment): Added. Tests if the element is an img element that has an
  attachment.

* css/SelectorPseudoClassAndCompatibilityElementMap.in: Added has-attachment.

* css/parser/CSSParserContext.cpp:
(WebCore::CSSParserContext::CSSParserContext): Initialize new attachmentEnabled member based
  on RuntimeEnabledFeatures.
(WebCore::operator==): Compare new attachmentEnabled member.
* css/parser/CSSParserContext.h:
(WebCore::CSSParserContextHash::hash): Include new attachmentEnabled member.

* css/parser/CSSSelectorParser.cpp:
(WebCore::CSSSelectorParser::consumePseudo): Reject :has-attachment if the attachment
  element is not enabled.

* cssjit/SelectorCompiler.cpp:
(WebCore::SelectorCompiler::addPseudoClassType): Handle PseudoClassHasAttachment.

LayoutTests:

* fast/css/has-attachment-expected.txt: Added.
* fast/css/has-attachment.html: Added.
* platform/win/TestExpectations:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@237932 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/css/has-attachment-expected.txt [new file with mode: 0644]
LayoutTests/fast/css/has-attachment.html [new file with mode: 0644]
LayoutTests/platform/win/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/css/CSSSelector.cpp
Source/WebCore/css/CSSSelector.h
Source/WebCore/css/SelectorChecker.cpp
Source/WebCore/css/SelectorCheckerTestFunctions.h
Source/WebCore/css/SelectorPseudoClassAndCompatibilityElementMap.in
Source/WebCore/css/parser/CSSParserContext.cpp
Source/WebCore/css/parser/CSSParserContext.h
Source/WebCore/css/parser/CSSSelectorParser.cpp
Source/WebCore/cssjit/SelectorCompiler.cpp

index 18dcd51..4fb4c72 100644 (file)
@@ -1,3 +1,15 @@
+2018-11-07  Dan Bernstein  <mitz@apple.com>
+
+        Add a pseudoclass that matches img elements that are backed by an attachment
+        https://bugs.webkit.org/show_bug.cgi?id=191286
+        <rdar://problem/45823554>
+
+        Reviewed by Dean Jackson.
+
+        * fast/css/has-attachment-expected.txt: Added.
+        * fast/css/has-attachment.html: Added.
+        * platform/win/TestExpectations:
+
 2018-11-07  Ali Juma  <ajuma@chromium.org>
 
         IntersectionObserverEntry doesn't keep JS wrappers of rects alive
diff --git a/LayoutTests/fast/css/has-attachment-expected.txt b/LayoutTests/fast/css/has-attachment-expected.txt
new file mode 100644 (file)
index 0000000..26c57b2
--- /dev/null
@@ -0,0 +1,11 @@
+This tests the :has-attachment pseudoclass.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS getComputedStyle(target).clear is "both"
+PASS getComputedStyle(target).clear is "none"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/css/has-attachment.html b/LayoutTests/fast/css/has-attachment.html
new file mode 100644 (file)
index 0000000..cdd2148
--- /dev/null
@@ -0,0 +1,19 @@
+<!DOCTYPE html><!-- webkit-test-runner [ enableAttachmentElement=true ] -->
+<head>
+    <script src="../../resources/js-test-pre.js"></script>
+    <style>
+        img { clear: both; }
+        img:has-attachment { clear: none; }
+    </style>
+</head>
+<body>
+    <img id=target>
+    <script>
+        description("This tests the :has-attachment pseudoclass.");
+        var target = document.getElementById("target");
+        shouldBeEqualToString("getComputedStyle(target).clear", "both");
+        HTMLAttachmentElement.getAttachmentIdentifier(target);
+        shouldBeEqualToString("getComputedStyle(target).clear", "none");
+    </script>
+    <script src="../../resources/js-test-post.js"></script>
+</body>
index 72d1e1f..80a42f9 100644 (file)
@@ -625,6 +625,7 @@ webkit.org/b/35013 svg/zoom/text/ [ Skip ]
 
 # TODO Attachment elements do not provide a custom renderer
 webkit.org/b/142260 fast/attachment [ Skip ]
+webkit.org/b/142260 fast/css/has-attachment.html [ Skip ]
 
 # TODO APNG is not supported
 webkit.org/b/142731 fast/images/animated-png.html [ Skip ]
index 77d5f42..bb2e019 100644 (file)
@@ -1,3 +1,45 @@
+2018-11-07  Dan Bernstein  <mitz@apple.com>
+
+        Add a pseudoclass that matches img elements that are backed by an attachment
+        https://bugs.webkit.org/show_bug.cgi?id=191286
+        <rdar://problem/45823554>
+
+        Reviewed by Dean Jackson.
+
+        Test: fast/css/has-attachment.html
+
+        Added a :has-attachment pseudoclass, enabled only when the attachment element is enabled at
+        runtime, that matches elements (currently only img elements qualify) that have an attachment
+        element in their shadow DOM.
+
+        * css/CSSSelector.cpp:
+        (WebCore::CSSSelector::selectorText const): Handle the new PseudoClassHasAttachment value.
+        * css/CSSSelector.h: Added a new value to the PseudoClassType enum.
+
+        * css/SelectorChecker.cpp:
+        (WebCore::SelectorChecker::checkOne const): Check the new PseudoClassHasAttachment value
+          using the new hasAttachment test function.
+
+        * css/SelectorCheckerTestFunctions.h:
+        (WebCore::hasAttachment): Added. Tests if the element is an img element that has an
+          attachment.
+
+        * css/SelectorPseudoClassAndCompatibilityElementMap.in: Added has-attachment.
+
+        * css/parser/CSSParserContext.cpp:
+        (WebCore::CSSParserContext::CSSParserContext): Initialize new attachmentEnabled member based
+          on RuntimeEnabledFeatures.
+        (WebCore::operator==): Compare new attachmentEnabled member.
+        * css/parser/CSSParserContext.h:
+        (WebCore::CSSParserContextHash::hash): Include new attachmentEnabled member.
+
+        * css/parser/CSSSelectorParser.cpp:
+        (WebCore::CSSSelectorParser::consumePseudo): Reject :has-attachment if the attachment
+          element is not enabled.
+
+        * cssjit/SelectorCompiler.cpp:
+        (WebCore::SelectorCompiler::addPseudoClassType): Handle PseudoClassHasAttachment.
+
 2018-11-07  Don Olmstead  <don.olmstead@sony.com>
 
         Make generic MainThreadSharedTimer implementation
index b347735..f365a85 100644 (file)
@@ -505,6 +505,11 @@ String CSSSelector::selectorText(const String& rightSide) const
                 str.appendLiteral(":future");
                 break;
 #endif
+#if ENABLE(ATTACHMENT_ELEMENT)
+            case CSSSelector::PseudoClassHasAttachment:
+                str.appendLiteral(":has-attachment");
+                break;
+#endif
             case CSSSelector::PseudoClassHorizontal:
                 str.appendLiteral(":horizontal");
                 break;
index 0ec5870..544cc2c 100644 (file)
@@ -162,6 +162,9 @@ namespace WebCore {
 #endif
             PseudoClassHost,
             PseudoClassDefined,
+#if ENABLE(ATTACHMENT_ELEMENT)
+            PseudoClassHasAttachment,
+#endif
         };
 
         enum PseudoElementType {
index ebb1510..70c83b8 100644 (file)
@@ -1111,6 +1111,11 @@ bool SelectorChecker::checkOne(CheckingContext& checkingContext, const LocalCont
             return false;
 #endif
 
+#if ENABLE(ATTACHMENT_ELEMENT)
+        case CSSSelector::PseudoClassHasAttachment:
+            return hasAttachment(element);
+#endif
+
         case CSSSelector::PseudoClassUnknown:
             ASSERT_NOT_REACHED();
             break;
index b7b2e3b..b8c7e61 100644 (file)
 #include "ScrollbarTheme.h"
 #include <wtf/Compiler.h>
 
+#if ENABLE(ATTACHMENT_ELEMENT)
+#include "HTMLAttachmentElement.h"
+#endif
+
 #if ENABLE(VIDEO_TRACK)
 #include "WebVTTElement.h"
 #endif
@@ -130,6 +134,13 @@ ALWAYS_INLINE bool isWindowInactive(const Element& element)
     return !page->focusController().isActive();
 }
 
+#if ENABLE(ATTACHMENT_ELEMENT)
+ALWAYS_INLINE bool hasAttachment(const Element& element)
+{
+    return is<HTMLImageElement>(element) && downcast<HTMLImageElement>(element).attachmentElement();
+}
+#endif
+
 ALWAYS_INLINE bool containslanguageSubtagMatchingRange(StringView language, StringView range, unsigned languageLength, unsigned& position)
 {
     unsigned languageSubtagsStartIndex = position;
index 63bd94a..6d6f3f1 100644 (file)
@@ -28,6 +28,9 @@ first-line, PseudoClassUnknown, PseudoElementFirstLine
 first-of-type
 focus
 focus-within
+#if ENABLE(ATTACHMENT_ELEMENT)
+has-attachment
+#endif
 horizontal
 host, PseudoClassHost, PseudoElementUnknown
 hover
index a088c34..06c702a 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "Document.h"
 #include "Page.h"
+#include "RuntimeEnabledFeatures.h"
 #include "Settings.h"
 #include <wtf/NeverDestroyed.h>
 
@@ -68,6 +69,9 @@ CSSParserContext::CSSParserContext(const Document& document, const URL& sheetBas
     springTimingFunctionEnabled = document.settings().springTimingFunctionEnabled();
     constantPropertiesEnabled = document.settings().constantPropertiesEnabled();
     colorFilterEnabled = document.settings().colorFilterEnabled();
+#if ENABLE(ATTACHMENT_ELEMENT)
+    attachmentEnabled = RuntimeEnabledFeatures::sharedFeatures().attachmentElementEnabled();
+#endif
     deferredCSSParserEnabled = document.settings().deferredCSSParserEnabled();
     useSystemAppearance = document.page() ? document.page()->useSystemAppearance() : false;
 
@@ -94,6 +98,9 @@ bool operator==(const CSSParserContext& a, const CSSParserContext& b)
         && a.springTimingFunctionEnabled == b.springTimingFunctionEnabled
         && a.constantPropertiesEnabled == b.constantPropertiesEnabled
         && a.colorFilterEnabled == b.colorFilterEnabled
+#if ENABLE(ATTACHMENT_ELEMENT)
+        && a.attachmentEnabled == b.attachmentEnabled
+#endif
         && a.deferredCSSParserEnabled == b.deferredCSSParserEnabled
         && a.hasDocumentSecurityOrigin == b.hasDocumentSecurityOrigin
         && a.useSystemAppearance == b.useSystemAppearance;
index 0878344..ececef6 100644 (file)
@@ -55,6 +55,9 @@ public:
     bool springTimingFunctionEnabled { false };
     bool constantPropertiesEnabled { false };
     bool colorFilterEnabled { false };
+#if ENABLE(ATTACHMENT_ELEMENT)
+    bool attachmentEnabled { false };
+#endif
     bool deferredCSSParserEnabled { false };
     
     // This is only needed to support getMatchedCSSRules.
@@ -98,7 +101,10 @@ struct CSSParserContextHash {
             & key.deferredCSSParserEnabled                  << 8
             & key.hasDocumentSecurityOrigin                 << 9
             & key.useSystemAppearance                       << 10
-            & key.mode                                      << 11; // Keep this last.
+#if ENABLE(ATTACHMENT_ELEMENT)
+            & key.attachmentEnabled                         << 11
+#endif
+            & key.mode                                      << 12; // Keep this last.
         hash ^= WTF::intHash(bits);
         return hash;
     }
index 3ec22fc..1e7d026 100644 (file)
@@ -493,9 +493,13 @@ std::unique_ptr<CSSParserSelector> CSSSelectorParser::consumePseudo(CSSParserTok
     auto lowercasedValue = token.value().convertToASCIILowercase();
     auto value = StringView { lowercasedValue };
 
-    if (colons == 1)
+    if (colons == 1) {
         selector = std::unique_ptr<CSSParserSelector>(CSSParserSelector::parsePseudoClassSelectorFromStringView(value));
-    else {
+#if ENABLE(ATTACHMENT_ELEMENT)
+        if (!m_context.attachmentEnabled && selector && selector->match() == CSSSelector::PseudoClass && selector->pseudoClassType() == CSSSelector::PseudoClassHasAttachment)
+            return nullptr;
+#endif
+    } else {
         selector = std::unique_ptr<CSSParserSelector>(CSSParserSelector::parsePseudoElementSelectorFromStringView(value));
 #if ENABLE(VIDEO_TRACK)
         // Treat the ident version of cue as PseudoElementWebkitCustom.
index 803d825..efbcc0d 100644 (file)
@@ -619,6 +619,12 @@ static inline FunctionType addPseudoClassType(const CSSSelector& selector, Selec
         return FunctionType::SimpleSelectorChecker;
 #endif
 
+#if ENABLE(ATTACHMENT_ELEMENT)
+    case CSSSelector::PseudoClassHasAttachment:
+        fragment.unoptimizedPseudoClasses.append(JSC::FunctionPtr<CSSOperationPtrTag>(hasAttachment));
+        return FunctionType::SimpleSelectorChecker;
+#endif
+
     // These pseudo-classes only have meaning with scrollbars.
     case CSSSelector::PseudoClassHorizontal:
     case CSSSelector::PseudoClassVertical: