Use enum classes and OptionSets for PaintPhase and PaintBehavior
[WebKit-https.git] / Source / WebCore / rendering / RenderThemeMac.mm
index a2e3ce7..e2053ad 100644 (file)
@@ -25,6 +25,7 @@
 #import "BitmapImage.h"
 #import "CSSValueKeywords.h"
 #import "CSSValueList.h"
+#import "Color.h"
 #import "ColorMac.h"
 #import "Document.h"
 #import "Element.h"
@@ -35,6 +36,7 @@
 #import "FrameSelection.h"
 #import "FrameView.h"
 #import "GeometryUtilities.h"
+#import "GraphicsContext.h"
 #import "GraphicsContextCG.h"
 #import "HTMLAttachmentElement.h"
 #import "HTMLInputElement.h"
@@ -136,14 +138,19 @@ static const double progressAnimationNumFrames = 256;
     self = [super init];
     if (!self)
         return nil;
+
     [[NSNotificationCenter defaultCenter] addObserver:self
         selector:@selector(systemColorsDidChange:) name:NSSystemColorsDidChangeNotification object:nil];
+
+    [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self
+        selector:@selector(systemColorsDidChange:) name:NSWorkspaceAccessibilityDisplayOptionsDidChangeNotification object:nil];
+
     return self;
 }
 
-- (void)systemColorsDidChange:(NSNotification *)unusedNotification
+- (void)systemColorsDidChange:(NSNotification *)notification
 {
-    ASSERT_UNUSED(unusedNotification, [[unusedNotification name] isEqualToString:NSSystemColorsDidChangeNotification]);
+    UNUSED_PARAM(notification);
     WebCore::RenderTheme::singleton().platformColorsDidChange();
 }
 
@@ -156,6 +163,14 @@ static const double progressAnimationNumFrames = 256;
 
 - (CFDictionaryRef)_adjustedCoreUIDrawOptionsForDrawingBordersOnly:(CFDictionaryRef)defaultOptions
 {
+#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
+    // Dark mode controls don't have borders, just a semi-transparent background of shadows.
+    // In the dark mode case we can't disable borders, or we will not paint anything for the control.
+    NSAppearanceName appearance = [self.controlView.effectiveAppearance bestMatchFromAppearancesWithNames:@[ NSAppearanceNameAqua, NSAppearanceNameDarkAqua ]];
+    if ([appearance isEqualToString:NSAppearanceNameDarkAqua])
+        return defaultOptions;
+#endif
+
     // FIXME: This is a workaround for <rdar://problem/11385461>. When that bug is resolved, we should remove this code,
     // as well as the internal method overrides below.
     CFMutableDictionaryRef coreUIDrawOptions = CFDictionaryCreateMutableCopy(NULL, 0, defaultOptions);
@@ -213,7 +228,7 @@ RenderThemeMac::RenderThemeMac()
 
 NSView *RenderThemeMac::documentViewFor(const RenderObject& o) const
 {
-    LocalDefaultSystemAppearance localAppearance(o.page().useSystemAppearance(), o.page().defaultAppearance());
+    LocalDefaultSystemAppearance localAppearance(o.page().useSystemAppearance(), o.page().useDarkAppearance());
     ControlStates states(extractControlStatesForRenderer(o));
     return ThemeMac::ensuredView(&o.view().frameView(), states);
 }
@@ -251,6 +266,9 @@ void RenderThemeMac::purgeCaches()
     m_mediaControlsScript.clearImplIfNotShared();
     m_legacyMediaControlsStyleSheet.clearImplIfNotShared();
     m_mediaControlsStyleSheet.clearImplIfNotShared();
+    m_darkColorCache = ColorCache();
+
+    RenderTheme::purgeCaches();
 }
 
 String RenderThemeMac::mediaControlsScript()
@@ -305,14 +323,14 @@ String RenderThemeMac::imageControlsStyleSheet() const
 
 Color RenderThemeMac::platformActiveSelectionBackgroundColor(OptionSet<StyleColor::Options> options) const
 {
-    LocalDefaultSystemAppearance localAppearance(options.contains(StyleColor::Options::UseSystemAppearance), options.contains(StyleColor::Options::UseDefaultAppearance));
+    LocalDefaultSystemAppearance localAppearance(options.contains(StyleColor::Options::UseSystemAppearance), options.contains(StyleColor::Options::UseDarkAppearance));
     return colorFromNSColor([NSColor selectedTextBackgroundColor]);
 }
 
 Color RenderThemeMac::platformInactiveSelectionBackgroundColor(OptionSet<StyleColor::Options> options) const
 {
 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
-    LocalDefaultSystemAppearance localAppearance(options.contains(StyleColor::Options::UseSystemAppearance), options.contains(StyleColor::Options::UseDefaultAppearance));
+    LocalDefaultSystemAppearance localAppearance(options.contains(StyleColor::Options::UseSystemAppearance), options.contains(StyleColor::Options::UseDarkAppearance));
     return colorFromNSColor([NSColor unemphasizedSelectedTextBackgroundColor]);
 #else
     UNUSED_PARAM(options);
@@ -320,27 +338,49 @@ Color RenderThemeMac::platformInactiveSelectionBackgroundColor(OptionSet<StyleCo
 #endif
 }
 
+Color RenderThemeMac::transformSelectionBackgroundColor(const Color& color, OptionSet<StyleColor::Options> options) const
+{
+    LocalDefaultSystemAppearance localAppearance(options.contains(StyleColor::Options::UseSystemAppearance), options.contains(StyleColor::Options::UseDarkAppearance));
+    if (localAppearance.usingDarkAppearance()) {
+        // Use an alpha value that is similar to results from blendWithWhite() on light colors.
+        static const float darkAppearanceAlpha = 0.8;
+        return !color.isOpaque() ? color : color.colorWithAlpha(darkAppearanceAlpha);
+    }
+
+    return RenderTheme::transformSelectionBackgroundColor(color, options);
+}
+
+bool RenderThemeMac::supportsSelectionForegroundColors(OptionSet<StyleColor::Options> options) const
+{
+    LocalDefaultSystemAppearance localAppearance(options.contains(StyleColor::Options::UseSystemAppearance), options.contains(StyleColor::Options::UseDarkAppearance));
+    return localAppearance.usingDarkAppearance();
+}
+
 Color RenderThemeMac::platformActiveSelectionForegroundColor(OptionSet<StyleColor::Options> options) const
 {
-    LocalDefaultSystemAppearance localAppearance(options.contains(StyleColor::Options::UseSystemAppearance), options.contains(StyleColor::Options::UseDefaultAppearance));
-    return colorFromNSColor([NSColor selectedTextColor]);
+    LocalDefaultSystemAppearance localAppearance(options.contains(StyleColor::Options::UseSystemAppearance), options.contains(StyleColor::Options::UseDarkAppearance));
+    if (localAppearance.usingDarkAppearance())
+        return colorFromNSColor([NSColor selectedTextColor]);
+    return { };
 }
 
 Color RenderThemeMac::platformInactiveSelectionForegroundColor(OptionSet<StyleColor::Options> options) const
 {
 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
-    LocalDefaultSystemAppearance localAppearance(options.contains(StyleColor::Options::UseSystemAppearance), options.contains(StyleColor::Options::UseDefaultAppearance));
-    return colorFromNSColor([NSColor unemphasizedSelectedTextColor]);
+    LocalDefaultSystemAppearance localAppearance(options.contains(StyleColor::Options::UseSystemAppearance), options.contains(StyleColor::Options::UseDarkAppearance));
+    if (localAppearance.usingDarkAppearance())
+        return colorFromNSColor([NSColor unemphasizedSelectedTextColor]);
+    return { };
 #else
     UNUSED_PARAM(options);
-    return colorFromNSColor([NSColor textColor]);
+    return { };
 #endif
 }
 
 Color RenderThemeMac::platformActiveListBoxSelectionBackgroundColor(OptionSet<StyleColor::Options> options) const
 {
 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
-    LocalDefaultSystemAppearance localAppearance(options.contains(StyleColor::Options::UseSystemAppearance), options.contains(StyleColor::Options::UseDefaultAppearance));
+    LocalDefaultSystemAppearance localAppearance(options.contains(StyleColor::Options::UseSystemAppearance), options.contains(StyleColor::Options::UseDarkAppearance));
     return colorFromNSColor([NSColor selectedContentBackgroundColor]);
 #else
     UNUSED_PARAM(options);
@@ -351,7 +391,7 @@ Color RenderThemeMac::platformActiveListBoxSelectionBackgroundColor(OptionSet<St
 Color RenderThemeMac::platformInactiveListBoxSelectionBackgroundColor(OptionSet<StyleColor::Options> options) const
 {
 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
-    LocalDefaultSystemAppearance localAppearance(options.contains(StyleColor::Options::UseSystemAppearance), options.contains(StyleColor::Options::UseDefaultAppearance));
+    LocalDefaultSystemAppearance localAppearance(options.contains(StyleColor::Options::UseSystemAppearance), options.contains(StyleColor::Options::UseDarkAppearance));
     return colorFromNSColor([NSColor unemphasizedSelectedContentBackgroundColor]);
 #else
     UNUSED_PARAM(options);
@@ -361,14 +401,14 @@ Color RenderThemeMac::platformInactiveListBoxSelectionBackgroundColor(OptionSet<
 
 Color RenderThemeMac::platformActiveListBoxSelectionForegroundColor(OptionSet<StyleColor::Options> options) const
 {
-    LocalDefaultSystemAppearance localAppearance(options.contains(StyleColor::Options::UseSystemAppearance), options.contains(StyleColor::Options::UseDefaultAppearance));
+    LocalDefaultSystemAppearance localAppearance(options.contains(StyleColor::Options::UseSystemAppearance), options.contains(StyleColor::Options::UseDarkAppearance));
     return colorFromNSColor([NSColor alternateSelectedControlTextColor]);
 }
 
 Color RenderThemeMac::platformInactiveListBoxSelectionForegroundColor(OptionSet<StyleColor::Options> options) const
 {
 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
-    LocalDefaultSystemAppearance localAppearance(options.contains(StyleColor::Options::UseSystemAppearance), options.contains(StyleColor::Options::UseDefaultAppearance));
+    LocalDefaultSystemAppearance localAppearance(options.contains(StyleColor::Options::UseSystemAppearance), options.contains(StyleColor::Options::UseDarkAppearance));
     return colorFromNSColor([NSColor unemphasizedSelectedTextColor]);
 #else
     UNUSED_PARAM(options);
@@ -383,6 +423,24 @@ Color RenderThemeMac::platformFocusRingColor(OptionSet<StyleColor::Options> opti
     return systemColor(CSSValueWebkitFocusRingColor, options);
 }
 
+Color RenderThemeMac::platformActiveTextSearchHighlightColor(OptionSet<StyleColor::Options> options) const
+{
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300
+    LocalDefaultSystemAppearance localAppearance(options.contains(StyleColor::Options::UseSystemAppearance), options.contains(StyleColor::Options::UseDarkAppearance));
+    return colorFromNSColor([NSColor findHighlightColor]);
+#else
+    UNUSED_PARAM(options);
+    return Color(255, 255, 0); // Yellow.
+#endif
+}
+
+Color RenderThemeMac::platformInactiveTextSearchHighlightColor(OptionSet<StyleColor::Options> options) const
+{
+    // The inactive color is normally used, since no legacy WebKit client marks a text match as active.
+    // So just return the same color for both states.
+    return platformActiveTextSearchHighlightColor(options);
+}
+
 static FontSelectionValue toFontWeight(NSInteger appKitFontWeight)
 {
     ASSERT(appKitFontWeight > 0 && appKitFontWeight < 15);
@@ -478,46 +536,88 @@ static RGBA32 menuBackgroundColor()
 
 void RenderThemeMac::platformColorsDidChange()
 {
-    m_systemColorCache.clear();
-    m_systemVisitedLinkColor = Color();
+    m_darkColorCache = ColorCache();
+
     RenderTheme::platformColorsDidChange();
 }
 
+auto RenderThemeMac::colorCache(OptionSet<StyleColor::Options> options) const -> ColorCache&
+{
+    const bool useSystemAppearance = options.contains(StyleColor::Options::UseSystemAppearance);
+    const bool useDarkAppearance = options.contains(StyleColor::Options::UseDarkAppearance);
+    LocalDefaultSystemAppearance localAppearance(useSystemAppearance, useDarkAppearance);
+    if (localAppearance.usingDarkAppearance())
+        return m_darkColorCache;
+    return RenderTheme::colorCache(options);
+}
+
 Color RenderThemeMac::systemColor(CSSValueID cssValueID, OptionSet<StyleColor::Options> options) const
 {
     const bool useSystemAppearance = options.contains(StyleColor::Options::UseSystemAppearance);
-    const bool useDefaultAppearance = options.contains(StyleColor::Options::UseDefaultAppearance);
+    const bool useDarkAppearance = options.contains(StyleColor::Options::UseDarkAppearance);
     const bool forVisitedLink = options.contains(StyleColor::Options::ForVisitedLink);
 
-    LocalDefaultSystemAppearance localAppearance(useSystemAppearance, useDefaultAppearance);
+    LocalDefaultSystemAppearance localAppearance(useSystemAppearance, useDarkAppearance);
 
-    // The system color cache below can't handle visited links. The only color value
-    // that cares about visited links is CSSValueWebkitLink, so handle it here.
-    if (forVisitedLink && cssValueID == CSSValueWebkitLink) {
-        // Only use NSColor when the system appearance is desired, otherwise use RenderTheme's default.
-        if (useSystemAppearance) {
-            if (!m_systemVisitedLinkColor.isValid())
-                m_systemVisitedLinkColor = colorFromNSColor([NSColor systemPurpleColor]);
-            return m_systemVisitedLinkColor;
-        }
+    auto& cache = colorCache(options);
+
+    if (useSystemAppearance) {
+        // Special handling for links and other system colors when the system appearance is desired.
+        auto systemAppearanceColor = [] (Color& color, SEL selector) -> Color {
+            if (!color.isValid()) {
+                auto systemColor = wtfObjcMsgSend<NSColor *>([NSColor class], selector);
+                color = semanticColorFromNSColor(systemColor);
+            }
 
+            return color;
+        };
+
+        switch (cssValueID) {
+        // Web views that want system appearance get the system version of link colors, which differ from the HTML spec.
+        case CSSValueWebkitLink:
+            if (forVisitedLink)
+                return systemAppearanceColor(cache.systemVisitedLinkColor, @selector(systemPurpleColor));
+            return systemAppearanceColor(cache.systemLinkColor, @selector(linkColor));
+
+        case CSSValueWebkitActivelink:
+            // FIXME: Use a semantic system color for this, instead of systemRedColor. <rdar://problem/39256684>
+            return systemAppearanceColor(cache.systemActiveLinkColor, @selector(systemRedColor));
+
+        // The following colors would expose user appearance preferences to the web, and could be used for fingerprinting.
+        // These should only be available when the web view is wanting the system appearance.
+        case CSSValueWebkitFocusRingColor:
+        case CSSValueActiveborder:
+            return systemAppearanceColor(cache.systemFocusRingColor, @selector(keyboardFocusIndicatorColor));
+
+        case CSSValueAppleSystemControlAccent:
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
+            return systemAppearanceColor(cache.systemControlAccentColor, @selector(controlAccentColor));
+#else
+            return systemAppearanceColor(cache.systemControlAccentColor, @selector(alternateSelectedControlColor));
+#endif
+
+        case CSSValueAppleSystemSelectedContentBackground:
+            return activeListBoxSelectionBackgroundColor(options);
+
+        case CSSValueAppleSystemSelectedTextBackground:
+        case CSSValueHighlight:
+            return activeSelectionBackgroundColor(options);
+
+        default:
+            // Handle other system colors below, that don't need special system appearance handling.
+            break;
+        }
+    } else if (forVisitedLink && cssValueID == CSSValueWebkitLink) {
+        // The system color cache below can't handle visited links. The only color value
+        // that cares about visited links is CSSValueWebkitLink, so handle it here.
         return RenderTheme::systemColor(cssValueID, options);
     }
 
     ASSERT(!forVisitedLink);
 
-    return m_systemColorCache.ensure(cssValueID, [this, cssValueID, useSystemAppearance, options] () -> Color {
-        auto selectCocoaColor = [cssValueID, useSystemAppearance] () -> SEL {
+    return cache.systemStyleColors.ensure(cssValueID, [this, cssValueID, options, &localAppearance] () -> Color {
+        auto selectCocoaColor = [cssValueID] () -> SEL {
             switch (cssValueID) {
-            case CSSValueWebkitLink:
-                // Only use NSColor when the system appearance is desired, otherwise use RenderTheme's default.
-                return useSystemAppearance ? @selector(linkColor) : nullptr;
-            case CSSValueWebkitActivelink:
-                // Only use NSColor when the system appearance is desired, otherwise use RenderTheme's default.
-                // FIXME: Use a semantic system color for this, instead of systemRedColor. <rdar://problem/39256684>
-                return useSystemAppearance ? @selector(systemRedColor) : nullptr;
-            case CSSValueActiveborder:
-                return @selector(keyboardFocusIndicatorColor);
             case CSSValueActivecaption:
                 return @selector(windowFrameTextColor);
             case CSSValueAppworkspace:
@@ -532,8 +632,6 @@ Color RenderThemeMac::systemColor(CSSValueID cssValueID, OptionSet<StyleColor::O
                 return @selector(textColor);
             case CSSValueGraytext:
                 return @selector(disabledControlTextColor);
-            case CSSValueHighlight:
-                return @selector(selectedTextBackgroundColor);
             case CSSValueHighlighttext:
                 return @selector(selectedTextColor);
             case CSSValueInactiveborder:
@@ -558,8 +656,6 @@ Color RenderThemeMac::systemColor(CSSValueID cssValueID, OptionSet<StyleColor::O
                 return @selector(highlightColor);
             case CSSValueThreedlightshadow:
                 return @selector(controlLightHighlightColor);
-            case CSSValueWebkitFocusRingColor:
-                return @selector(keyboardFocusIndicatorColor);
             case CSSValueWindow:
                 return @selector(windowBackgroundColor);
             case CSSValueWindowframe:
@@ -570,8 +666,39 @@ Color RenderThemeMac::systemColor(CSSValueID cssValueID, OptionSet<StyleColor::O
                 return @selector(headerTextColor);
             case CSSValueAppleSystemTextBackground:
                 return @selector(textBackgroundColor);
+            case CSSValueAppleSystemControlBackground:
+                return @selector(controlBackgroundColor);
             case CSSValueAppleSystemAlternateSelectedText:
                 return @selector(alternateSelectedControlTextColor);
+            case CSSValueAppleSystemUnemphasizedSelectedContentBackground:
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
+                return @selector(unemphasizedSelectedContentBackgroundColor);
+#else
+                return @selector(secondarySelectedControlColor);
+#endif
+            case CSSValueAppleSystemSelectedText:
+                return @selector(selectedTextColor);
+            case CSSValueAppleSystemUnemphasizedSelectedText:
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
+                return @selector(unemphasizedSelectedTextColor);
+#else
+                return @selector(textColor);
+#endif
+            case CSSValueAppleSystemUnemphasizedSelectedTextBackground:
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
+                return @selector(unemphasizedSelectedTextBackgroundColor);
+#else
+                return @selector(secondarySelectedControlColor);
+#endif
+            case CSSValueAppleSystemPlaceholderText:
+                return @selector(placeholderTextColor);
+            case CSSValueAppleSystemFindHighlightBackground:
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300
+                return @selector(findHighlightColor);
+#else
+                // Handled below.
+                return nullptr;
+#endif
             case CSSValueAppleSystemLabel:
                 return @selector(labelColor);
             case CSSValueAppleSystemSecondaryLabel:
@@ -582,6 +709,12 @@ Color RenderThemeMac::systemColor(CSSValueID cssValueID, OptionSet<StyleColor::O
                 return @selector(quaternaryLabelColor);
             case CSSValueAppleSystemGrid:
                 return @selector(gridColor);
+            case CSSValueAppleSystemSeparator:
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
+                return @selector(separatorColor);
+#else
+                return @selector(gridColor);
+#endif
             case CSSValueAppleWirelessPlaybackTargetActive:
                 return @selector(systemBlueColor);
             case CSSValueAppleSystemBlue:
@@ -609,26 +742,81 @@ Color RenderThemeMac::systemColor(CSSValueID cssValueID, OptionSet<StyleColor::O
 
         if (auto selector = selectCocoaColor()) {
             if (auto color = wtfObjcMsgSend<NSColor *>([NSColor class], selector))
-                return colorFromNSColor(color);
+                return semanticColorFromNSColor(color);
         }
 
         switch (cssValueID) {
         case CSSValueActivebuttontext:
             // No corresponding NSColor for this so we use a hard coded value.
             return Color::white;
+
         case CSSValueButtonface:
         case CSSValueThreedface:
             // We selected this value instead of [NSColor controlColor] to avoid website incompatibilities.
             // We may want to consider changing to [NSColor controlColor] some day.
             return 0xFFC0C0C0;
+
         case CSSValueInfobackground:
             // No corresponding NSColor for this so we use a hard coded value.
             return 0xFFFBFCC5;
+
         case CSSValueMenu:
             return menuBackgroundColor();
+
+        case CSSValueWebkitFocusRingColor:
+        case CSSValueActiveborder:
+            // Hardcoded to avoid exposing a user appearance preference to the web for fingerprinting.
+            if (localAppearance.usingDarkAppearance())
+                return Color(0x4C1AA9FF, Color::Semantic);
+            return Color(0x3F0067F4, Color::Semantic);
+
+        case CSSValueAppleSystemControlAccent:
+            // Hardcoded to avoid exposing a user appearance preference to the web for fingerprinting.
+            // Same color in light and dark appearances.
+            return Color(0xFF007AFF, Color::Semantic);
+
+        case CSSValueAppleSystemSelectedContentBackground:
+            // Hardcoded to avoid exposing a user appearance preference to the web for fingerprinting.
+            if (localAppearance.usingDarkAppearance())
+                return Color(0xFF0058D0, Color::Semantic);
+            return Color(0xFF0063E1, Color::Semantic);
+
+        case CSSValueHighlight:
+        case CSSValueAppleSystemSelectedTextBackground:
+            // Hardcoded to avoid exposing a user appearance preference to the web for fingerprinting.
+            if (localAppearance.usingDarkAppearance())
+                return Color(0xCC3F638B, Color::Semantic);
+            return Color(0x9980BCFE, Color::Semantic);
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED < 101300
+        case CSSValueAppleSystemFindHighlightBackground:
+            return platformActiveTextSearchHighlightColor(options);
+#endif
+
+        case CSSValueAppleSystemEvenAlternatingContentBackground: {
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
+            NSArray<NSColor *> *alternateColors = [NSColor alternatingContentBackgroundColors];
+#else
+            NSArray<NSColor *> *alternateColors = [NSColor controlAlternatingRowBackgroundColors];
+#endif
+            ASSERT(alternateColors.count >= 2);
+            return semanticColorFromNSColor(alternateColors[0]);
+        }
+
+        case CSSValueAppleSystemOddAlternatingContentBackground: {
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
+            NSArray<NSColor *> *alternateColors = [NSColor alternatingContentBackgroundColors];
+#else
+            NSArray<NSColor *> *alternateColors = [NSColor controlAlternatingRowBackgroundColors];
+#endif
+            ASSERT(alternateColors.count >= 2);
+            return semanticColorFromNSColor(alternateColors[1]);
+        }
+
         case CSSValueBackground:
             // Use platform-independent value returned by base class.
             FALLTHROUGH;
+
         default:
             return RenderTheme::systemColor(cssValueID, options);
         }
@@ -867,7 +1055,12 @@ bool RenderThemeMac::paintTextField(const RenderObject& o, const PaintInfo& pain
     AffineTransform transform = paintInfo.context().getCTM();
     if (transform.xScale() > 1 || transform.yScale() > 1) {
         adjustedPaintRect.inflateX(1 / transform.xScale());
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
+        adjustedPaintRect.inflateY(2 / transform.yScale());
+        adjustedPaintRect.move(0, -1 / transform.yScale());
+#else
         adjustedPaintRect.inflateY(1 / transform.yScale());
+#endif
     }
     NSTextFieldCell *textField = this->textField();
 
@@ -1468,7 +1661,7 @@ void RenderThemeMac::setPopupButtonCellState(const RenderObject& o, const IntSiz
 
 void RenderThemeMac::paintCellAndSetFocusedElementNeedsRepaintIfNecessary(NSCell* cell, const RenderObject& renderer, const PaintInfo& paintInfo, const FloatRect& rect)
 {
-    LocalDefaultSystemAppearance localAppearance(renderer.page().useSystemAppearance(), renderer.page().defaultAppearance());
+    LocalDefaultSystemAppearance localAppearance(renderer.page().useSystemAppearance(), renderer.page().useDarkAppearance());
     bool shouldDrawFocusRing = isFocused(renderer) && renderer.style().outlineStyleIsAuto() == OutlineIsAuto::On;
     bool shouldUseImageBuffer = renderer.style().effectiveZoom() != 1 || renderer.page().pageScaleFactor() != 1;
     bool shouldDrawCell = true;
@@ -1550,7 +1743,7 @@ bool RenderThemeMac::paintSliderThumb(const RenderObject& o, const PaintInfo& pa
         ? sliderThumbVertical()
         : sliderThumbHorizontal();
 
-    LocalDefaultSystemAppearance localAppearance(o.page().useSystemAppearance(), o.page().defaultAppearance());
+    LocalDefaultSystemAppearance localAppearance(o.page().useSystemAppearance(), o.page().useDarkAppearance());
 
     LocalCurrentGraphicsContext localContext(paintInfo.context());
 
@@ -1898,7 +2091,7 @@ bool RenderThemeMac::paintSearchFieldResultsButton(const RenderBox& box, const P
 
 bool RenderThemeMac::paintSnapshottedPluginOverlay(const RenderObject& renderer, const PaintInfo& paintInfo, const IntRect&)
 {
-    if (paintInfo.phase != PaintPhaseBlockBackground)
+    if (paintInfo.phase != PaintPhase::BlockBackground)
         return true;
 
     if (!is<RenderBlock>(renderer))
@@ -2110,7 +2303,7 @@ NSServicesRolloverButtonCell* RenderThemeMac::servicesRolloverButtonCell() const
 
 bool RenderThemeMac::paintImageControlsButton(const RenderObject& renderer, const PaintInfo& paintInfo, const IntRect& rect)
 {
-    if (paintInfo.phase != PaintPhaseBlockBackground)
+    if (paintInfo.phase != PaintPhase::BlockBackground)
         return true;
 
 #if HAVE(APPKIT_SERVICE_CONTROLS_SUPPORT)
@@ -2625,6 +2818,60 @@ bool RenderThemeMac::paintAttachment(const RenderObject& renderer, const PaintIn
 
 #endif // ENABLE(ATTACHMENT_ELEMENT)
 
+static CGColorRef colorForStyle(DocumentMarkerLineStyle style, bool useDarkMode)
+{
+    switch (style) {
+    // Red.
+    case DocumentMarkerLineStyle::Spelling:
+        return cachedCGColor(useDarkMode ? Color { 255, 140, 140, 217 } : Color { 255, 59, 48, 191 });
+    // Blue.
+    case DocumentMarkerLineStyle::DictationAlternatives:
+    case DocumentMarkerLineStyle::TextCheckingDictationPhraseWithAlternatives:
+    case DocumentMarkerLineStyle::AutocorrectionReplacement:
+        return cachedCGColor(useDarkMode ? Color { 40, 145, 255, 217 } : Color { 0, 122, 255, 191 });
+    // Green.
+    case DocumentMarkerLineStyle::Grammar:
+        return cachedCGColor(useDarkMode ? Color { 50, 215, 75, 217 } : Color { 25, 175, 50, 191 });
+    }
+}
+
+void RenderThemeMac::drawLineForDocumentMarker(const RenderText& renderer, GraphicsContext& context, const FloatPoint& origin, float width, DocumentMarkerLineStyle style)
+{
+    if (context.paintingDisabled())
+        return;
+
+    auto circleColor = colorForStyle(style, renderer.page().useSystemAppearance() && renderer.page().useDarkAppearance());
+
+    // Center the underline and ensure we only draw entires dots.
+    FloatPoint offsetPoint = origin;
+    float widthMod = fmodf(width, cMisspellingLinePatternWidth);
+    if (cMisspellingLinePatternWidth - widthMod > cMisspellingLinePatternGapWidth) {
+        float gapIncludeWidth = 0;
+        if (width > cMisspellingLinePatternWidth)
+            gapIncludeWidth = cMisspellingLinePatternGapWidth;
+        offsetPoint.move(floor((widthMod + gapIncludeWidth) / 2), 0);
+        width -= widthMod;
+    }
+
+    CGContextRef ctx = context.platformContext();
+    CGContextStateSaver stateSaver { ctx };
+    CGContextSetFillColorWithColor(ctx, circleColor);
+    for (int x = 0; x < width; x += cMisspellingLinePatternWidth)
+        CGContextAddEllipseInRect(ctx, CGRectMake(offsetPoint.x() + x, offsetPoint.y(), cMisspellingLineThickness, cMisspellingLineThickness));
+    CGContextSetCompositeOperation(ctx, kCGCompositeSover);
+    CGContextFillPath(ctx);
+}
+
+bool RenderThemeMac::usingDarkAppearance(const RenderObject& o) const
+{
+#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
+    return o.page().useSystemAppearance() && o.page().useDarkAppearance();
+#else
+    UNUSED_PARAM(o);
+    return false;
+#endif
+}
+
 } // namespace WebCore
 
 #endif // PLATFORM(MAC)