Add CSS -webkit-appearance property for Apple Pay buttons
[WebKit-https.git] / Source / WebCore / rendering / RenderTheme.cpp
index 9c921c4..cdd01e3 100644 (file)
@@ -1,7 +1,8 @@
-/**
+/*
  * This file is part of the theme implementation for form controls in WebCore.
  *
- * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Computer, Inc.
+ * Copyright (C) 2005-2010, 2012, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -23,6 +24,7 @@
 #include "RenderTheme.h"
 
 #include "CSSValueKeywords.h"
+#include "ControlStates.h"
 #include "Document.h"
 #include "FileList.h"
 #include "FileSystem.h"
 #include "SpinButtonElement.h"
 #include "StringTruncator.h"
 #include "TextControlInnerElements.h"
+#include <wtf/NeverDestroyed.h>
 
 #if ENABLE(METER_ELEMENT)
 #include "HTMLMeterElement.h"
 #include "RenderMeter.h"
 #endif
 
-#if ENABLE(INPUT_SPEECH)
-#include "RenderInputSpeech.h"
-#endif
-
 #if ENABLE(DATALIST_ELEMENT)
 #include "HTMLCollection.h"
 #include "HTMLDataListElement.h"
@@ -69,7 +68,7 @@ using namespace HTMLNames;
 
 static Color& customFocusRingColor()
 {
-    DEFINE_STATIC_LOCAL(Color, color, ());
+    static NeverDestroyed<Color> color;
     return color;
 }
 
@@ -80,7 +79,7 @@ RenderTheme::RenderTheme()
 {
 }
 
-void RenderTheme::adjustStyle(StyleResolver& styleResolver, RenderStyle& style, Element* e, bool UAHasAppearance, const BorderData& border, const FillLayer& background, const Color& backgroundColor)
+void RenderTheme::adjustStyle(StyleResolver& styleResolver, RenderStyle& style, const Element* element, bool UAHasAppearance, const BorderData& border, const FillLayer& background, const Color& backgroundColor)
 {
     // Force inline and table display styles to be inline-block (except for table- which is block)
     ControlPart part = style.appearance();
@@ -92,7 +91,7 @@ void RenderTheme::adjustStyle(StyleResolver& styleResolver, RenderStyle& style,
     else if (style.display() == COMPACT || style.display() == LIST_ITEM || style.display() == TABLE)
         style.setDisplay(BLOCK);
 
-    if (UAHasAppearance && isControlStyled(&style, border, background, backgroundColor)) {
+    if (UAHasAppearance && isControlStyled(style, border, background, backgroundColor)) {
         if (part == MenulistPart) {
             style.setAppearance(MenulistButtonPart);
             part = MenulistButtonPart;
@@ -117,7 +116,7 @@ void RenderTheme::adjustStyle(StyleResolver& styleResolver, RenderStyle& style,
     case ButtonPart: {
         // Border
         LengthBox borderBox(style.borderTopWidth(), style.borderRightWidth(), style.borderBottomWidth(), style.borderLeftWidth());
-        borderBox = m_theme->controlBorder(part, style.font(), borderBox, style.effectiveZoom());
+        borderBox = m_theme->controlBorder(part, style.fontCascade(), borderBox, style.effectiveZoom());
         if (borderBox.top().value() != static_cast<int>(style.borderTopWidth())) {
             if (borderBox.top().value())
                 style.setBorderTopWidth(borderBox.top().value());
@@ -146,7 +145,7 @@ void RenderTheme::adjustStyle(StyleResolver& styleResolver, RenderStyle& style,
         }
 
         // Padding
-        LengthBox paddingBox = m_theme->controlPadding(part, style.font(), style.paddingBox(), style.effectiveZoom());
+        LengthBox paddingBox = m_theme->controlPadding(part, style.fontCascade(), style.paddingBox(), style.effectiveZoom());
         if (paddingBox != style.paddingBox())
             style.setPaddingBox(paddingBox);
 
@@ -157,31 +156,32 @@ void RenderTheme::adjustStyle(StyleResolver& styleResolver, RenderStyle& style,
         // Width / Height
         // The width and height here are affected by the zoom.
         // FIXME: Check is flawed, since it doesn't take min-width/max-width into account.
-        LengthSize controlSize = m_theme->controlSize(part, style.font(), LengthSize(style.width(), style.height()), style.effectiveZoom());
+        LengthSize controlSize = m_theme->controlSize(part, style.fontCascade(), LengthSize(style.width(), style.height()), style.effectiveZoom());
         if (controlSize.width() != style.width())
             style.setWidth(controlSize.width());
         if (controlSize.height() != style.height())
             style.setHeight(controlSize.height());
                 
         // Min-Width / Min-Height
-        LengthSize minControlSize = m_theme->minimumControlSize(part, style.font(), style.effectiveZoom());
+        LengthSize minControlSize = m_theme->minimumControlSize(part, style.fontCascade(), style.effectiveZoom());
         if (minControlSize.width() != style.minWidth())
             style.setMinWidth(minControlSize.width());
         if (minControlSize.height() != style.minHeight())
             style.setMinHeight(minControlSize.height());
                 
         // Font
-        FontDescription controlFont = m_theme->controlFont(part, style.font(), style.effectiveZoom());
-        if (controlFont != style.font().fontDescription()) {
-            // Reset our line-height
+        if (auto themeFont = m_theme->controlFont(part, style.fontCascade(), style.effectiveZoom())) {
+            // If overriding the specified font with the theme font, also override the line height with the standard line height.
             style.setLineHeight(RenderStyle::initialLineHeight());
-
-            // Now update our font.
-            if (style.setFontDescription(controlFont))
-                style.font().update(0);
+            if (style.setFontDescription(themeFont.value()))
+                style.fontCascade().update(nullptr);
         }
+
+        // Special style that tells enabled default buttons in active windows to use the ActiveButtonText color.
+        // The active window part of the test has to be done at paint time since it's not triggered by a style change.
+        style.setInsideDefaultButton(part == DefaultButtonPart && element && !element->isDisabledFormControl());
+        break;
     }
-    break;
     default:
         break;
     }
@@ -191,25 +191,25 @@ void RenderTheme::adjustStyle(StyleResolver& styleResolver, RenderStyle& style,
     switch (style.appearance()) {
 #if !USE(NEW_THEME)
     case CheckboxPart:
-        return adjustCheckboxStyle(&styleResolver, &style, e);
+        return adjustCheckboxStyle(styleResolver, style, element);
     case RadioPart:
-        return adjustRadioStyle(&styleResolver, &style, e);
+        return adjustRadioStyle(styleResolver, style, element);
     case PushButtonPart:
     case SquareButtonPart:
     case DefaultButtonPart:
     case ButtonPart:
-        return adjustButtonStyle(&styleResolver, &style, e);
+        return adjustButtonStyle(styleResolver, style, element);
     case InnerSpinButtonPart:
-        return adjustInnerSpinButtonStyle(&styleResolver, &style, e);
+        return adjustInnerSpinButtonStyle(styleResolver, style, element);
 #endif
     case TextFieldPart:
-        return adjustTextFieldStyle(&styleResolver, &style, e);
+        return adjustTextFieldStyle(styleResolver, style, element);
     case TextAreaPart:
-        return adjustTextAreaStyle(&styleResolver, &style, e);
+        return adjustTextAreaStyle(styleResolver, style, element);
     case MenulistPart:
-        return adjustMenuListStyle(&styleResolver, &style, e);
+        return adjustMenuListStyle(styleResolver, style, element);
     case MenulistButtonPart:
-        return adjustMenuListButtonStyle(&styleResolver, &style, e);
+        return adjustMenuListButtonStyle(styleResolver, style, element);
     case MediaPlayButtonPart:
     case MediaCurrentTimePart:
     case MediaTimeRemainingPart:
@@ -217,67 +217,79 @@ void RenderTheme::adjustStyle(StyleResolver& styleResolver, RenderStyle& style,
     case MediaExitFullscreenButtonPart:
     case MediaMuteButtonPart:
     case MediaVolumeSliderContainerPart:
-        return adjustMediaControlStyle(&styleResolver, &style, e);
+        return adjustMediaControlStyle(styleResolver, style, element);
     case MediaSliderPart:
     case MediaVolumeSliderPart:
     case MediaFullScreenVolumeSliderPart:
     case SliderHorizontalPart:
     case SliderVerticalPart:
-        return adjustSliderTrackStyle(&styleResolver, &style, e);
+        return adjustSliderTrackStyle(styleResolver, style, element);
     case SliderThumbHorizontalPart:
     case SliderThumbVerticalPart:
-        return adjustSliderThumbStyle(&styleResolver, &style, e);
+        return adjustSliderThumbStyle(styleResolver, style, element);
     case SearchFieldPart:
-        return adjustSearchFieldStyle(&styleResolver, &style, e);
+        return adjustSearchFieldStyle(styleResolver, style, element);
     case SearchFieldCancelButtonPart:
-        return adjustSearchFieldCancelButtonStyle(&styleResolver, &style, e);
+        return adjustSearchFieldCancelButtonStyle(styleResolver, style, element);
     case SearchFieldDecorationPart:
-        return adjustSearchFieldDecorationPartStyle(&styleResolver, &style, e);
+        return adjustSearchFieldDecorationPartStyle(styleResolver, style, element);
     case SearchFieldResultsDecorationPart:
-        return adjustSearchFieldResultsDecorationPartStyle(&styleResolver, &style, e);
+        return adjustSearchFieldResultsDecorationPartStyle(styleResolver, style, element);
     case SearchFieldResultsButtonPart:
-        return adjustSearchFieldResultsButtonStyle(&styleResolver, &style, e);
-#if ENABLE(PROGRESS_ELEMENT)
+        return adjustSearchFieldResultsButtonStyle(styleResolver, style, element);
     case ProgressBarPart:
-        return adjustProgressBarStyle(&styleResolver, &style, e);
-#endif
+        return adjustProgressBarStyle(styleResolver, style, element);
 #if ENABLE(METER_ELEMENT)
     case MeterPart:
     case RelevancyLevelIndicatorPart:
     case ContinuousCapacityLevelIndicatorPart:
     case DiscreteCapacityLevelIndicatorPart:
     case RatingLevelIndicatorPart:
-        return adjustMeterStyle(&styleResolver, &style, e);
+        return adjustMeterStyle(styleResolver, style, element);
 #endif
-#if ENABLE(INPUT_SPEECH)
-    case InputSpeechButtonPart:
-        return adjustInputFieldSpeechButtonStyle(&styleResolver, &style, e);
-#endif
-#if ENABLE(IMAGE_CONTROLS)
+#if ENABLE(SERVICE_CONTROLS)
     case ImageControlsButtonPart:
         break;
 #endif
+    case CapsLockIndicatorPart:
+        return adjustCapsLockIndicatorStyle(styleResolver, style, element);
+#if ENABLE(APPLE_PAY)
+    case ApplePayButtonPart:
+        return adjustApplePayButtonStyle(styleResolver, style, element);
+#endif
+#if ENABLE(ATTACHMENT_ELEMENT)
+    case AttachmentPart:
+        return adjustAttachmentStyle(styleResolver, style, element);
+#endif
     default:
         break;
     }
 }
 
-bool RenderTheme::paint(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
+bool RenderTheme::paint(const RenderBox& box, ControlStates& controlStates, const PaintInfo& paintInfo, const LayoutRect& rect)
 {
     // If painting is disabled, but we aren't updating control tints, then just bail.
     // If we are updating control tints, just schedule a repaint if the theme supports tinting
     // for that control.
-    if (paintInfo.context->updatingControlTints()) {
-        if (controlSupportsTints(o))
-            o->repaint();
+    if (paintInfo.context().updatingControlTints()) {
+        if (controlSupportsTints(box))
+            box.repaint();
         return false;
     }
-    if (paintInfo.context->paintingDisabled())
+    if (paintInfo.context().paintingDisabled())
+        return false;
+
+    if (UNLIKELY(paintInfo.context().isRecording()))
         return false;
 
-    ControlPart part = o->style().appearance();
+    ControlPart part = box.style().appearance();
+    IntRect integralSnappedRect = snappedIntRect(rect);
+    float deviceScaleFactor = box.document().deviceScaleFactor();
+    FloatRect devicePixelSnappedRect = snapRectToDevicePixels(rect, deviceScaleFactor);
 
 #if USE(NEW_THEME)
+    float pageScaleFactor = box.document().page() ? box.document().page()->pageScaleFactor() : 1.0f;
+    
     switch (part) {
     case CheckboxPart:
     case RadioPart:
@@ -286,113 +298,120 @@ bool RenderTheme::paint(RenderObject* o, const PaintInfo& paintInfo, const IntRe
     case DefaultButtonPart:
     case ButtonPart:
     case InnerSpinButtonPart:
-        m_theme->paint(part, controlStatesForRenderer(o), const_cast<GraphicsContext*>(paintInfo.context), r, o->style().effectiveZoom(), &o->view().frameView());
+        updateControlStatesForRenderer(box, controlStates);
+        m_theme->paint(part, controlStates, paintInfo.context(), devicePixelSnappedRect, box.style().effectiveZoom(), &box.view().frameView(), deviceScaleFactor, pageScaleFactor);
         return false;
     default:
         break;
     }
+#else
+    UNUSED_PARAM(controlStates);
 #endif
 
     // Call the appropriate paint method based off the appearance value.
     switch (part) {
 #if !USE(NEW_THEME)
     case CheckboxPart:
-        return paintCheckbox(o, paintInfo, r);
+        return paintCheckbox(box, paintInfo, integralSnappedRect);
     case RadioPart:
-        return paintRadio(o, paintInfo, r);
+        return paintRadio(box, paintInfo, integralSnappedRect);
     case PushButtonPart:
     case SquareButtonPart:
     case DefaultButtonPart:
     case ButtonPart:
-        return paintButton(o, paintInfo, r);
+        return paintButton(box, paintInfo, integralSnappedRect);
     case InnerSpinButtonPart:
-        return paintInnerSpinButton(o, paintInfo, r);
+        return paintInnerSpinButton(box, paintInfo, integralSnappedRect);
 #endif
     case MenulistPart:
-        return paintMenuList(o, paintInfo, r);
+        return paintMenuList(box, paintInfo, devicePixelSnappedRect);
 #if ENABLE(METER_ELEMENT)
     case MeterPart:
     case RelevancyLevelIndicatorPart:
     case ContinuousCapacityLevelIndicatorPart:
     case DiscreteCapacityLevelIndicatorPart:
     case RatingLevelIndicatorPart:
-        return paintMeter(o, paintInfo, r);
+        return paintMeter(box, paintInfo, integralSnappedRect);
 #endif
-#if ENABLE(PROGRESS_ELEMENT)
     case ProgressBarPart:
-        return paintProgressBar(o, paintInfo, r);
-#endif
+        return paintProgressBar(box, paintInfo, integralSnappedRect);
     case SliderHorizontalPart:
     case SliderVerticalPart:
-        return paintSliderTrack(o, paintInfo, r);
+        return paintSliderTrack(box, paintInfo, integralSnappedRect);
     case SliderThumbHorizontalPart:
     case SliderThumbVerticalPart:
-        return paintSliderThumb(o, paintInfo, r);
+        return paintSliderThumb(box, paintInfo, integralSnappedRect);
     case MediaEnterFullscreenButtonPart:
     case MediaExitFullscreenButtonPart:
-        return paintMediaFullscreenButton(o, paintInfo, r);
+        return paintMediaFullscreenButton(box, paintInfo, integralSnappedRect);
     case MediaPlayButtonPart:
-        return paintMediaPlayButton(o, paintInfo, r);
+        return paintMediaPlayButton(box, paintInfo, integralSnappedRect);
     case MediaOverlayPlayButtonPart:
-        return paintMediaOverlayPlayButton(o, paintInfo, r);
+        return paintMediaOverlayPlayButton(box, paintInfo, integralSnappedRect);
     case MediaMuteButtonPart:
-        return paintMediaMuteButton(o, paintInfo, r);
+        return paintMediaMuteButton(box, paintInfo, integralSnappedRect);
     case MediaSeekBackButtonPart:
-        return paintMediaSeekBackButton(o, paintInfo, r);
+        return paintMediaSeekBackButton(box, paintInfo, integralSnappedRect);
     case MediaSeekForwardButtonPart:
-        return paintMediaSeekForwardButton(o, paintInfo, r);
+        return paintMediaSeekForwardButton(box, paintInfo, integralSnappedRect);
     case MediaRewindButtonPart:
-        return paintMediaRewindButton(o, paintInfo, r);
+        return paintMediaRewindButton(box, paintInfo, integralSnappedRect);
     case MediaReturnToRealtimeButtonPart:
-        return paintMediaReturnToRealtimeButton(o, paintInfo, r);
+        return paintMediaReturnToRealtimeButton(box, paintInfo, integralSnappedRect);
     case MediaToggleClosedCaptionsButtonPart:
-        return paintMediaToggleClosedCaptionsButton(o, paintInfo, r);
+        return paintMediaToggleClosedCaptionsButton(box, paintInfo, integralSnappedRect);
     case MediaSliderPart:
-        return paintMediaSliderTrack(o, paintInfo, r);
+        return paintMediaSliderTrack(box, paintInfo, integralSnappedRect);
     case MediaSliderThumbPart:
-        return paintMediaSliderThumb(o, paintInfo, r);
+        return paintMediaSliderThumb(box, paintInfo, integralSnappedRect);
     case MediaVolumeSliderMuteButtonPart:
-        return paintMediaMuteButton(o, paintInfo, r);
+        return paintMediaMuteButton(box, paintInfo, integralSnappedRect);
     case MediaVolumeSliderContainerPart:
-        return paintMediaVolumeSliderContainer(o, paintInfo, r);
+        return paintMediaVolumeSliderContainer(box, paintInfo, integralSnappedRect);
     case MediaVolumeSliderPart:
-        return paintMediaVolumeSliderTrack(o, paintInfo, r);
+        return paintMediaVolumeSliderTrack(box, paintInfo, integralSnappedRect);
     case MediaVolumeSliderThumbPart:
-        return paintMediaVolumeSliderThumb(o, paintInfo, r);
+        return paintMediaVolumeSliderThumb(box, paintInfo, integralSnappedRect);
     case MediaFullScreenVolumeSliderPart:
-        return paintMediaFullScreenVolumeSliderTrack(o, paintInfo, r);
+        return paintMediaFullScreenVolumeSliderTrack(box, paintInfo, integralSnappedRect);
     case MediaFullScreenVolumeSliderThumbPart:
-        return paintMediaFullScreenVolumeSliderThumb(o, paintInfo, r);
+        return paintMediaFullScreenVolumeSliderThumb(box, paintInfo, integralSnappedRect);
     case MediaTimeRemainingPart:
-        return paintMediaTimeRemaining(o, paintInfo, r);
+        return paintMediaTimeRemaining(box, paintInfo, integralSnappedRect);
     case MediaCurrentTimePart:
-        return paintMediaCurrentTime(o, paintInfo, r);
+        return paintMediaCurrentTime(box, paintInfo, integralSnappedRect);
     case MediaControlsBackgroundPart:
-        return paintMediaControlsBackground(o, paintInfo, r);
+        return paintMediaControlsBackground(box, paintInfo, integralSnappedRect);
     case MenulistButtonPart:
     case TextFieldPart:
     case TextAreaPart:
     case ListboxPart:
         return true;
     case SearchFieldPart:
-        return paintSearchField(o, paintInfo, r);
+        return paintSearchField(box, paintInfo, integralSnappedRect);
     case SearchFieldCancelButtonPart:
-        return paintSearchFieldCancelButton(o, paintInfo, r);
+        return paintSearchFieldCancelButton(box, paintInfo, integralSnappedRect);
     case SearchFieldDecorationPart:
-        return paintSearchFieldDecorationPart(o, paintInfo, r);
+        return paintSearchFieldDecorationPart(box, paintInfo, integralSnappedRect);
     case SearchFieldResultsDecorationPart:
-        return paintSearchFieldResultsDecorationPart(o, paintInfo, r);
+        return paintSearchFieldResultsDecorationPart(box, paintInfo, integralSnappedRect);
     case SearchFieldResultsButtonPart:
-        return paintSearchFieldResultsButton(o, paintInfo, r);
+        return paintSearchFieldResultsButton(box, paintInfo, integralSnappedRect);
     case SnapshottedPluginOverlayPart:
-        return paintSnapshottedPluginOverlay(o, paintInfo, r);
-#if ENABLE(INPUT_SPEECH)
-    case InputSpeechButtonPart:
-        return paintInputFieldSpeechButton(o, paintInfo, r);
-#endif
-#if ENABLE(IMAGE_CONTROLS)
+        return paintSnapshottedPluginOverlay(box, paintInfo, integralSnappedRect);
+#if ENABLE(SERVICE_CONTROLS)
     case ImageControlsButtonPart:
-        return paintImageControlsButton(o, paintInfo, r);
+        return paintImageControlsButton(box, paintInfo, integralSnappedRect);
+#endif
+    case CapsLockIndicatorPart:
+        return paintCapsLockIndicator(box, paintInfo, integralSnappedRect);
+#if ENABLE(APPLE_PAY)
+    case ApplePayButtonPart:
+        return paintApplePayButton(box, paintInfo, integralSnappedRect);
+#endif
+#if ENABLE(ATTACHMENT_ELEMENT)
+    case AttachmentPart:
+        return paintAttachment(box, paintInfo, integralSnappedRect);
 #endif
     default:
         break;
@@ -401,22 +420,23 @@ bool RenderTheme::paint(RenderObject* o, const PaintInfo& paintInfo, const IntRe
     return true; // We don't support the appearance, so let the normal background/border paint.
 }
 
-bool RenderTheme::paintBorderOnly(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
+bool RenderTheme::paintBorderOnly(const RenderBox& box, const PaintInfo& paintInfo, const LayoutRect& rect)
 {
-    if (paintInfo.context->paintingDisabled())
+    if (paintInfo.context().paintingDisabled())
         return false;
 
 #if PLATFORM(IOS)
-    UNUSED_PARAM(r);
-    return o->style().appearance() != NoControlPart;
+    UNUSED_PARAM(rect);
+    return box.style().appearance() != NoControlPart;
 #else
+    FloatRect devicePixelSnappedRect = snapRectToDevicePixels(rect, box.document().deviceScaleFactor());
     // Call the appropriate paint method based off the appearance value.
-    switch (o->style().appearance()) {
+    switch (box.style().appearance()) {
     case TextFieldPart:
-        return paintTextField(o, paintInfo, r);
+        return paintTextField(box, paintInfo, devicePixelSnappedRect);
     case ListboxPart:
     case TextAreaPart:
-        return paintTextArea(o, paintInfo, r);
+        return paintTextArea(box, paintInfo, devicePixelSnappedRect);
     case MenulistButtonPart:
     case SearchFieldPart:
         return true;
@@ -434,9 +454,7 @@ bool RenderTheme::paintBorderOnly(RenderObject* o, const PaintInfo& paintInfo, c
     case DiscreteCapacityLevelIndicatorPart:
     case RatingLevelIndicatorPart:
 #endif
-#if ENABLE(PROGRESS_ELEMENT)
     case ProgressBarPart:
-#endif
     case SliderHorizontalPart:
     case SliderVerticalPart:
     case SliderThumbHorizontalPart:
@@ -445,10 +463,7 @@ bool RenderTheme::paintBorderOnly(RenderObject* o, const PaintInfo& paintInfo, c
     case SearchFieldDecorationPart:
     case SearchFieldResultsDecorationPart:
     case SearchFieldResultsButtonPart:
-#if ENABLE(INPUT_SPEECH)
-    case InputSpeechButtonPart:
-#endif
-#if ENABLE(IMAGE_CONTROLS)
+#if ENABLE(SERVICE_CONTROLS)
     case ImageControlsButtonPart:
 #endif
     default:
@@ -459,36 +474,39 @@ bool RenderTheme::paintBorderOnly(RenderObject* o, const PaintInfo& paintInfo, c
 #endif
 }
 
-bool RenderTheme::paintDecorations(RenderObject* renderer, const PaintInfo& paintInfo, const IntRect& rect)
+bool RenderTheme::paintDecorations(const RenderBox& box, const PaintInfo& paintInfo, const LayoutRect& rect)
 {
-    if (paintInfo.context->paintingDisabled())
+    if (paintInfo.context().paintingDisabled())
         return false;
 
+    IntRect integralSnappedRect = snappedIntRect(rect);
+    FloatRect devicePixelSnappedRect = snapRectToDevicePixels(rect, box.document().deviceScaleFactor());
+
     // Call the appropriate paint method based off the appearance value.
-    switch (renderer->style().appearance()) {
+    switch (box.style().appearance()) {
     case MenulistButtonPart:
-        return paintMenuListButtonDecorations(renderer, paintInfo, rect);
+        return paintMenuListButtonDecorations(box, paintInfo, devicePixelSnappedRect);
     case TextFieldPart:
-        return paintTextFieldDecorations(renderer, paintInfo, rect);
+        return paintTextFieldDecorations(box, paintInfo, devicePixelSnappedRect);
     case TextAreaPart:
-        return paintTextAreaDecorations(renderer, paintInfo, rect);
+        return paintTextAreaDecorations(box, paintInfo, devicePixelSnappedRect);
     case CheckboxPart:
-        return paintCheckboxDecorations(renderer, paintInfo, rect);
+        return paintCheckboxDecorations(box, paintInfo, integralSnappedRect);
     case RadioPart:
-        return paintRadioDecorations(renderer, paintInfo, rect);
+        return paintRadioDecorations(box, paintInfo, integralSnappedRect);
     case PushButtonPart:
-        return paintPushButtonDecorations(renderer, paintInfo, rect);
+        return paintPushButtonDecorations(box, paintInfo, integralSnappedRect);
     case SquareButtonPart:
-        return paintSquareButtonDecorations(renderer, paintInfo, rect);
+        return paintSquareButtonDecorations(box, paintInfo, integralSnappedRect);
     case ButtonPart:
-        return paintButtonDecorations(renderer, paintInfo, rect);
+        return paintButtonDecorations(box, paintInfo, integralSnappedRect);
     case MenulistPart:
-        return paintMenuListDecorations(renderer, paintInfo, rect);
+        return paintMenuListDecorations(box, paintInfo, integralSnappedRect);
     case SliderThumbHorizontalPart:
     case SliderThumbVerticalPart:
-        return paintSliderThumbDecorations(renderer, paintInfo, rect);
+        return paintSliderThumbDecorations(box, paintInfo, integralSnappedRect);
     case SearchFieldPart:
-        return paintSearchFieldDecorations(renderer, paintInfo, rect);
+        return paintSearchFieldDecorations(box, paintInfo, integralSnappedRect);
 #if ENABLE(METER_ELEMENT)
     case MeterPart:
     case RelevancyLevelIndicatorPart:
@@ -496,9 +514,7 @@ bool RenderTheme::paintDecorations(RenderObject* renderer, const PaintInfo& pain
     case DiscreteCapacityLevelIndicatorPart:
     case RatingLevelIndicatorPart:
 #endif
-#if ENABLE(PROGRESS_ELEMENT)
     case ProgressBarPart:
-#endif
     case SliderHorizontalPart:
     case SliderVerticalPart:
     case ListboxPart:
@@ -507,10 +523,7 @@ bool RenderTheme::paintDecorations(RenderObject* renderer, const PaintInfo& pain
     case SearchFieldDecorationPart:
     case SearchFieldResultsDecorationPart:
     case SearchFieldResultsButtonPart:
-#if ENABLE(INPUT_SPEECH)
-    case InputSpeechButtonPart:
-#endif
-#if ENABLE(IMAGE_CONTROLS)
+#if ENABLE(SERVICE_CONTROLS)
     case ImageControlsButtonPart:
 #endif
     default:
@@ -550,13 +563,13 @@ String RenderTheme::formatMediaControlsRemainingTime(float currentTime, float du
     return formatMediaControlsTime(currentTime - duration);
 }
 
-IntPoint RenderTheme::volumeSliderOffsetFromMuteButton(RenderBox* muteButtonBox, const IntSize& size) const
+LayoutPoint RenderTheme::volumeSliderOffsetFromMuteButton(const RenderBox& muteButtonBox, const LayoutSize& size) const
 {
-    int y = -size.height();
-    FloatPoint absPoint = muteButtonBox->localToAbsolute(FloatPoint(muteButtonBox->pixelSnappedOffsetLeft(), y), IsFixed | UseTransforms);
+    LayoutUnit y = -size.height();
+    FloatPoint absPoint = muteButtonBox.localToAbsolute(FloatPoint(muteButtonBox.offsetLeft(), y), IsFixed | UseTransforms);
     if (absPoint.y() < 0)
-        y = muteButtonBox->height();
-    return IntPoint(0, y);
+        y = muteButtonBox.height();
+    return LayoutPoint(0, y);
 }
 
 #endif
@@ -662,17 +675,12 @@ Color RenderTheme::platformInactiveListBoxSelectionForegroundColor() const
     return platformInactiveSelectionForegroundColor();
 }
 
-int RenderTheme::baselinePosition(const RenderObject* o) const
+int RenderTheme::baselinePosition(const RenderBox& box) const
 {
-    if (!o->isBox())
-        return 0;
-
-    const RenderBox* box = toRenderBox(o);
-
 #if USE(NEW_THEME)
-    return box->height() + box->marginTop() + m_theme->baselinePositionAdjustment(o->style().appearance()) * o->style().effectiveZoom();
+    return box.height() + box.marginTop() + m_theme->baselinePositionAdjustment(box.style().appearance()) * box.style().effectiveZoom();
 #else
-    return box->height() + box->marginTop();
+    return box.height() + box.marginTop();
 #endif
 }
 
@@ -683,9 +691,9 @@ bool RenderTheme::isControlContainer(ControlPart appearance) const
     return appearance != CheckboxPart && appearance != RadioPart;
 }
 
-bool RenderTheme::isControlStyled(const RenderStyle* style, const BorderData& border, const FillLayer& background, const Color& backgroundColor) const
+bool RenderTheme::isControlStyled(const RenderStyle& style, const BorderData& border, const FillLayer& background, const Color& backgroundColor) const
 {
-    switch (style->appearance()) {
+    switch (style.appearance()) {
     case PushButtonPart:
     case SquareButtonPart:
     case DefaultButtonPart:
@@ -702,196 +710,178 @@ bool RenderTheme::isControlStyled(const RenderStyle* style, const BorderData& bo
     case TextFieldPart:
     case TextAreaPart:
         // Test the style to see if the UA border and background match.
-        return (style->border() != border
-            || *style->backgroundLayers() != background
-            || style->visitedDependentColor(CSSPropertyBackgroundColor) != backgroundColor);
+        return (style.border() != border
+            || *style.backgroundLayers() != background
+            || !style.backgroundColorEqualsToColorIgnoringVisited(backgroundColor));
     default:
         return false;
     }
 }
 
-void RenderTheme::adjustRepaintRect(const RenderObject* o, IntRect& r)
+void RenderTheme::adjustRepaintRect(const RenderObject& renderer, FloatRect& rect)
 {
 #if USE(NEW_THEME)
-    m_theme->inflateControlPaintRect(o->style().appearance(), controlStatesForRenderer(o), r, o->style().effectiveZoom());
+    ControlStates states(extractControlStatesForRenderer(renderer));
+    m_theme->inflateControlPaintRect(renderer.style().appearance(), states, rect, renderer.style().effectiveZoom());
 #else
-    UNUSED_PARAM(o);
-    UNUSED_PARAM(r);
+    UNUSED_PARAM(renderer);
+    UNUSED_PARAM(rect);
 #endif
 }
 
-bool RenderTheme::supportsFocusRing(const RenderStyle* style) const
+bool RenderTheme::supportsFocusRing(const RenderStyle& style) const
 {
-    return (style->hasAppearance() && style->appearance() != TextFieldPart && style->appearance() != TextAreaPart && style->appearance() != MenulistButtonPart && style->appearance() != ListboxPart);
+    return (style.hasAppearance() && style.appearance() != TextFieldPart && style.appearance() != TextAreaPart && style.appearance() != MenulistButtonPart && style.appearance() != ListboxPart);
 }
 
-bool RenderTheme::stateChanged(RenderObject* o, ControlState state) const
+bool RenderTheme::stateChanged(const RenderObject& o, ControlStates::States state) const
 {
     // Default implementation assumes the controls don't respond to changes in :hover state
-    if (state == HoverState && !supportsHover(&o->style()))
+    if (state == ControlStates::HoverState && !supportsHover(o.style()))
         return false;
 
     // Assume pressed state is only responded to if the control is enabled.
-    if (state == PressedState && !isEnabled(o))
+    if (state == ControlStates::PressedState && !isEnabled(o))
         return false;
 
     // Repaint the control.
-    o->repaint();
+    o.repaint();
     return true;
 }
 
-ControlStates RenderTheme::controlStatesForRenderer(const RenderObject* o) const
+void RenderTheme::updateControlStatesForRenderer(const RenderBox& box, ControlStates& controlStates) const
+{
+    ControlStates newStates = extractControlStatesForRenderer(box);
+    controlStates.setStates(newStates.states());
+    if (isFocused(box))
+        controlStates.setTimeSinceControlWasFocused(box.document().page()->focusController().timeSinceFocusWasSet());
+}
+
+ControlStates::States RenderTheme::extractControlStatesForRenderer(const RenderObject& o) const
 {
-    ControlStates result = 0;
+    ControlStates::States states = 0;
     if (isHovered(o)) {
-        result |= HoverState;
+        states |= ControlStates::HoverState;
         if (isSpinUpButtonPartHovered(o))
-            result |= SpinUpState;
+            states |= ControlStates::SpinUpState;
     }
     if (isPressed(o)) {
-        result |= PressedState;
+        states |= ControlStates::PressedState;
         if (isSpinUpButtonPartPressed(o))
-            result |= SpinUpState;
+            states |= ControlStates::SpinUpState;
     }
-    if (isFocused(o) && o->style().outlineStyleIsAuto())
-        result |= FocusState;
+    if (isFocused(o) && o.style().outlineStyleIsAuto())
+        states |= ControlStates::FocusState;
     if (isEnabled(o))
-        result |= EnabledState;
+        states |= ControlStates::EnabledState;
     if (isChecked(o))
-        result |= CheckedState;
-    if (isReadOnlyControl(o))
-        result |= ReadOnlyState;
+        states |= ControlStates::CheckedState;
     if (isDefault(o))
-        result |= DefaultState;
+        states |= ControlStates::DefaultState;
     if (!isActive(o))
-        result |= WindowInactiveState;
+        states |= ControlStates::WindowInactiveState;
     if (isIndeterminate(o))
-        result |= IndeterminateState;
-    return result;
+        states |= ControlStates::IndeterminateState;
+    return states;
 }
 
-bool RenderTheme::isActive(const RenderObject* o) const
+bool RenderTheme::isActive(const RenderObject& o) const
 {
-    Node* node = o->node();
-    if (!node)
-        return false;
-
-    Frame* frame = node->document().frame();
-    if (!frame)
-        return false;
-
-    Page* page = frame->page();
+    Page* page = o.document().page();
     if (!page)
         return false;
 
     return page->focusController().isActive();
 }
 
-bool RenderTheme::isChecked(const RenderObject* o) const
+bool RenderTheme::isChecked(const RenderObject& o) const
 {
-    if (!o->node())
-        return false;
-
-    HTMLInputElement* inputElement = o->node()->toInputElement();
-    if (!inputElement)
-        return false;
-
-    return inputElement->shouldAppearChecked();
+    return is<HTMLInputElement>(o.node()) && downcast<HTMLInputElement>(*o.node()).shouldAppearChecked();
 }
 
-bool RenderTheme::isIndeterminate(const RenderObject* o) const
+bool RenderTheme::isIndeterminate(const RenderObject& o) const
 {
-    if (!o->node())
-        return false;
-
-    HTMLInputElement* inputElement = o->node()->toInputElement();
-    if (!inputElement)
-        return false;
-
-    return inputElement->shouldAppearIndeterminate();
+    return is<HTMLInputElement>(o.node()) && downcast<HTMLInputElement>(*o.node()).shouldAppearIndeterminate();
 }
 
-bool RenderTheme::isEnabled(const RenderObject* o) const
+bool RenderTheme::isEnabled(const RenderObject& renderer) const
 {
-    Node* node = o->node();
-    if (!node || !node->isElementNode())
+    Node* node = renderer.node();
+    if (!is<Element>(node))
         return true;
-    return !toElement(node)->isDisabledFormControl();
+    return !downcast<Element>(*node).isDisabledFormControl();
 }
 
-bool RenderTheme::isFocused(const RenderObject* o) const
+bool RenderTheme::isFocused(const RenderObject& renderer) const
 {
-    Node* node = o->node();
-    if (!node || !node->isElementNode())
+    Node* node = renderer.node();
+    if (!is<Element>(node))
         return false;
 
-    Element* focusDelegate = toElement(node)->focusDelegate();
+    Element* focusDelegate = downcast<Element>(*node).focusDelegate();
     Document& document = focusDelegate->document();
     Frame* frame = document.frame();
     return focusDelegate == document.focusedElement() && frame && frame->selection().isFocusedAndActive();
 }
 
-bool RenderTheme::isPressed(const RenderObject* o) const
+bool RenderTheme::isPressed(const RenderObject& renderer) const
 {
-    if (!o->node() || !o->node()->isElementNode())
+    if (!is<Element>(renderer.node()))
         return false;
-    return toElement(o->node())->active();
+    return downcast<Element>(*renderer.node()).active();
 }
 
-bool RenderTheme::isSpinUpButtonPartPressed(const RenderObject* o) const
+bool RenderTheme::isSpinUpButtonPartPressed(const RenderObject& renderer) const
 {
-    Node* node = o->node();
-    if (!node || !node->isElementNode())
+    Node* node = renderer.node();
+    if (!is<Element>(node))
         return false;
-    Element* element = toElement(node);
-    if (!element->active() || !element->isSpinButtonElement())
+    Element& element = downcast<Element>(*node);
+    if (!element.active() || !is<SpinButtonElement>(element))
         return false;
-    return static_cast<SpinButtonElement*>(element)->upDownState() == SpinButtonElement::Up;
+    return downcast<SpinButtonElement>(element).upDownState() == SpinButtonElement::Up;
 }
 
-bool RenderTheme::isReadOnlyControl(const RenderObject* o) const
+bool RenderTheme::isReadOnlyControl(const RenderObject& renderer) const
 {
-    Node* node = o->node();
-    if (!node || !node->isElementNode())
+    Node* node = renderer.node();
+    if (!is<HTMLFormControlElement>(node))
         return false;
-    return toElement(node)->matchesReadOnlyPseudoClass();
+    return !downcast<Element>(*node).matchesReadWritePseudoClass();
 }
 
-bool RenderTheme::isHovered(const RenderObject* o) const
+bool RenderTheme::isHovered(const RenderObject& renderer) const
 {
-    Node* node = o->node();
-    if (!node || !node->isElementNode())
+    Node* node = renderer.node();
+    if (!is<Element>(node))
         return false;
-    if (!toElement(node)->isSpinButtonElement())
-        return toElement(node)->hovered();
-    SpinButtonElement* element = static_cast<SpinButtonElement*>(node);
-    return element->hovered() && element->upDownState() != SpinButtonElement::Indeterminate;
+    Element& element = downcast<Element>(*node);
+    if (!is<SpinButtonElement>(element))
+        return element.hovered();
+    SpinButtonElement& spinButton = downcast<SpinButtonElement>(element);
+    return spinButton.hovered() && spinButton.upDownState() != SpinButtonElement::Indeterminate;
 }
 
-bool RenderTheme::isSpinUpButtonPartHovered(const RenderObject* o) const
+bool RenderTheme::isSpinUpButtonPartHovered(const RenderObject& renderer) const
 {
-    Node* node = o->node();
-    if (!node || !node->isElementNode() || !toElement(node)->isSpinButtonElement())
+    Node* node = renderer.node();
+    if (!is<SpinButtonElement>(node))
         return false;
-    SpinButtonElement* element = static_cast<SpinButtonElement*>(node);
-    return element->upDownState() == SpinButtonElement::Up;
+    return downcast<SpinButtonElement>(*node).upDownState() == SpinButtonElement::Up;
 }
 
-bool RenderTheme::isDefault(const RenderObject* o) const
+bool RenderTheme::isDefault(const RenderObject& o) const
 {
     // A button should only have the default appearance if the page is active
     if (!isActive(o))
         return false;
 
-    if (!o->frame().settings().applicationChromeMode())
-        return false;
-    
-    return o->style().appearance() == DefaultButtonPart;
+    return o.style().appearance() == DefaultButtonPart;
 }
 
 #if !USE(NEW_THEME)
 
-void RenderTheme::adjustCheckboxStyle(StyleResolver*, RenderStyle* style, Element*) const
+void RenderTheme::adjustCheckboxStyle(StyleResolver&, RenderStyle& style, const Element*) const
 {
     // A summary of the rules for checkbox designed to match WinIE:
     // width/height - honored (WinIE actually scales its control for small widths, but lets it overflow for small heights.)
@@ -899,16 +889,16 @@ void RenderTheme::adjustCheckboxStyle(StyleResolver*, RenderStyle* style, Elemen
     setCheckboxSize(style);
 
     // padding - not honored by WinIE, needs to be removed.
-    style->resetPadding();
+    style.resetPadding();
 
     // border - honored by WinIE, but looks terrible (just paints in the control box and turns off the Windows XP theme)
     // for now, we will not honor it.
-    style->resetBorder();
+    style.resetBorder();
 
-    style->setBoxShadow(nullptr);
+    style.setBoxShadow(nullptr);
 }
 
-void RenderTheme::adjustRadioStyle(StyleResolver*, RenderStyle* style, Element*) const
+void RenderTheme::adjustRadioStyle(StyleResolver&, RenderStyle& style, const Element*) const
 {
     // A summary of the rules for checkbox designed to match WinIE:
     // width/height - honored (WinIE actually scales its control for small widths, but lets it overflow for small heights.)
@@ -916,16 +906,16 @@ void RenderTheme::adjustRadioStyle(StyleResolver*, RenderStyle* style, Element*)
     setRadioSize(style);
 
     // padding - not honored by WinIE, needs to be removed.
-    style->resetPadding();
+    style.resetPadding();
 
     // border - honored by WinIE, but looks terrible (just paints in the control box and turns off the Windows XP theme)
     // for now, we will not honor it.
-    style->resetBorder();
+    style.resetBorder();
 
-    style->setBoxShadow(nullptr);
+    style.setBoxShadow(nullptr);
 }
 
-void RenderTheme::adjustButtonStyle(StyleResolver*, RenderStyle* style, Element*) const
+void RenderTheme::adjustButtonStyle(StyleResolver&, RenderStyle& style, const Element*) const
 {
     // Most platforms will completely honor all CSS, and so we have no need to
     // adjust the style at all by default. We will still allow the theme a crack
@@ -933,56 +923,63 @@ void RenderTheme::adjustButtonStyle(StyleResolver*, RenderStyle* style, Element*
     setButtonSize(style);
 }
 
-void RenderTheme::adjustInnerSpinButtonStyle(StyleResolver*, RenderStyle*, Element*) const
+void RenderTheme::adjustInnerSpinButtonStyle(StyleResolver&, RenderStyle&, const Element*) const
 {
 }
 #endif
 
-void RenderTheme::adjustTextFieldStyle(StyleResolver*, RenderStyle*, Element*) const
+void RenderTheme::adjustTextFieldStyle(StyleResolver&, RenderStyle&, const Element*) const
 {
 }
 
-void RenderTheme::adjustTextAreaStyle(StyleResolver*, RenderStyle*, Element*) const
+void RenderTheme::adjustTextAreaStyle(StyleResolver&, RenderStyle&, const Element*) const
 {
 }
 
-void RenderTheme::adjustMenuListStyle(StyleResolver*, RenderStyle*, Element*) const
+void RenderTheme::adjustMenuListStyle(StyleResolver&, RenderStyle&, const Element*) const
 {
 }
 
-#if ENABLE(INPUT_SPEECH)
-void RenderTheme::adjustInputFieldSpeechButtonStyle(StyleResolver* styleResolver, RenderStyle* style, Element* element) const
+#if ENABLE(METER_ELEMENT)
+void RenderTheme::adjustMeterStyle(StyleResolver&, RenderStyle& style, const Element*) const
 {
-    RenderInputSpeech::adjustInputFieldSpeechButtonStyle(styleResolver, style, element);
+    style.setBoxShadow(nullptr);
 }
 
-bool RenderTheme::paintInputFieldSpeechButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
+IntSize RenderTheme::meterSizeForBounds(const RenderMeter&, const IntRect& bounds) const
 {
-    return RenderInputSpeech::paintInputFieldSpeechButton(object, paintInfo, rect);
+    return bounds.size();
 }
-#endif
 
-#if ENABLE(METER_ELEMENT)
-void RenderTheme::adjustMeterStyle(StyleResolver*, RenderStyle* style, Element*) const
+bool RenderTheme::supportsMeter(ControlPart) const
 {
-    style->setBoxShadow(nullptr);
+    return false;
 }
 
-IntSize RenderTheme::meterSizeForBounds(const RenderMeter*, const IntRect& bounds) const
+bool RenderTheme::paintMeter(const RenderObject&, const PaintInfo&, const IntRect&)
 {
-    return bounds.size();
+    return true;
 }
+#endif
 
-bool RenderTheme::supportsMeter(ControlPart) const
+void RenderTheme::adjustCapsLockIndicatorStyle(StyleResolver&, RenderStyle&, const Element*) const
+{
+}
+
+bool RenderTheme::paintCapsLockIndicator(const RenderObject&, const PaintInfo&, const IntRect&)
 {
     return false;
 }
 
-bool RenderTheme::paintMeter(RenderObject*, const PaintInfo&, const IntRect&)
+#if ENABLE(ATTACHMENT_ELEMENT)
+void RenderTheme::adjustAttachmentStyle(StyleResolver&, RenderStyle&, const Element*) const
 {
-    return true;
 }
 
+bool RenderTheme::paintAttachment(const RenderObject&, const PaintInfo&, const IntRect&)
+{
+    return false;
+}
 #endif
 
 #if ENABLE(DATALIST_ELEMENT)
@@ -991,30 +988,26 @@ LayoutUnit RenderTheme::sliderTickSnappingThreshold() const
     return 0;
 }
 
-void RenderTheme::paintSliderTicks(RenderObject* o, const PaintInfo& paintInfo, const IntRect& rect)
+void RenderTheme::paintSliderTicks(const RenderObject& o, const PaintInfo& paintInfo, const IntRect& rect)
 {
-    Node* node = o->node();
-    if (!node)
-        return;
-
-    HTMLInputElement* input = node->toInputElement();
-    if (!input)
+    if (!is<HTMLInputElement>(o.node()))
         return;
 
-    HTMLDataListElement* dataList = toHTMLDataListElement(input->list());
+    auto& input = downcast<HTMLInputElement>(*o.node());
+    auto* dataList = downcast<HTMLDataListElement>(input.list());
     if (!dataList)
         return;
 
-    double min = input->minimum();
-    double max = input->maximum();
-    ControlPart part = o->style().appearance();
+    double min = input.minimum();
+    double max = input.maximum();
+    ControlPart part = o.style().appearance();
     // We don't support ticks on alternate sliders like MediaVolumeSliders.
     if (part !=  SliderHorizontalPart && part != SliderVerticalPart)
         return;
     bool isHorizontal = part ==  SliderHorizontalPart;
 
     IntSize thumbSize;
-    RenderObject* thumbRenderer = input->sliderThumbElement()->renderer();
+    const RenderObject* thumbRenderer = input.sliderThumbElement()->renderer();
     if (thumbRenderer) {
         const RenderStyle& thumbStyle = thumbRenderer->style();
         int thumbWidth = thumbStyle.width().intValue();
@@ -1024,16 +1017,16 @@ void RenderTheme::paintSliderTicks(RenderObject* o, const PaintInfo& paintInfo,
     }
 
     IntSize tickSize = sliderTickSize();
-    float zoomFactor = o->style().effectiveZoom();
+    float zoomFactor = o.style().effectiveZoom();
     FloatRect tickRect;
     int tickRegionSideMargin = 0;
     int tickRegionWidth = 0;
     IntRect trackBounds;
-    RenderObject* trackRenderer = input->sliderTrackElement()->renderer();
+    RenderObject* trackRenderer = input.sliderTrackElement()->renderer();
     // We can ignoring transforms because transform is handled by the graphics context.
     if (trackRenderer)
         trackBounds = trackRenderer->absoluteBoundingBoxRectIgnoringTransforms();
-    IntRect sliderBounds = o->absoluteBoundingBoxRectIgnoringTransforms();
+    IntRect sliderBounds = o.absoluteBoundingBoxRectIgnoringTransforms();
 
     // Make position relative to the transformed ancestor element.
     trackBounds.setX(trackBounds.x() - sliderBounds.x() + rect.x());
@@ -1052,92 +1045,95 @@ void RenderTheme::paintSliderTicks(RenderObject* o, const PaintInfo& paintInfo,
         tickRegionSideMargin = trackBounds.y() + (thumbSize.width() - tickSize.width() * zoomFactor) / 2.0;
         tickRegionWidth = trackBounds.height() - thumbSize.width();
     }
-    RefPtr<HTMLCollection> options = dataList->options();
-    GraphicsContextStateSaver stateSaver(*paintInfo.context);
-    paintInfo.context->setFillColor(o->style().visitedDependentColor(CSSPropertyColor), ColorSpaceDeviceRGB);
+    Ref<HTMLCollection> options = dataList->options();
+    GraphicsContextStateSaver stateSaver(paintInfo.context());
+    paintInfo.context().setFillColor(o.style().visitedDependentColor(CSSPropertyColor));
     for (unsigned i = 0; Node* node = options->item(i); i++) {
-        ASSERT(isHTMLOptionElement(node));
-        HTMLOptionElement* optionElement = toHTMLOptionElement(node);
-        String value = optionElement->value();
-        if (!input->isValidValue(value))
+        ASSERT(is<HTMLOptionElement>(*node));
+        HTMLOptionElement& optionElement = downcast<HTMLOptionElement>(*node);
+        String value = optionElement.value();
+        if (!input.isValidValue(value))
             continue;
-        double parsedValue = parseToDoubleForNumberType(input->sanitizeValue(value));
+        double parsedValue = parseToDoubleForNumberType(input.sanitizeValue(value));
         double tickFraction = (parsedValue - min) / (max - min);
-        double tickRatio = isHorizontal && o->style().isLeftToRightDirection() ? tickFraction : 1.0 - tickFraction;
+        double tickRatio = isHorizontal && o.style().isLeftToRightDirection() ? tickFraction : 1.0 - tickFraction;
         double tickPosition = round(tickRegionSideMargin + tickRegionWidth * tickRatio);
         if (isHorizontal)
             tickRect.setX(tickPosition);
         else
             tickRect.setY(tickPosition);
-        paintInfo.context->fillRect(tickRect);
+        paintInfo.context().fillRect(tickRect);
     }
 }
 #endif
 
-#if ENABLE(PROGRESS_ELEMENT)
-double RenderTheme::animationRepeatIntervalForProgressBar(RenderProgress*) const
+double RenderTheme::animationRepeatIntervalForProgressBar(RenderProgress&) const
 {
     return 0;
 }
 
-double RenderTheme::animationDurationForProgressBar(RenderProgress*) const
+double RenderTheme::animationDurationForProgressBar(RenderProgress&) const
 {
     return 0;
 }
 
-void RenderTheme::adjustProgressBarStyle(StyleResolver*, RenderStyle*, Element*) const
+void RenderTheme::adjustProgressBarStyle(StyleResolver&, RenderStyle&, const Element*) const
 {
 }
 
-IntRect RenderTheme::progressBarRectForBounds(const RenderObject*, const IntRect& bounds) const
+IntRect RenderTheme::progressBarRectForBounds(const RenderObject&, const IntRect& bounds) const
 {
     return bounds;
 }
-#endif
 
-bool RenderTheme::shouldHaveSpinButton(HTMLInputElement* inputElement) const
+bool RenderTheme::shouldHaveSpinButton(const HTMLInputElement& inputElement) const
+{
+    return inputElement.isSteppable() && !inputElement.isRangeControl();
+}
+
+bool RenderTheme::shouldHaveCapsLockIndicator(const HTMLInputElement&) const
 {
-    return inputElement->isSteppable() && !inputElement->isRangeControl();
+    return false;
 }
 
-void RenderTheme::adjustMenuListButtonStyle(StyleResolver*, RenderStyle*, Element*) const
+void RenderTheme::adjustMenuListButtonStyle(StyleResolver&, RenderStyle&, const Element*) const
 {
 }
 
-void RenderTheme::adjustMediaControlStyle(StyleResolver*, RenderStyle*, Element*) const
+void RenderTheme::adjustMediaControlStyle(StyleResolver&, RenderStyle&, const Element*) const
 {
 }
 
-void RenderTheme::adjustSliderTrackStyle(StyleResolver*, RenderStyle*, Element*) const
+void RenderTheme::adjustSliderTrackStyle(StyleResolver&, RenderStyle&, const Element*) const
 {
 }
 
-void RenderTheme::adjustSliderThumbStyle(StyleResolver*, RenderStyle* style, Element* element) const
+void RenderTheme::adjustSliderThumbStyle(StyleResolver&, RenderStyle& style, const Element* element) const
 {
     adjustSliderThumbSize(style, element);
 }
 
-void RenderTheme::adjustSliderThumbSize(RenderStyle*, Element*) const
+void RenderTheme::adjustSliderThumbSize(RenderStyle&, const Element*) const
 {
 }
 
-void RenderTheme::adjustSearchFieldStyle(StyleResolver*, RenderStyle*, Element*) const
+void RenderTheme::adjustSearchFieldStyle(StyleResolver&, RenderStyle&, const Element*) const
 {
 }
 
-void RenderTheme::adjustSearchFieldCancelButtonStyle(StyleResolver*, RenderStyle*, Element*) const
+void RenderTheme::adjustSearchFieldCancelButtonStyle(StyleResolver&, RenderStyle&, const Element*) const
 {
 }
 
-void RenderTheme::adjustSearchFieldDecorationPartStyle(StyleResolver*, RenderStyle*, Element*) const
+void RenderTheme::adjustSearchFieldDecorationPartStyle(StyleResolver&, RenderStyle&, const Element*) const
 {
 }
 
-void RenderTheme::adjustSearchFieldResultsDecorationPartStyle(StyleResolver*, RenderStyle*, Element*) const
+void RenderTheme::adjustSearchFieldResultsDecorationPartStyle(StyleResolver&, RenderStyle&, const Element*) const
 {
 }
 
-void RenderTheme::adjustSearchFieldResultsButtonStyle(StyleResolver*, RenderStyle*, Element*) const
+void RenderTheme::adjustSearchFieldResultsButtonStyle(StyleResolver&, RenderStyle&, const Element*) const
 {
 }
 
@@ -1156,11 +1152,62 @@ void RenderTheme::platformColorsDidChange()
     Page::updateStyleForAllPagesAfterGlobalChangeInEnvironment();
 }
 
+FontCascadeDescription& RenderTheme::cachedSystemFontDescription(CSSValueID systemFontID) const
+{
+    static NeverDestroyed<FontCascadeDescription> caption;
+    static NeverDestroyed<FontCascadeDescription> icon;
+    static NeverDestroyed<FontCascadeDescription> menu;
+    static NeverDestroyed<FontCascadeDescription> messageBox;
+    static NeverDestroyed<FontCascadeDescription> smallCaption;
+    static NeverDestroyed<FontCascadeDescription> statusBar;
+    static NeverDestroyed<FontCascadeDescription> webkitMiniControl;
+    static NeverDestroyed<FontCascadeDescription> webkitSmallControl;
+    static NeverDestroyed<FontCascadeDescription> webkitControl;
+    static NeverDestroyed<FontCascadeDescription> defaultDescription;
+
+    switch (systemFontID) {
+    case CSSValueCaption:
+        return caption;
+    case CSSValueIcon:
+        return icon;
+    case CSSValueMenu:
+        return menu;
+    case CSSValueMessageBox:
+        return messageBox;
+    case CSSValueSmallCaption:
+        return smallCaption;
+    case CSSValueStatusBar:
+        return statusBar;
+    case CSSValueWebkitMiniControl:
+        return webkitMiniControl;
+    case CSSValueWebkitSmallControl:
+        return webkitSmallControl;
+    case CSSValueWebkitControl:
+        return webkitControl;
+    case CSSValueNone:
+        return defaultDescription;
+    default:
+        ASSERT_NOT_REACHED();
+        return defaultDescription;
+    }
+}
+
+void RenderTheme::systemFont(CSSValueID systemFontID, FontCascadeDescription& fontDescription) const
+{
+    fontDescription = cachedSystemFontDescription(systemFontID);
+    if (fontDescription.isAbsoluteSize())
+        return;
+
+    updateCachedSystemFontDescription(systemFontID, fontDescription);
+}
+
 Color RenderTheme::systemColor(CSSValueID cssValueId) const
 {
     switch (cssValueId) {
     case CSSValueActiveborder:
         return 0xFFFFFFFF;
+    case CSSValueActivebuttontext:
+        return 0xFF000000;
     case CSSValueActivecaption:
         return 0xFFCCCCCC;
     case CSSValueAppworkspace:
@@ -1281,7 +1328,7 @@ String RenderTheme::fileListDefaultLabel(bool multipleFilesAllowed) const
     return fileButtonNoFileSelectedLabel();
 }
 
-String RenderTheme::fileListNameForWidth(const FileList* fileList, const Font& font, int width, bool multipleFilesAllowed) const
+String RenderTheme::fileListNameForWidth(const FileList* fileList, const FontCascade& font, int width, bool multipleFilesAllowed) const
 {
     if (width <= 0)
         return String();
@@ -1292,9 +1339,19 @@ String RenderTheme::fileListNameForWidth(const FileList* fileList, const Font& f
     else if (fileList->length() == 1)
         string = fileList->item(0)->name();
     else
-        return StringTruncator::rightTruncate(multipleFileUploadText(fileList->length()), width, font, StringTruncator::EnableRoundingHacks);
+        return StringTruncator::rightTruncate(multipleFileUploadText(fileList->length()), width, font);
 
-    return StringTruncator::centerTruncate(string, width, font, StringTruncator::EnableRoundingHacks);
+    return StringTruncator::centerTruncate(string, width, font);
 }
 
+#if ENABLE(TOUCH_EVENTS)
+Color RenderTheme::platformTapHighlightColor() const
+{
+    // This color is expected to be drawn on a semi-transparent overlay,
+    // making it more transparent than its alpha value indicates.
+    static NeverDestroyed<const Color> defaultTapHighlightColor = Color(0, 0, 0, 102);
+    return defaultTapHighlightColor;
+}
+#endif
+
 } // namespace WebCore