Add a new "color-filter" CSS property as an experimental feature
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 25 Apr 2018 01:50:39 +0000 (01:50 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 25 Apr 2018 01:50:39 +0000 (01:50 +0000)
https://bugs.webkit.org/show_bug.cgi?id=184940
Source/WebCore:

rdar://problem/39664904

Reviewed by Jon Lee.

Add a new CSS property called "color-filter" as an experimental feature (off by default).

This property specifies a list of filter functions (as specified in https://drafts.fxtf.org/filter-effects/#supported-filter-functions)
to CSS colors, allowing authors to modify the provided page colors, for example to improve accessibility.
Filters that move pixels (i.e. blur() and drop-shadow()) are invalid in this property.

Colors will be mapped through the filter functions just before paint time, and gradient stop colors will also be mapped.

This patch adds support for parsing color-filter.

Test: css3/color-filters/color-filter-parsing.html

* css/CSSComputedStyleDeclaration.cpp:
(WebCore::ComputedStyleExtractor::valueForPropertyinStyle):
* css/CSSProperties.json:
* css/parser/CSSParser.cpp:
(WebCore::CSSParserContext::CSSParserContext):
(WebCore::operator==):
* css/parser/CSSParserMode.h:
* css/parser/CSSPropertyParser.cpp:
(WebCore::CSSPropertyParser::parseSingleValue):
* css/parser/CSSPropertyParserHelpers.cpp:
(WebCore::CSSPropertyParserHelpers::isColorFilterFunction):
(WebCore::CSSPropertyParserHelpers::consumeFilterFunction):
(WebCore::CSSPropertyParserHelpers::consumeFilter):
* css/parser/CSSPropertyParserHelpers.h:
* page/Settings.yaml:
* rendering/style/RenderStyle.cpp:
(WebCore::RenderStyle::changeRequiresRepaint const):
* rendering/style/RenderStyle.h:
(WebCore::RenderStyle::mutableColorFilter):
(WebCore::RenderStyle::colorFilter const):
(WebCore::RenderStyle::hasColorFilter const):
(WebCore::RenderStyle::setColorFilter):
(WebCore::RenderStyle::initialColorFilter):
* rendering/style/StyleRareInheritedData.cpp:
(WebCore::StyleRareInheritedData::StyleRareInheritedData):
(WebCore::StyleRareInheritedData::operator== const):
(WebCore::StyleRareInheritedData::hasColorFilters const):
* rendering/style/StyleRareInheritedData.h:

Source/WebKit:

Reviewed by Jon Lee.

Add the color-filter property as an experimental feature.

* Shared/WebPreferences.yaml:

LayoutTests:

Reviewed by Jon Lee.

* css3/color-filters/color-filter-parsing-expected.txt: Added.
* css3/color-filters/color-filter-parsing.html: Added.

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

18 files changed:
LayoutTests/ChangeLog
LayoutTests/css3/color-filters/color-filter-parsing-expected.txt [new file with mode: 0644]
LayoutTests/css3/color-filters/color-filter-parsing.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/css/CSSComputedStyleDeclaration.cpp
Source/WebCore/css/CSSProperties.json
Source/WebCore/css/parser/CSSParser.cpp
Source/WebCore/css/parser/CSSParserMode.h
Source/WebCore/css/parser/CSSPropertyParser.cpp
Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp
Source/WebCore/css/parser/CSSPropertyParserHelpers.h
Source/WebCore/page/Settings.yaml
Source/WebCore/rendering/style/RenderStyle.cpp
Source/WebCore/rendering/style/RenderStyle.h
Source/WebCore/rendering/style/StyleRareInheritedData.cpp
Source/WebCore/rendering/style/StyleRareInheritedData.h
Source/WebKit/ChangeLog
Source/WebKit/Shared/WebPreferences.yaml

index 33fcebe..4625d25 100644 (file)
@@ -1,5 +1,15 @@
 2018-04-24  Simon Fraser  <simon.fraser@apple.com>
 
+        Add a new "color-filter" CSS property as an experimental feature
+        https://bugs.webkit.org/show_bug.cgi?id=184940
+
+        Reviewed by Jon Lee.
+
+        * css3/color-filters/color-filter-parsing-expected.txt: Added.
+        * css3/color-filters/color-filter-parsing.html: Added.
+
+2018-04-24  Simon Fraser  <simon.fraser@apple.com>
+
         shape-outside and filter styles occur twice in the result of getComputedStyle
         https://bugs.webkit.org/show_bug.cgi?id=184931
 
diff --git a/LayoutTests/css3/color-filters/color-filter-parsing-expected.txt b/LayoutTests/css3/color-filters/color-filter-parsing-expected.txt
new file mode 100644 (file)
index 0000000..28f6810
--- /dev/null
@@ -0,0 +1,36 @@
+
+PASS Parse none 
+PASS Parse auto 
+PASS Parsing garbage value returns none 
+PASS Parsing garbage function returns none 
+FAIL Parse brightness() assert_equals: expected "brightness(1)" but got "brightness(0)"
+PASS Parse contrast() 
+PASS Parse grayscale() 
+PASS Parse hue-rotate() 
+PASS Parse invert 
+PASS Parse opacity() 
+PASS Parse saturate() 
+PASS Parse sepia() 
+PASS drop-shadow() is not allowed in color-filter 
+PASS blur() is not allowed in color-filter 
+PASS Canonicalize grayscale() argument 
+PASS Canonicalize hue-rotate() argument 
+FAIL Negative value for brightness() is invalid assert_equals: expected "none" but got "brightness(-0.4)"
+PASS Negative value for contrast() is invalid 
+PASS Negative value for grayscale() is invalid 
+PASS Negative value allowed for hue-rotate() 
+PASS Negative value for invert() is invalid 
+PASS Negative value for opacity() is invalid 
+PASS Negative value for saturate() is invalid 
+PASS Negative value for sepia() is invalid 
+PASS brightness(): values of amount over 100% are allowed, providing brighter results 
+PASS contrast(): values of amount over 100% are allowed, providing results with more contrast 
+PASS Values of amount over 100% are allowed but UAs must clamp the values to 1 
+PASS hue-rotate(): implementations must not normalize this value in order to allow animations beyond 360deg 
+PASS invert(): values of amount over 100% are allowed but UAs must clamp the values to 1 
+PASS opacity(): values of amount over 100% are allowed but UAs must clamp the values to 1 
+PASS saturate(): values of amount over 100% are allowed, providing super-saturated results 
+PASS sepia(): values of amount over 100% are allowed but UAs must clamp the values to 1 
+PASS Parse filter list 
+PASS Filter list with blur is invalid 
+
diff --git a/LayoutTests/css3/color-filters/color-filter-parsing.html b/LayoutTests/css3/color-filters/color-filter-parsing.html
new file mode 100644 (file)
index 0000000..2672a11
--- /dev/null
@@ -0,0 +1,69 @@
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<div id="test"></div>
+
+<script>
+
+if (window.internals)
+    internals.settings.setColorFilterEnabled(true);
+
+var testDiv = document.querySelector('#test');
+
+function testColorFilterParsing(value, expected, name)
+{
+    test(() => {
+               testDiv.style.colorFilter = '';
+               testDiv.style.colorFilter = value;
+               var computedStyle = getComputedStyle(testDiv).colorFilter;
+        assert_equals(computedStyle, expected);
+    }, name);
+}
+
+testColorFilterParsing("none", "none", "Parse none");
+testColorFilterParsing("auto", "none", "Parse auto");
+testColorFilterParsing("garbage", "none", "Parsing garbage value returns none");
+testColorFilterParsing("garbage()", "none", "Parsing garbage function returns none");
+
+// Argument-free funtions.
+testColorFilterParsing("brightness()", "brightness(1)", "Parse brightness()"); // webkit.org/b/184937
+testColorFilterParsing("contrast()", "contrast(1)", "Parse contrast()");
+testColorFilterParsing("grayscale()", "grayscale(1)", "Parse grayscale()");
+testColorFilterParsing("hue-rotate()", "hue-rotate(0deg)", "Parse hue-rotate()");
+testColorFilterParsing("invert()", "invert(1)", "Parse invert");
+testColorFilterParsing("opacity()", "opacity(1)", "Parse opacity()");
+testColorFilterParsing("saturate()", "saturate(1)", "Parse saturate()");
+testColorFilterParsing("sepia()", "sepia(1)", "Parse sepia()");
+
+// Functions not allowed.
+testColorFilterParsing("drop-shadow(110px 110px 0 blue)", "none", "drop-shadow() is not allowed in color-filter");
+testColorFilterParsing("blur(10px)", "none", "blur() is not allowed in color-filter");
+
+// Argument canonicalization.
+testColorFilterParsing("grayscale(30%)", "grayscale(0.3)", "Canonicalize grayscale() argument");
+testColorFilterParsing("hue-rotate(1.2rad)", "hue-rotate(68.75493541569878deg)", "Canonicalize hue-rotate() argument");
+
+// Negative values.
+testColorFilterParsing("brightness(-0.4)", "none", "Negative value for brightness() is invalid"); // webkit.org/b/184937
+testColorFilterParsing("contrast(-0.6)", "none", "Negative value for contrast() is invalid");
+testColorFilterParsing("grayscale(-0.)", "none", "Negative value for grayscale() is invalid");
+testColorFilterParsing("hue-rotate(-20deg)", "hue-rotate(-20deg)", "Negative value allowed for hue-rotate()");
+testColorFilterParsing("invert(-0.6)", "none", "Negative value for invert() is invalid");
+testColorFilterParsing("opacity(-0.5)", "none", "Negative value for opacity() is invalid");
+testColorFilterParsing("saturate(-0.2)", "none", "Negative value for saturate() is invalid");
+testColorFilterParsing("sepia(-0.5)", "none", "Negative value for sepia() is invalid");
+
+// Values > 1 or 100%
+testColorFilterParsing("brightness(2.4)", "brightness(2.4)", "brightness(): values of amount over 100% are allowed, providing brighter results");
+testColorFilterParsing("contrast(3.6)", "contrast(3.6)", "contrast(): values of amount over 100% are allowed, providing results with more contrast");
+testColorFilterParsing("grayscale(120%)", "grayscale(1)", "Values of amount over 100% are allowed but UAs must clamp the values to 1");
+testColorFilterParsing("hue-rotate(740deg)", "hue-rotate(740deg)", "hue-rotate(): implementations must not normalize this value in order to allow animations beyond 360deg");
+testColorFilterParsing("invert(2.3)", "invert(1)", "invert(): values of amount over 100% are allowed but UAs must clamp the values to 1");
+testColorFilterParsing("opacity(12.5)", "opacity(1)", "opacity(): values of amount over 100% are allowed but UAs must clamp the values to 1");
+testColorFilterParsing("saturate(200%)", "saturate(2)", "saturate(): values of amount over 100% are allowed, providing super-saturated results");
+testColorFilterParsing("sepia(5.3)", "sepia(1)", "sepia(): values of amount over 100% are allowed but UAs must clamp the values to 1");
+
+// Function lists.
+testColorFilterParsing("grayscale(50%) hue-rotate(45deg) opacity(0.5)", "grayscale(0.5) hue-rotate(45deg) opacity(0.5)", "Parse filter list");
+testColorFilterParsing("grayscale(50%) blur(10px) opacity(0.5)", "none", "Filter list with blur is invalid");
+
+</script>
index 8d75737..c9dd677 100644 (file)
@@ -1,5 +1,54 @@
 2018-04-24  Simon Fraser  <simon.fraser@apple.com>
 
+        Add a new "color-filter" CSS property as an experimental feature
+        https://bugs.webkit.org/show_bug.cgi?id=184940
+        rdar://problem/39664904
+
+        Reviewed by Jon Lee.
+        
+        Add a new CSS property called "color-filter" as an experimental feature (off by default).
+        
+        This property specifies a list of filter functions (as specified in https://drafts.fxtf.org/filter-effects/#supported-filter-functions)
+        to CSS colors, allowing authors to modify the provided page colors, for example to improve accessibility.
+        Filters that move pixels (i.e. blur() and drop-shadow()) are invalid in this property.
+        
+        Colors will be mapped through the filter functions just before paint time, and gradient stop colors will also be mapped.
+        
+        This patch adds support for parsing color-filter.
+
+        Test: css3/color-filters/color-filter-parsing.html
+
+        * css/CSSComputedStyleDeclaration.cpp:
+        (WebCore::ComputedStyleExtractor::valueForPropertyinStyle):
+        * css/CSSProperties.json:
+        * css/parser/CSSParser.cpp:
+        (WebCore::CSSParserContext::CSSParserContext):
+        (WebCore::operator==):
+        * css/parser/CSSParserMode.h:
+        * css/parser/CSSPropertyParser.cpp:
+        (WebCore::CSSPropertyParser::parseSingleValue):
+        * css/parser/CSSPropertyParserHelpers.cpp:
+        (WebCore::CSSPropertyParserHelpers::isColorFilterFunction):
+        (WebCore::CSSPropertyParserHelpers::consumeFilterFunction):
+        (WebCore::CSSPropertyParserHelpers::consumeFilter):
+        * css/parser/CSSPropertyParserHelpers.h:
+        * page/Settings.yaml:
+        * rendering/style/RenderStyle.cpp:
+        (WebCore::RenderStyle::changeRequiresRepaint const):
+        * rendering/style/RenderStyle.h:
+        (WebCore::RenderStyle::mutableColorFilter):
+        (WebCore::RenderStyle::colorFilter const):
+        (WebCore::RenderStyle::hasColorFilter const):
+        (WebCore::RenderStyle::setColorFilter):
+        (WebCore::RenderStyle::initialColorFilter):
+        * rendering/style/StyleRareInheritedData.cpp:
+        (WebCore::StyleRareInheritedData::StyleRareInheritedData):
+        (WebCore::StyleRareInheritedData::operator== const):
+        (WebCore::StyleRareInheritedData::hasColorFilters const):
+        * rendering/style/StyleRareInheritedData.h:
+
+2018-04-24  Simon Fraser  <simon.fraser@apple.com>
+
         shape-outside and filter styles occur twice in the result of getComputedStyle
         https://bugs.webkit.org/show_bug.cgi?id=184931
 
index bc4f53a..eeae426 100644 (file)
@@ -143,6 +143,7 @@ static const CSSPropertyID computedProperties[] = {
     CSSPropertyClear,
     CSSPropertyClip,
     CSSPropertyColor,
+    CSSPropertyColorFilter,
     CSSPropertyCounterIncrement,
     CSSPropertyCounterReset,
     CSSPropertyContent,
@@ -3844,6 +3845,8 @@ RefPtr<CSSValue> ComputedStyleExtractor::valueForPropertyinStyle(const RenderSty
             return shapePropertyValue(style, style.shapeOutside());
         case CSSPropertyFilter:
             return valueForFilter(style, style.filter());
+        case CSSPropertyColorFilter:
+            return valueForFilter(style, style.colorFilter());
 #if ENABLE(FILTERS_LEVEL_2)
         case CSSPropertyWebkitBackdropFilter:
             return valueForFilter(style, style.backdropFilter());
index a3b70f4..ccd67d4 100644 (file)
                 "url": "https://www.w3.org/TR/filter-effects/#FilterProperty"
             }
         },
+        "color-filter": {
+            "inherited": true,
+            "codegen-properties": {
+                "conditional-converter": "FilterOperations"
+            },
+            "status": {
+                "status": "experimental"
+            }
+        },
         "align-content": {
             "values": [
                 "flex-start",
index a87c671..954ab08 100644 (file)
@@ -89,6 +89,7 @@ CSSParserContext::CSSParserContext(Document& document, const URL& sheetBaseURL,
     springTimingFunctionEnabled = document.settings().springTimingFunctionEnabled();
     constantPropertiesEnabled = document.settings().constantPropertiesEnabled();
     conicGradientsEnabled = document.settings().conicGradientsEnabled();
+    colorFilterEnabled = document.settings().colorFilterEnabled();
     deferredCSSParserEnabled = document.settings().deferredCSSParserEnabled();
     allowNewLinesClamp = document.settings().appleMailLinesClampEnabled();
     useSystemAppearance = document.page() ? document.page()->useSystemAppearance() : false;
@@ -113,6 +114,7 @@ bool operator==(const CSSParserContext& a, const CSSParserContext& b)
         && a.springTimingFunctionEnabled == b.springTimingFunctionEnabled
         && a.constantPropertiesEnabled == b.constantPropertiesEnabled
         && a.conicGradientsEnabled == b.conicGradientsEnabled
+        && a.colorFilterEnabled == b.colorFilterEnabled
         && a.deferredCSSParserEnabled == b.deferredCSSParserEnabled
         && a.hasDocumentSecurityOrigin == b.hasDocumentSecurityOrigin
         && a.useSystemAppearance == b.useSystemAppearance;
index 1c8836b..99c1e3a 100644 (file)
@@ -105,6 +105,7 @@ public:
     bool springTimingFunctionEnabled { false };
     bool constantPropertiesEnabled { false };
     bool conicGradientsEnabled { false };
+    bool colorFilterEnabled { false };
     bool deferredCSSParserEnabled { false };
     bool allowNewLinesClamp { false };
     
index bd19610..bcece70 100644 (file)
@@ -4133,7 +4133,11 @@ RefPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSPropertyID property, CSS
 #if ENABLE(FILTERS_LEVEL_2)
     case CSSPropertyWebkitBackdropFilter:
 #endif
-        return consumeFilter(m_range, m_context);
+        return consumeFilter(m_range, m_context, AllowedFilterFunctions::All);
+    case CSSPropertyColorFilter:
+        if (!m_context.colorFilterEnabled)
+            return nullptr;
+        return consumeFilter(m_range, m_context, AllowedFilterFunctions::Color);
     case CSSPropertyTextDecoration:
     case CSSPropertyWebkitTextDecorationsInEffect:
     case CSSPropertyWebkitTextDecorationLine:
index c5d95ae..217172b 100644 (file)
@@ -1404,11 +1404,32 @@ static bool isValidPrimitiveFilterFunction(CSSValueID filterFunction)
     }
 }
 
-RefPtr<CSSFunctionValue> consumeFilterFunction(CSSParserTokenRange& range, const CSSParserContext& context)
+static bool isColorFilterFunction(CSSValueID filterFunction)
+{
+    switch (filterFunction) {
+    case CSSValueBrightness:
+    case CSSValueContrast:
+    case CSSValueGrayscale:
+    case CSSValueHueRotate:
+    case CSSValueInvert:
+    case CSSValueOpacity:
+    case CSSValueSaturate:
+    case CSSValueSepia:
+        return true;
+    default:
+        return false;
+    }
+}
+
+static RefPtr<CSSFunctionValue> consumeFilterFunction(CSSParserTokenRange& range, const CSSParserContext& context, AllowedFilterFunctions allowedFunctions)
 {
     CSSValueID filterType = range.peek().functionId();
     if (!isValidPrimitiveFilterFunction(filterType))
         return nullptr;
+
+    if (allowedFunctions == AllowedFilterFunctions::Color && !isColorFilterFunction(filterType))
+        return nullptr;
+
     CSSParserTokenRange args = consumeFunction(range);
     RefPtr<CSSFunctionValue> filterValue = CSSFunctionValue::create(filterType);
     RefPtr<CSSValue> parsedValue;
@@ -1444,16 +1465,17 @@ RefPtr<CSSFunctionValue> consumeFilterFunction(CSSParserTokenRange& range, const
     return filterValue;
 }
 
-RefPtr<CSSValue> consumeFilter(CSSParserTokenRange& range, const CSSParserContext& context)
+RefPtr<CSSValue> consumeFilter(CSSParserTokenRange& range, const CSSParserContext& context, AllowedFilterFunctions allowedFunctions)
 {
     if (range.peek().id() == CSSValueNone)
         return consumeIdent(range);
 
+    bool referenceFiltersAllowed = allowedFunctions == AllowedFilterFunctions::All;
     auto list = CSSValueList::createSpaceSeparated();
     do {
-        RefPtr<CSSValue> filterValue = consumeUrl(range);
+        RefPtr<CSSValue> filterValue = referenceFiltersAllowed ? consumeUrl(range) : nullptr;
         if (!filterValue) {
-            filterValue = consumeFilterFunction(range, context);
+            filterValue = consumeFilterFunction(range, context, allowedFunctions);
             if (!filterValue)
                 return nullptr;
         }
index fbc393f..ce35266 100644 (file)
@@ -93,8 +93,12 @@ enum class ConsumeGeneratedImage {
 RefPtr<CSSValue> consumeImage(CSSParserTokenRange&, CSSParserContext, ConsumeGeneratedImage = ConsumeGeneratedImage::Allow);
 RefPtr<CSSValue> consumeImageOrNone(CSSParserTokenRange&, CSSParserContext);
 
-RefPtr<CSSValue> consumeFilter(CSSParserTokenRange&, const CSSParserContext&);
-RefPtr<CSSFunctionValue> consumeFilterFunction(CSSParserTokenRange&, const CSSParserContext&);
+enum class AllowedFilterFunctions {
+    All,
+    Color
+};
+
+RefPtr<CSSValue> consumeFilter(CSSParserTokenRange&, const CSSParserContext&, AllowedFilterFunctions = AllowedFilterFunctions::All);
 RefPtr<CSSShadowValue> consumeSingleShadow(CSSParserTokenRange&, CSSParserMode, bool allowInset, bool allowSpread);
 
 // Template implementations are at the bottom of the file for readability.
index a06f689..e2e4c7c 100644 (file)
@@ -520,9 +520,13 @@ shouldConvertInvalidURLsToBlank:
 
 springTimingFunctionEnabled:
   initial: false
+
 conicGradientsEnabled:
   initial: false
 
+colorFilterEnabled:
+  initial: false
+
 treatIPAddressAsDomain:
   initial: false
 
index ca1a841..1ff3bdc 100644 (file)
@@ -905,6 +905,7 @@ bool RenderStyle::changeRequiresRepaint(const RenderStyle& other, unsigned& chan
         || !m_backgroundData->isEquivalentForPainting(*other.m_backgroundData)
         || m_rareInheritedData->userModify != other.m_rareInheritedData->userModify
         || m_rareInheritedData->userSelect != other.m_rareInheritedData->userSelect
+        || m_rareInheritedData->colorFilter != other.m_rareInheritedData->colorFilter
         || m_rareNonInheritedData->userDrag != other.m_rareNonInheritedData->userDrag
         || m_rareNonInheritedData->borderFit != other.m_rareNonInheritedData->borderFit
         || m_rareNonInheritedData->objectFit != other.m_rareNonInheritedData->objectFit
index fb4354f..25d5a95 100644 (file)
@@ -753,6 +753,10 @@ public:
     bool hasFilter() const { return !m_rareNonInheritedData->filter->operations.operations().isEmpty(); }
     bool hasReferenceFilterOnly() const;
 
+    FilterOperations& mutableColorFilter() { return m_rareInheritedData.access().colorFilter.access().operations; }
+    const FilterOperations& colorFilter() const { return m_rareInheritedData->colorFilter->operations; }
+    bool hasColorFilter() const { return !m_rareInheritedData->colorFilter->operations.operations().isEmpty(); }
+
 #if ENABLE(FILTERS_LEVEL_2)
     FilterOperations& mutableBackdropFilter() { return m_rareNonInheritedData.access().backdropFilter.access().operations; }
     const FilterOperations& backdropFilter() const { return m_rareNonInheritedData->backdropFilter->operations; }
@@ -1157,6 +1161,7 @@ public:
     void setRubyPosition(RubyPosition position) { SET_VAR(m_rareInheritedData, rubyPosition, position); }
 
     void setFilter(const FilterOperations& ops) { SET_NESTED_VAR(m_rareNonInheritedData, filter, operations, ops); }
+    void setColorFilter(const FilterOperations& ops) { SET_NESTED_VAR(m_rareInheritedData, colorFilter, operations, ops); }
 
 #if ENABLE(FILTERS_LEVEL_2)
     void setBackdropFilter(const FilterOperations& ops) { SET_NESTED_VAR(m_rareNonInheritedData, backdropFilter, operations, ops); }
@@ -1658,6 +1663,7 @@ public:
 #endif
 
     static const FilterOperations& initialFilter() { static NeverDestroyed<FilterOperations> ops; return ops; }
+    static const FilterOperations& initialColorFilter() { static NeverDestroyed<FilterOperations> ops; return ops; }
 
 #if ENABLE(FILTERS_LEVEL_2)
     static const FilterOperations& initialBackdropFilter() { static NeverDestroyed<FilterOperations> ops; return ops; }
index a0f19d6..6a80f15 100644 (file)
@@ -29,6 +29,7 @@
 #include "RenderStyleConstants.h"
 #include "ShadowData.h"
 #include "StyleCustomPropertyData.h"
+#include "StyleFilterData.h"
 #include "StyleImage.h"
 #include <wtf/PointerComparison.h>
 
@@ -41,7 +42,7 @@ struct GreaterThanOrSameSizeAsStyleRareInheritedData : public RefCounted<Greater
     Color colors[9];
     void* ownPtrs[1];
     AtomicString atomicStrings[5];
-    void* refPtrs[2];
+    void* refPtrs[3];
     Length lengths[2];
     float secondFloat;
     unsigned bitfields[4];
@@ -50,7 +51,7 @@ struct GreaterThanOrSameSizeAsStyleRareInheritedData : public RefCounted<Greater
     short hyphenationShorts[3];
 
 #if PLATFORM(IOS)
-    Color compositionColor;
+    Color compositionColor; // FIXME: this has gone.
 #endif
 #if ENABLE(TEXT_AUTOSIZING)
     TextSizeAdjustment textSizeAdjust;
@@ -136,6 +137,7 @@ StyleRareInheritedData::StyleRareInheritedData()
     , hyphenationLimitBefore(-1)
     , hyphenationLimitAfter(-1)
     , hyphenationLimitLines(-1)
+    , colorFilter(StyleFilterData::create())
     , lineGrid(RenderStyle::initialLineGrid())
     , tabSize(RenderStyle::initialTabSize())
 #if ENABLE(TEXT_AUTOSIZING)
@@ -231,6 +233,7 @@ inline StyleRareInheritedData::StyleRareInheritedData(const StyleRareInheritedDa
     , hyphenationLimitAfter(o.hyphenationLimitAfter)
     , hyphenationLimitLines(o.hyphenationLimitLines)
     , textEmphasisCustomMark(o.textEmphasisCustomMark)
+    , colorFilter(o.colorFilter)
     , lineGrid(o.lineGrid)
     , tabSize(o.tabSize)
 #if ENABLE(TEXT_AUTOSIZING)
@@ -307,6 +310,7 @@ bool StyleRareInheritedData::operator==(const StyleRareInheritedData& o) const
         && hyphenationString == o.hyphenationString
         && textEmphasisCustomMark == o.textEmphasisCustomMark
         && arePointingToEqualData(quotes, o.quotes)
+        && colorFilter == o.colorFilter
         && tabSize == o.tabSize
         && lineGrid == o.lineGrid
 #if ENABLE(CSS_IMAGE_ORIENTATION)
@@ -345,4 +349,9 @@ bool StyleRareInheritedData::operator==(const StyleRareInheritedData& o) const
         && arePointingToEqualData(listStyleImage, o.listStyleImage);
 }
 
+bool StyleRareInheritedData::hasColorFilters() const
+{
+    return !colorFilter->operations.isEmpty();
+}
+
 } // namespace WebCore
index e1936e3..e88461f 100644 (file)
@@ -40,6 +40,7 @@ namespace WebCore {
 class CursorList;
 class QuotesData;
 class ShadowData;
+class StyleFilterData;
 class StyleImage;
 
 // This struct is for rarely used inherited CSS3, CSS2, and WebKit-specific properties.
@@ -57,6 +58,8 @@ public:
         return !(*this == o);
     }
 
+    bool hasColorFilters() const;
+
     RefPtr<StyleImage> listStyleImage;
 
     Color textStrokeColor;
@@ -156,6 +159,7 @@ public:
 
     AtomicString textEmphasisCustomMark;
     RefPtr<QuotesData> quotes;
+    DataRef<StyleFilterData> colorFilter;
 
     AtomicString lineGrid;
     unsigned tabSize;
index fdfefa0..631fd38 100644 (file)
@@ -1,3 +1,14 @@
+2018-04-24  Simon Fraser  <simon.fraser@apple.com>
+
+        Add a new "color-filter" CSS property as an experimental feature
+        https://bugs.webkit.org/show_bug.cgi?id=184940
+
+        Reviewed by Jon Lee.
+        
+        Add the color-filter property as an experimental feature.
+
+        * Shared/WebPreferences.yaml:
+
 2018-04-24  Saam Barati  <sbarati@apple.com>
 
         Keep around a pre-warmed process when doing process swap on navigation
index 8332925..b5f62c7 100644 (file)
@@ -1080,11 +1080,18 @@ CacheAPIEnabled:
   category: experimental
   webcoreBinding: RuntimeEnabledFeatures
 
+ColorFilterEnabled:
+  type: bool
+  defaultValue: DEFAULT_EXPERIMENTAL_FEATURES_ENABLED
+  humanReadableName: "Color Filter"
+  humanReadableDescription: "Enable CSS Color Filter property"
+  category: experimental
+
 ConstantPropertiesEnabled:
   type: bool
   defaultValue: DEFAULT_EXPERIMENTAL_FEATURES_ENABLED
   humanReadableName: "Constant Properties"
-  humanReadableDescription: "Enable CSS constant() properties"
+  humanReadableDescription: "Enable CSS constant() values"
   category: experimental
 
 SpringTimingFunctionEnabled: