diff options
Diffstat (limited to 'Source/WebCore/rendering/RenderTheme.cpp')
-rw-r--r-- | Source/WebCore/rendering/RenderTheme.cpp | 712 |
1 files changed, 389 insertions, 323 deletions
diff --git a/Source/WebCore/rendering/RenderTheme.cpp b/Source/WebCore/rendering/RenderTheme.cpp index 8595c32d0..c31a9aa6c 100644 --- a/Source/WebCore/rendering/RenderTheme.cpp +++ b/Source/WebCore/rendering/RenderTheme.cpp @@ -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" @@ -40,20 +42,16 @@ #include "PaintInfo.h" #include "RenderStyle.h" #include "RenderView.h" -#include "Settings.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 +67,7 @@ using namespace HTMLNames; static Color& customFocusRingColor() { - DEFINE_STATIC_LOCAL(Color, color, ()); + static NeverDestroyed<Color> color; return color; } @@ -80,7 +78,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(); @@ -89,10 +87,10 @@ void RenderTheme::adjustStyle(StyleResolver& styleResolver, RenderStyle& style, || style.display() == TABLE_ROW || style.display() == TABLE_COLUMN_GROUP || style.display() == TABLE_COLUMN || style.display() == TABLE_CELL || style.display() == TABLE_CAPTION) style.setDisplay(INLINE_BLOCK); - else if (style.display() == COMPACT || style.display() == RUN_IN || style.display() == LIST_ITEM || style.display() == TABLE) + 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 +115,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,9 +144,9 @@ 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); + style.setPaddingBox(WTFMove(paddingBox)); // Whitespace if (m_theme->controlRequiresPreWhiteSpace(part)) @@ -157,31 +155,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()); - if (controlSize.width() != style.width()) - style.setWidth(controlSize.width()); - if (controlSize.height() != style.height()) - style.setHeight(controlSize.height()); - + LengthSize controlSize = m_theme->controlSize(part, style.fontCascade(), { style.width(), style.height() }, style.effectiveZoom()); + if (controlSize.width != style.width()) + style.setWidth(WTFMove(controlSize.width)); + if (controlSize.height != style.height()) + style.setHeight(WTFMove(controlSize.height)); + // Min-Width / Min-Height - LengthSize minControlSize = m_theme->minimumControlSize(part, style.font(), style.effectiveZoom()); - if (minControlSize.width() != style.minWidth()) - style.setMinWidth(minControlSize.width()); - if (minControlSize.height() != style.minHeight()) - style.setMinHeight(minControlSize.height()); - + LengthSize minControlSize = m_theme->minimumControlSize(part, style.fontCascade(), style.effectiveZoom()); + if (minControlSize.width != style.minWidth()) + style.setMinWidth(WTFMove(minControlSize.width)); + if (minControlSize.height != style.minHeight()) + style.setMinHeight(WTFMove(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 +190,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,63 +216,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(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(INPUT_SPEECH) - case InputSpeechButtonPart: - return adjustInputFieldSpeechButtonStyle(&styleResolver, &style, e); +#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; - ControlPart part = o->style().appearance(); + if (UNLIKELY(paintInfo.context().isRecording())) + return false; + + 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.page().pageScaleFactor(); + switch (part) { case CheckboxPart: case RadioPart: @@ -282,109 +297,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); + return paintSnapshottedPluginOverlay(box, paintInfo, integralSnappedRect); +#if ENABLE(SERVICE_CONTROLS) + case ImageControlsButtonPart: + 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; @@ -393,22 +419,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; @@ -426,9 +453,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: @@ -437,8 +462,8 @@ bool RenderTheme::paintBorderOnly(RenderObject* o, const PaintInfo& paintInfo, c case SearchFieldDecorationPart: case SearchFieldResultsDecorationPart: case SearchFieldResultsButtonPart: -#if ENABLE(INPUT_SPEECH) - case InputSpeechButtonPart: +#if ENABLE(SERVICE_CONTROLS) + case ImageControlsButtonPart: #endif default: break; @@ -448,36 +473,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: @@ -485,9 +513,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: @@ -496,8 +522,8 @@ bool RenderTheme::paintDecorations(RenderObject* renderer, const PaintInfo& pain case SearchFieldDecorationPart: case SearchFieldResultsDecorationPart: case SearchFieldResultsButtonPart: -#if ENABLE(INPUT_SPEECH) - case InputSpeechButtonPart: +#if ENABLE(SERVICE_CONTROLS) + case ImageControlsButtonPart: #endif default: break; @@ -536,13 +562,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 @@ -648,17 +674,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 } @@ -669,9 +690,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: @@ -684,200 +705,178 @@ bool RenderTheme::isControlStyled(const RenderStyle* style, const BorderData& bo case ContinuousCapacityLevelIndicatorPart: case DiscreteCapacityLevelIndicatorPart: case RatingLevelIndicatorPart: - case SearchFieldPart: + // FIXME: SearchFieldPart should be included here when making search fields style-able. 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.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& renderer) const { - Node* node = o->node(); - if (!node) - return false; - - Frame* frame = node->document().frame(); - if (!frame) - return false; - - Page* page = frame->page(); - if (!page) - return false; - - return page->focusController().isActive(); + return renderer.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.) @@ -885,16 +884,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.) @@ -902,16 +901,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 @@ -919,56 +918,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) @@ -977,30 +983,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(); @@ -1010,16 +1012,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()); @@ -1038,92 +1040,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 { } @@ -1142,11 +1147,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: @@ -1229,14 +1285,14 @@ Color RenderTheme::tapHighlightColor() // Value chosen by observation. This can be tweaked. static const int minColorContrastValue = 1300; // For transparent or translucent background color, use lightening. -static const int minDisabledColorAlphaValue = 128; +static const float minDisabledColorAlphaValue = 0.5; Color RenderTheme::disabledTextColor(const Color& textColor, const Color& backgroundColor) const { // The explicit check for black is an optimization for the 99% case (black on white). // This also means that black on black will turn into grey on black when disabled. Color disabledColor; - if (textColor.rgb() == Color::black || backgroundColor.alpha() < minDisabledColorAlphaValue || differenceSquared(textColor, Color::white) > differenceSquared(backgroundColor, Color::white)) + if (Color::isBlackColor(textColor) || backgroundColor.alphaAsFloat() < minDisabledColorAlphaValue || differenceSquared(textColor, Color::white) > differenceSquared(backgroundColor, Color::white)) disabledColor = textColor.light(); else disabledColor = textColor.dark(); @@ -1267,7 +1323,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(); @@ -1278,9 +1334,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 |