Rename DEFINE_STATIC_LOCAL to DEPRECATED_DEFINE_STATIC_LOCAL
[WebKit-https.git] / Source / WebCore / rendering / RenderTheme.cpp
1 /**
2  * This file is part of the theme implementation for form controls in WebCore.
3  *
4  * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Computer, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB.  If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21
22 #include "config.h"
23 #include "RenderTheme.h"
24
25 #include "CSSValueKeywords.h"
26 #include "Document.h"
27 #include "FileList.h"
28 #include "FileSystem.h"
29 #include "FloatConversion.h"
30 #include "FocusController.h"
31 #include "FontSelector.h"
32 #include "Frame.h"
33 #include "FrameSelection.h"
34 #include "GraphicsContext.h"
35 #include "HTMLInputElement.h"
36 #include "HTMLNames.h"
37 #include "LocalizedStrings.h"
38 #include "MediaControlElements.h"
39 #include "Page.h"
40 #include "PaintInfo.h"
41 #include "RenderStyle.h"
42 #include "RenderView.h"
43 #include "Settings.h"
44 #include "SpinButtonElement.h"
45 #include "StringTruncator.h"
46 #include "TextControlInnerElements.h"
47
48 #if ENABLE(METER_ELEMENT)
49 #include "HTMLMeterElement.h"
50 #include "RenderMeter.h"
51 #endif
52
53 #if ENABLE(INPUT_SPEECH)
54 #include "RenderInputSpeech.h"
55 #endif
56
57 #if ENABLE(DATALIST_ELEMENT)
58 #include "HTMLCollection.h"
59 #include "HTMLDataListElement.h"
60 #include "HTMLOptionElement.h"
61 #include "HTMLParserIdioms.h"
62 #endif
63
64 // The methods in this file are shared by all themes on every platform.
65
66 namespace WebCore {
67
68 using namespace HTMLNames;
69
70 static Color& customFocusRingColor()
71 {
72     DEPRECATED_DEFINE_STATIC_LOCAL(Color, color, ());
73     return color;
74 }
75
76 RenderTheme::RenderTheme()
77 #if USE(NEW_THEME)
78     : m_theme(platformTheme())
79 #endif
80 {
81 }
82
83 void RenderTheme::adjustStyle(StyleResolver& styleResolver, RenderStyle& style, Element* e, bool UAHasAppearance, const BorderData& border, const FillLayer& background, const Color& backgroundColor)
84 {
85     // Force inline and table display styles to be inline-block (except for table- which is block)
86     ControlPart part = style.appearance();
87     if (style.display() == INLINE || style.display() == INLINE_TABLE || style.display() == TABLE_ROW_GROUP
88         || style.display() == TABLE_HEADER_GROUP || style.display() == TABLE_FOOTER_GROUP
89         || style.display() == TABLE_ROW || style.display() == TABLE_COLUMN_GROUP || style.display() == TABLE_COLUMN
90         || style.display() == TABLE_CELL || style.display() == TABLE_CAPTION)
91         style.setDisplay(INLINE_BLOCK);
92     else if (style.display() == COMPACT || style.display() == LIST_ITEM || style.display() == TABLE)
93         style.setDisplay(BLOCK);
94
95     if (UAHasAppearance && isControlStyled(&style, border, background, backgroundColor)) {
96         if (part == MenulistPart) {
97             style.setAppearance(MenulistButtonPart);
98             part = MenulistButtonPart;
99         } else
100             style.setAppearance(NoControlPart);
101     }
102
103     if (!style.hasAppearance())
104         return;
105
106     // Never support box-shadow on native controls.
107     style.setBoxShadow(nullptr);
108     
109 #if USE(NEW_THEME)
110     switch (part) {
111     case CheckboxPart:
112     case InnerSpinButtonPart:
113     case RadioPart:
114     case PushButtonPart:
115     case SquareButtonPart:
116     case DefaultButtonPart:
117     case ButtonPart: {
118         // Border
119         LengthBox borderBox(style.borderTopWidth(), style.borderRightWidth(), style.borderBottomWidth(), style.borderLeftWidth());
120         borderBox = m_theme->controlBorder(part, style.font(), borderBox, style.effectiveZoom());
121         if (borderBox.top().value() != static_cast<int>(style.borderTopWidth())) {
122             if (borderBox.top().value())
123                 style.setBorderTopWidth(borderBox.top().value());
124             else
125                 style.resetBorderTop();
126         }
127         if (borderBox.right().value() != static_cast<int>(style.borderRightWidth())) {
128             if (borderBox.right().value())
129                 style.setBorderRightWidth(borderBox.right().value());
130             else
131                 style.resetBorderRight();
132         }
133         if (borderBox.bottom().value() != static_cast<int>(style.borderBottomWidth())) {
134             style.setBorderBottomWidth(borderBox.bottom().value());
135             if (borderBox.bottom().value())
136                 style.setBorderBottomWidth(borderBox.bottom().value());
137             else
138                 style.resetBorderBottom();
139         }
140         if (borderBox.left().value() != static_cast<int>(style.borderLeftWidth())) {
141             style.setBorderLeftWidth(borderBox.left().value());
142             if (borderBox.left().value())
143                 style.setBorderLeftWidth(borderBox.left().value());
144             else
145                 style.resetBorderLeft();
146         }
147
148         // Padding
149         LengthBox paddingBox = m_theme->controlPadding(part, style.font(), style.paddingBox(), style.effectiveZoom());
150         if (paddingBox != style.paddingBox())
151             style.setPaddingBox(paddingBox);
152
153         // Whitespace
154         if (m_theme->controlRequiresPreWhiteSpace(part))
155             style.setWhiteSpace(PRE);
156             
157         // Width / Height
158         // The width and height here are affected by the zoom.
159         // FIXME: Check is flawed, since it doesn't take min-width/max-width into account.
160         LengthSize controlSize = m_theme->controlSize(part, style.font(), LengthSize(style.width(), style.height()), style.effectiveZoom());
161         if (controlSize.width() != style.width())
162             style.setWidth(controlSize.width());
163         if (controlSize.height() != style.height())
164             style.setHeight(controlSize.height());
165                 
166         // Min-Width / Min-Height
167         LengthSize minControlSize = m_theme->minimumControlSize(part, style.font(), style.effectiveZoom());
168         if (minControlSize.width() != style.minWidth())
169             style.setMinWidth(minControlSize.width());
170         if (minControlSize.height() != style.minHeight())
171             style.setMinHeight(minControlSize.height());
172                 
173         // Font
174         FontDescription controlFont = m_theme->controlFont(part, style.font(), style.effectiveZoom());
175         if (controlFont != style.font().fontDescription()) {
176             // Reset our line-height
177             style.setLineHeight(RenderStyle::initialLineHeight());
178
179             // Now update our font.
180             if (style.setFontDescription(controlFont))
181                 style.font().update(0);
182         }
183     }
184     break;
185     default:
186         break;
187     }
188 #endif
189
190     // Call the appropriate style adjustment method based off the appearance value.
191     switch (style.appearance()) {
192 #if !USE(NEW_THEME)
193     case CheckboxPart:
194         return adjustCheckboxStyle(&styleResolver, &style, e);
195     case RadioPart:
196         return adjustRadioStyle(&styleResolver, &style, e);
197     case PushButtonPart:
198     case SquareButtonPart:
199     case DefaultButtonPart:
200     case ButtonPart:
201         return adjustButtonStyle(&styleResolver, &style, e);
202     case InnerSpinButtonPart:
203         return adjustInnerSpinButtonStyle(&styleResolver, &style, e);
204 #endif
205     case TextFieldPart:
206         return adjustTextFieldStyle(&styleResolver, &style, e);
207     case TextAreaPart:
208         return adjustTextAreaStyle(&styleResolver, &style, e);
209     case MenulistPart:
210         return adjustMenuListStyle(&styleResolver, &style, e);
211     case MenulistButtonPart:
212         return adjustMenuListButtonStyle(&styleResolver, &style, e);
213     case MediaPlayButtonPart:
214     case MediaCurrentTimePart:
215     case MediaTimeRemainingPart:
216     case MediaEnterFullscreenButtonPart:
217     case MediaExitFullscreenButtonPart:
218     case MediaMuteButtonPart:
219     case MediaVolumeSliderContainerPart:
220         return adjustMediaControlStyle(&styleResolver, &style, e);
221     case MediaSliderPart:
222     case MediaVolumeSliderPart:
223     case MediaFullScreenVolumeSliderPart:
224     case SliderHorizontalPart:
225     case SliderVerticalPart:
226         return adjustSliderTrackStyle(&styleResolver, &style, e);
227     case SliderThumbHorizontalPart:
228     case SliderThumbVerticalPart:
229         return adjustSliderThumbStyle(&styleResolver, &style, e);
230     case SearchFieldPart:
231         return adjustSearchFieldStyle(&styleResolver, &style, e);
232     case SearchFieldCancelButtonPart:
233         return adjustSearchFieldCancelButtonStyle(&styleResolver, &style, e);
234     case SearchFieldDecorationPart:
235         return adjustSearchFieldDecorationPartStyle(&styleResolver, &style, e);
236     case SearchFieldResultsDecorationPart:
237         return adjustSearchFieldResultsDecorationPartStyle(&styleResolver, &style, e);
238     case SearchFieldResultsButtonPart:
239         return adjustSearchFieldResultsButtonStyle(&styleResolver, &style, e);
240 #if ENABLE(PROGRESS_ELEMENT)
241     case ProgressBarPart:
242         return adjustProgressBarStyle(&styleResolver, &style, e);
243 #endif
244 #if ENABLE(METER_ELEMENT)
245     case MeterPart:
246     case RelevancyLevelIndicatorPart:
247     case ContinuousCapacityLevelIndicatorPart:
248     case DiscreteCapacityLevelIndicatorPart:
249     case RatingLevelIndicatorPart:
250         return adjustMeterStyle(&styleResolver, &style, e);
251 #endif
252 #if ENABLE(INPUT_SPEECH)
253     case InputSpeechButtonPart:
254         return adjustInputFieldSpeechButtonStyle(&styleResolver, &style, e);
255 #endif
256 #if ENABLE(IMAGE_CONTROLS)
257     case ImageControlsButtonPart:
258         break;
259 #endif
260     default:
261         break;
262     }
263 }
264
265 bool RenderTheme::paint(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
266 {
267     // If painting is disabled, but we aren't updating control tints, then just bail.
268     // If we are updating control tints, just schedule a repaint if the theme supports tinting
269     // for that control.
270     if (paintInfo.context->updatingControlTints()) {
271         if (controlSupportsTints(o))
272             o->repaint();
273         return false;
274     }
275     if (paintInfo.context->paintingDisabled())
276         return false;
277
278     ControlPart part = o->style().appearance();
279
280 #if USE(NEW_THEME)
281     switch (part) {
282     case CheckboxPart:
283     case RadioPart:
284     case PushButtonPart:
285     case SquareButtonPart:
286     case DefaultButtonPart:
287     case ButtonPart:
288     case InnerSpinButtonPart:
289         m_theme->paint(part, controlStatesForRenderer(o), const_cast<GraphicsContext*>(paintInfo.context), r, o->style().effectiveZoom(), &o->view().frameView());
290         return false;
291     default:
292         break;
293     }
294 #endif
295
296     // Call the appropriate paint method based off the appearance value.
297     switch (part) {
298 #if !USE(NEW_THEME)
299     case CheckboxPart:
300         return paintCheckbox(o, paintInfo, r);
301     case RadioPart:
302         return paintRadio(o, paintInfo, r);
303     case PushButtonPart:
304     case SquareButtonPart:
305     case DefaultButtonPart:
306     case ButtonPart:
307         return paintButton(o, paintInfo, r);
308     case InnerSpinButtonPart:
309         return paintInnerSpinButton(o, paintInfo, r);
310 #endif
311     case MenulistPart:
312         return paintMenuList(o, paintInfo, r);
313 #if ENABLE(METER_ELEMENT)
314     case MeterPart:
315     case RelevancyLevelIndicatorPart:
316     case ContinuousCapacityLevelIndicatorPart:
317     case DiscreteCapacityLevelIndicatorPart:
318     case RatingLevelIndicatorPart:
319         return paintMeter(o, paintInfo, r);
320 #endif
321 #if ENABLE(PROGRESS_ELEMENT)
322     case ProgressBarPart:
323         return paintProgressBar(o, paintInfo, r);
324 #endif
325     case SliderHorizontalPart:
326     case SliderVerticalPart:
327         return paintSliderTrack(o, paintInfo, r);
328     case SliderThumbHorizontalPart:
329     case SliderThumbVerticalPart:
330         return paintSliderThumb(o, paintInfo, r);
331     case MediaEnterFullscreenButtonPart:
332     case MediaExitFullscreenButtonPart:
333         return paintMediaFullscreenButton(o, paintInfo, r);
334     case MediaPlayButtonPart:
335         return paintMediaPlayButton(o, paintInfo, r);
336     case MediaOverlayPlayButtonPart:
337         return paintMediaOverlayPlayButton(o, paintInfo, r);
338     case MediaMuteButtonPart:
339         return paintMediaMuteButton(o, paintInfo, r);
340     case MediaSeekBackButtonPart:
341         return paintMediaSeekBackButton(o, paintInfo, r);
342     case MediaSeekForwardButtonPart:
343         return paintMediaSeekForwardButton(o, paintInfo, r);
344     case MediaRewindButtonPart:
345         return paintMediaRewindButton(o, paintInfo, r);
346     case MediaReturnToRealtimeButtonPart:
347         return paintMediaReturnToRealtimeButton(o, paintInfo, r);
348     case MediaToggleClosedCaptionsButtonPart:
349         return paintMediaToggleClosedCaptionsButton(o, paintInfo, r);
350     case MediaSliderPart:
351         return paintMediaSliderTrack(o, paintInfo, r);
352     case MediaSliderThumbPart:
353         return paintMediaSliderThumb(o, paintInfo, r);
354     case MediaVolumeSliderMuteButtonPart:
355         return paintMediaMuteButton(o, paintInfo, r);
356     case MediaVolumeSliderContainerPart:
357         return paintMediaVolumeSliderContainer(o, paintInfo, r);
358     case MediaVolumeSliderPart:
359         return paintMediaVolumeSliderTrack(o, paintInfo, r);
360     case MediaVolumeSliderThumbPart:
361         return paintMediaVolumeSliderThumb(o, paintInfo, r);
362     case MediaFullScreenVolumeSliderPart:
363         return paintMediaFullScreenVolumeSliderTrack(o, paintInfo, r);
364     case MediaFullScreenVolumeSliderThumbPart:
365         return paintMediaFullScreenVolumeSliderThumb(o, paintInfo, r);
366     case MediaTimeRemainingPart:
367         return paintMediaTimeRemaining(o, paintInfo, r);
368     case MediaCurrentTimePart:
369         return paintMediaCurrentTime(o, paintInfo, r);
370     case MediaControlsBackgroundPart:
371         return paintMediaControlsBackground(o, paintInfo, r);
372     case MenulistButtonPart:
373     case TextFieldPart:
374     case TextAreaPart:
375     case ListboxPart:
376         return true;
377     case SearchFieldPart:
378         return paintSearchField(o, paintInfo, r);
379     case SearchFieldCancelButtonPart:
380         return paintSearchFieldCancelButton(o, paintInfo, r);
381     case SearchFieldDecorationPart:
382         return paintSearchFieldDecorationPart(o, paintInfo, r);
383     case SearchFieldResultsDecorationPart:
384         return paintSearchFieldResultsDecorationPart(o, paintInfo, r);
385     case SearchFieldResultsButtonPart:
386         return paintSearchFieldResultsButton(o, paintInfo, r);
387     case SnapshottedPluginOverlayPart:
388         return paintSnapshottedPluginOverlay(o, paintInfo, r);
389 #if ENABLE(INPUT_SPEECH)
390     case InputSpeechButtonPart:
391         return paintInputFieldSpeechButton(o, paintInfo, r);
392 #endif
393 #if ENABLE(IMAGE_CONTROLS)
394     case ImageControlsButtonPart:
395         return paintImageControlsButton(o, paintInfo, r);
396 #endif
397     default:
398         break;
399     }
400
401     return true; // We don't support the appearance, so let the normal background/border paint.
402 }
403
404 bool RenderTheme::paintBorderOnly(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
405 {
406     if (paintInfo.context->paintingDisabled())
407         return false;
408
409 #if PLATFORM(IOS)
410     UNUSED_PARAM(r);
411     return o->style().appearance() != NoControlPart;
412 #else
413     // Call the appropriate paint method based off the appearance value.
414     switch (o->style().appearance()) {
415     case TextFieldPart:
416         return paintTextField(o, paintInfo, r);
417     case ListboxPart:
418     case TextAreaPart:
419         return paintTextArea(o, paintInfo, r);
420     case MenulistButtonPart:
421     case SearchFieldPart:
422         return true;
423     case CheckboxPart:
424     case RadioPart:
425     case PushButtonPart:
426     case SquareButtonPart:
427     case DefaultButtonPart:
428     case ButtonPart:
429     case MenulistPart:
430 #if ENABLE(METER_ELEMENT)
431     case MeterPart:
432     case RelevancyLevelIndicatorPart:
433     case ContinuousCapacityLevelIndicatorPart:
434     case DiscreteCapacityLevelIndicatorPart:
435     case RatingLevelIndicatorPart:
436 #endif
437 #if ENABLE(PROGRESS_ELEMENT)
438     case ProgressBarPart:
439 #endif
440     case SliderHorizontalPart:
441     case SliderVerticalPart:
442     case SliderThumbHorizontalPart:
443     case SliderThumbVerticalPart:
444     case SearchFieldCancelButtonPart:
445     case SearchFieldDecorationPart:
446     case SearchFieldResultsDecorationPart:
447     case SearchFieldResultsButtonPart:
448 #if ENABLE(INPUT_SPEECH)
449     case InputSpeechButtonPart:
450 #endif
451 #if ENABLE(IMAGE_CONTROLS)
452     case ImageControlsButtonPart:
453 #endif
454     default:
455         break;
456     }
457
458     return false;
459 #endif
460 }
461
462 bool RenderTheme::paintDecorations(RenderObject* renderer, const PaintInfo& paintInfo, const IntRect& rect)
463 {
464     if (paintInfo.context->paintingDisabled())
465         return false;
466
467     // Call the appropriate paint method based off the appearance value.
468     switch (renderer->style().appearance()) {
469     case MenulistButtonPart:
470         return paintMenuListButtonDecorations(renderer, paintInfo, rect);
471     case TextFieldPart:
472         return paintTextFieldDecorations(renderer, paintInfo, rect);
473     case TextAreaPart:
474         return paintTextAreaDecorations(renderer, paintInfo, rect);
475     case CheckboxPart:
476         return paintCheckboxDecorations(renderer, paintInfo, rect);
477     case RadioPart:
478         return paintRadioDecorations(renderer, paintInfo, rect);
479     case PushButtonPart:
480         return paintPushButtonDecorations(renderer, paintInfo, rect);
481     case SquareButtonPart:
482         return paintSquareButtonDecorations(renderer, paintInfo, rect);
483     case ButtonPart:
484         return paintButtonDecorations(renderer, paintInfo, rect);
485     case MenulistPart:
486         return paintMenuListDecorations(renderer, paintInfo, rect);
487     case SliderThumbHorizontalPart:
488     case SliderThumbVerticalPart:
489         return paintSliderThumbDecorations(renderer, paintInfo, rect);
490     case SearchFieldPart:
491         return paintSearchFieldDecorations(renderer, paintInfo, rect);
492 #if ENABLE(METER_ELEMENT)
493     case MeterPart:
494     case RelevancyLevelIndicatorPart:
495     case ContinuousCapacityLevelIndicatorPart:
496     case DiscreteCapacityLevelIndicatorPart:
497     case RatingLevelIndicatorPart:
498 #endif
499 #if ENABLE(PROGRESS_ELEMENT)
500     case ProgressBarPart:
501 #endif
502     case SliderHorizontalPart:
503     case SliderVerticalPart:
504     case ListboxPart:
505     case DefaultButtonPart:
506     case SearchFieldCancelButtonPart:
507     case SearchFieldDecorationPart:
508     case SearchFieldResultsDecorationPart:
509     case SearchFieldResultsButtonPart:
510 #if ENABLE(INPUT_SPEECH)
511     case InputSpeechButtonPart:
512 #endif
513 #if ENABLE(IMAGE_CONTROLS)
514     case ImageControlsButtonPart:
515 #endif
516     default:
517         break;
518     }
519
520     return false;
521 }
522
523 #if ENABLE(VIDEO)
524
525 String RenderTheme::formatMediaControlsTime(float time) const
526 {
527     if (!std::isfinite(time))
528         time = 0;
529     int seconds = (int)fabsf(time);
530     int hours = seconds / (60 * 60);
531     int minutes = (seconds / 60) % 60;
532     seconds %= 60;
533     if (hours) {
534         if (hours > 9)
535             return String::format("%s%02d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds);
536
537         return String::format("%s%01d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds);
538     }
539
540     return String::format("%s%02d:%02d", (time < 0 ? "-" : ""), minutes, seconds);
541 }
542
543 String RenderTheme::formatMediaControlsCurrentTime(float currentTime, float /*duration*/) const
544 {
545     return formatMediaControlsTime(currentTime);
546 }
547
548 String RenderTheme::formatMediaControlsRemainingTime(float currentTime, float duration) const
549 {
550     return formatMediaControlsTime(currentTime - duration);
551 }
552
553 IntPoint RenderTheme::volumeSliderOffsetFromMuteButton(RenderBox* muteButtonBox, const IntSize& size) const
554 {
555     int y = -size.height();
556     FloatPoint absPoint = muteButtonBox->localToAbsolute(FloatPoint(muteButtonBox->pixelSnappedOffsetLeft(), y), IsFixed | UseTransforms);
557     if (absPoint.y() < 0)
558         y = muteButtonBox->height();
559     return IntPoint(0, y);
560 }
561
562 #endif
563
564 Color RenderTheme::activeSelectionBackgroundColor() const
565 {
566     if (!m_activeSelectionBackgroundColor.isValid())
567         m_activeSelectionBackgroundColor = platformActiveSelectionBackgroundColor().blendWithWhite();
568     return m_activeSelectionBackgroundColor;
569 }
570
571 Color RenderTheme::inactiveSelectionBackgroundColor() const
572 {
573     if (!m_inactiveSelectionBackgroundColor.isValid())
574         m_inactiveSelectionBackgroundColor = platformInactiveSelectionBackgroundColor().blendWithWhite();
575     return m_inactiveSelectionBackgroundColor;
576 }
577
578 Color RenderTheme::activeSelectionForegroundColor() const
579 {
580     if (!m_activeSelectionForegroundColor.isValid() && supportsSelectionForegroundColors())
581         m_activeSelectionForegroundColor = platformActiveSelectionForegroundColor();
582     return m_activeSelectionForegroundColor;
583 }
584
585 Color RenderTheme::inactiveSelectionForegroundColor() const
586 {
587     if (!m_inactiveSelectionForegroundColor.isValid() && supportsSelectionForegroundColors())
588         m_inactiveSelectionForegroundColor = platformInactiveSelectionForegroundColor();
589     return m_inactiveSelectionForegroundColor;
590 }
591
592 Color RenderTheme::activeListBoxSelectionBackgroundColor() const
593 {
594     if (!m_activeListBoxSelectionBackgroundColor.isValid())
595         m_activeListBoxSelectionBackgroundColor = platformActiveListBoxSelectionBackgroundColor();
596     return m_activeListBoxSelectionBackgroundColor;
597 }
598
599 Color RenderTheme::inactiveListBoxSelectionBackgroundColor() const
600 {
601     if (!m_inactiveListBoxSelectionBackgroundColor.isValid())
602         m_inactiveListBoxSelectionBackgroundColor = platformInactiveListBoxSelectionBackgroundColor();
603     return m_inactiveListBoxSelectionBackgroundColor;
604 }
605
606 Color RenderTheme::activeListBoxSelectionForegroundColor() const
607 {
608     if (!m_activeListBoxSelectionForegroundColor.isValid() && supportsListBoxSelectionForegroundColors())
609         m_activeListBoxSelectionForegroundColor = platformActiveListBoxSelectionForegroundColor();
610     return m_activeListBoxSelectionForegroundColor;
611 }
612
613 Color RenderTheme::inactiveListBoxSelectionForegroundColor() const
614 {
615     if (!m_inactiveListBoxSelectionForegroundColor.isValid() && supportsListBoxSelectionForegroundColors())
616         m_inactiveListBoxSelectionForegroundColor = platformInactiveListBoxSelectionForegroundColor();
617     return m_inactiveListBoxSelectionForegroundColor;
618 }
619
620 Color RenderTheme::platformActiveSelectionBackgroundColor() const
621 {
622     // Use a blue color by default if the platform theme doesn't define anything.
623     return Color(0, 0, 255);
624 }
625
626 Color RenderTheme::platformActiveSelectionForegroundColor() const
627 {
628     // Use a white color by default if the platform theme doesn't define anything.
629     return Color::white;
630 }
631
632 Color RenderTheme::platformInactiveSelectionBackgroundColor() const
633 {
634     // Use a grey color by default if the platform theme doesn't define anything.
635     // This color matches Firefox's inactive color.
636     return Color(176, 176, 176);
637 }
638
639 Color RenderTheme::platformInactiveSelectionForegroundColor() const
640 {
641     // Use a black color by default.
642     return Color::black;
643 }
644
645 Color RenderTheme::platformActiveListBoxSelectionBackgroundColor() const
646 {
647     return platformActiveSelectionBackgroundColor();
648 }
649
650 Color RenderTheme::platformActiveListBoxSelectionForegroundColor() const
651 {
652     return platformActiveSelectionForegroundColor();
653 }
654
655 Color RenderTheme::platformInactiveListBoxSelectionBackgroundColor() const
656 {
657     return platformInactiveSelectionBackgroundColor();
658 }
659
660 Color RenderTheme::platformInactiveListBoxSelectionForegroundColor() const
661 {
662     return platformInactiveSelectionForegroundColor();
663 }
664
665 int RenderTheme::baselinePosition(const RenderObject* o) const
666 {
667     if (!o->isBox())
668         return 0;
669
670     const RenderBox* box = toRenderBox(o);
671
672 #if USE(NEW_THEME)
673     return box->height() + box->marginTop() + m_theme->baselinePositionAdjustment(o->style().appearance()) * o->style().effectiveZoom();
674 #else
675     return box->height() + box->marginTop();
676 #endif
677 }
678
679 bool RenderTheme::isControlContainer(ControlPart appearance) const
680 {
681     // There are more leaves than this, but we'll patch this function as we add support for
682     // more controls.
683     return appearance != CheckboxPart && appearance != RadioPart;
684 }
685
686 bool RenderTheme::isControlStyled(const RenderStyle* style, const BorderData& border, const FillLayer& background, const Color& backgroundColor) const
687 {
688     switch (style->appearance()) {
689     case PushButtonPart:
690     case SquareButtonPart:
691     case DefaultButtonPart:
692     case ButtonPart:
693     case ListboxPart:
694     case MenulistPart:
695     case ProgressBarPart:
696     case MeterPart:
697     case RelevancyLevelIndicatorPart:
698     case ContinuousCapacityLevelIndicatorPart:
699     case DiscreteCapacityLevelIndicatorPart:
700     case RatingLevelIndicatorPart:
701     // FIXME: SearchFieldPart should be included here when making search fields style-able.
702     case TextFieldPart:
703     case TextAreaPart:
704         // Test the style to see if the UA border and background match.
705         return (style->border() != border
706             || *style->backgroundLayers() != background
707             || style->visitedDependentColor(CSSPropertyBackgroundColor) != backgroundColor);
708     default:
709         return false;
710     }
711 }
712
713 void RenderTheme::adjustRepaintRect(const RenderObject* o, IntRect& r)
714 {
715 #if USE(NEW_THEME)
716     m_theme->inflateControlPaintRect(o->style().appearance(), controlStatesForRenderer(o), r, o->style().effectiveZoom());
717 #else
718     UNUSED_PARAM(o);
719     UNUSED_PARAM(r);
720 #endif
721 }
722
723 bool RenderTheme::supportsFocusRing(const RenderStyle* style) const
724 {
725     return (style->hasAppearance() && style->appearance() != TextFieldPart && style->appearance() != TextAreaPart && style->appearance() != MenulistButtonPart && style->appearance() != ListboxPart);
726 }
727
728 bool RenderTheme::stateChanged(RenderObject* o, ControlState state) const
729 {
730     // Default implementation assumes the controls don't respond to changes in :hover state
731     if (state == HoverState && !supportsHover(&o->style()))
732         return false;
733
734     // Assume pressed state is only responded to if the control is enabled.
735     if (state == PressedState && !isEnabled(o))
736         return false;
737
738     // Repaint the control.
739     o->repaint();
740     return true;
741 }
742
743 ControlStates RenderTheme::controlStatesForRenderer(const RenderObject* o) const
744 {
745     ControlStates result = 0;
746     if (isHovered(o)) {
747         result |= HoverState;
748         if (isSpinUpButtonPartHovered(o))
749             result |= SpinUpState;
750     }
751     if (isPressed(o)) {
752         result |= PressedState;
753         if (isSpinUpButtonPartPressed(o))
754             result |= SpinUpState;
755     }
756     if (isFocused(o) && o->style().outlineStyleIsAuto())
757         result |= FocusState;
758     if (isEnabled(o))
759         result |= EnabledState;
760     if (isChecked(o))
761         result |= CheckedState;
762     if (isReadOnlyControl(o))
763         result |= ReadOnlyState;
764     if (isDefault(o))
765         result |= DefaultState;
766     if (!isActive(o))
767         result |= WindowInactiveState;
768     if (isIndeterminate(o))
769         result |= IndeterminateState;
770     return result;
771 }
772
773 bool RenderTheme::isActive(const RenderObject* o) const
774 {
775     Node* node = o->node();
776     if (!node)
777         return false;
778
779     Frame* frame = node->document().frame();
780     if (!frame)
781         return false;
782
783     Page* page = frame->page();
784     if (!page)
785         return false;
786
787     return page->focusController().isActive();
788 }
789
790 bool RenderTheme::isChecked(const RenderObject* o) const
791 {
792     if (!o->node())
793         return false;
794
795     HTMLInputElement* inputElement = o->node()->toInputElement();
796     if (!inputElement)
797         return false;
798
799     return inputElement->shouldAppearChecked();
800 }
801
802 bool RenderTheme::isIndeterminate(const RenderObject* o) const
803 {
804     if (!o->node())
805         return false;
806
807     HTMLInputElement* inputElement = o->node()->toInputElement();
808     if (!inputElement)
809         return false;
810
811     return inputElement->shouldAppearIndeterminate();
812 }
813
814 bool RenderTheme::isEnabled(const RenderObject* o) const
815 {
816     Node* node = o->node();
817     if (!node || !node->isElementNode())
818         return true;
819     return !toElement(node)->isDisabledFormControl();
820 }
821
822 bool RenderTheme::isFocused(const RenderObject* o) const
823 {
824     Node* node = o->node();
825     if (!node || !node->isElementNode())
826         return false;
827
828     Element* focusDelegate = toElement(node)->focusDelegate();
829     Document& document = focusDelegate->document();
830     Frame* frame = document.frame();
831     return focusDelegate == document.focusedElement() && frame && frame->selection().isFocusedAndActive();
832 }
833
834 bool RenderTheme::isPressed(const RenderObject* o) const
835 {
836     if (!o->node() || !o->node()->isElementNode())
837         return false;
838     return toElement(o->node())->active();
839 }
840
841 bool RenderTheme::isSpinUpButtonPartPressed(const RenderObject* o) const
842 {
843     Node* node = o->node();
844     if (!node || !node->isElementNode())
845         return false;
846     Element* element = toElement(node);
847     if (!element->active() || !element->isSpinButtonElement())
848         return false;
849     return static_cast<SpinButtonElement*>(element)->upDownState() == SpinButtonElement::Up;
850 }
851
852 bool RenderTheme::isReadOnlyControl(const RenderObject* o) const
853 {
854     Node* node = o->node();
855     if (!node || !node->isElementNode())
856         return false;
857     return toElement(node)->matchesReadOnlyPseudoClass();
858 }
859
860 bool RenderTheme::isHovered(const RenderObject* o) const
861 {
862     Node* node = o->node();
863     if (!node || !node->isElementNode())
864         return false;
865     if (!toElement(node)->isSpinButtonElement())
866         return toElement(node)->hovered();
867     SpinButtonElement* element = static_cast<SpinButtonElement*>(node);
868     return element->hovered() && element->upDownState() != SpinButtonElement::Indeterminate;
869 }
870
871 bool RenderTheme::isSpinUpButtonPartHovered(const RenderObject* o) const
872 {
873     Node* node = o->node();
874     if (!node || !node->isElementNode() || !toElement(node)->isSpinButtonElement())
875         return false;
876     SpinButtonElement* element = static_cast<SpinButtonElement*>(node);
877     return element->upDownState() == SpinButtonElement::Up;
878 }
879
880 bool RenderTheme::isDefault(const RenderObject* o) const
881 {
882     // A button should only have the default appearance if the page is active
883     if (!isActive(o))
884         return false;
885
886     if (!o->frame().settings().applicationChromeMode())
887         return false;
888     
889     return o->style().appearance() == DefaultButtonPart;
890 }
891
892 #if !USE(NEW_THEME)
893
894 void RenderTheme::adjustCheckboxStyle(StyleResolver*, RenderStyle* style, Element*) const
895 {
896     // A summary of the rules for checkbox designed to match WinIE:
897     // width/height - honored (WinIE actually scales its control for small widths, but lets it overflow for small heights.)
898     // font-size - not honored (control has no text), but we use it to decide which control size to use.
899     setCheckboxSize(style);
900
901     // padding - not honored by WinIE, needs to be removed.
902     style->resetPadding();
903
904     // border - honored by WinIE, but looks terrible (just paints in the control box and turns off the Windows XP theme)
905     // for now, we will not honor it.
906     style->resetBorder();
907
908     style->setBoxShadow(nullptr);
909 }
910
911 void RenderTheme::adjustRadioStyle(StyleResolver*, RenderStyle* style, Element*) const
912 {
913     // A summary of the rules for checkbox designed to match WinIE:
914     // width/height - honored (WinIE actually scales its control for small widths, but lets it overflow for small heights.)
915     // font-size - not honored (control has no text), but we use it to decide which control size to use.
916     setRadioSize(style);
917
918     // padding - not honored by WinIE, needs to be removed.
919     style->resetPadding();
920
921     // border - honored by WinIE, but looks terrible (just paints in the control box and turns off the Windows XP theme)
922     // for now, we will not honor it.
923     style->resetBorder();
924
925     style->setBoxShadow(nullptr);
926 }
927
928 void RenderTheme::adjustButtonStyle(StyleResolver*, RenderStyle* style, Element*) const
929 {
930     // Most platforms will completely honor all CSS, and so we have no need to
931     // adjust the style at all by default. We will still allow the theme a crack
932     // at setting up a desired vertical size.
933     setButtonSize(style);
934 }
935
936 void RenderTheme::adjustInnerSpinButtonStyle(StyleResolver*, RenderStyle*, Element*) const
937 {
938 }
939 #endif
940
941 void RenderTheme::adjustTextFieldStyle(StyleResolver*, RenderStyle*, Element*) const
942 {
943 }
944
945 void RenderTheme::adjustTextAreaStyle(StyleResolver*, RenderStyle*, Element*) const
946 {
947 }
948
949 void RenderTheme::adjustMenuListStyle(StyleResolver*, RenderStyle*, Element*) const
950 {
951 }
952
953 #if ENABLE(INPUT_SPEECH)
954 void RenderTheme::adjustInputFieldSpeechButtonStyle(StyleResolver* styleResolver, RenderStyle* style, Element* element) const
955 {
956     RenderInputSpeech::adjustInputFieldSpeechButtonStyle(styleResolver, style, element);
957 }
958
959 bool RenderTheme::paintInputFieldSpeechButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
960 {
961     return RenderInputSpeech::paintInputFieldSpeechButton(object, paintInfo, rect);
962 }
963 #endif
964
965 #if ENABLE(METER_ELEMENT)
966 void RenderTheme::adjustMeterStyle(StyleResolver*, RenderStyle* style, Element*) const
967 {
968     style->setBoxShadow(nullptr);
969 }
970
971 IntSize RenderTheme::meterSizeForBounds(const RenderMeter*, const IntRect& bounds) const
972 {
973     return bounds.size();
974 }
975
976 bool RenderTheme::supportsMeter(ControlPart) const
977 {
978     return false;
979 }
980
981 bool RenderTheme::paintMeter(RenderObject*, const PaintInfo&, const IntRect&)
982 {
983     return true;
984 }
985
986 #endif
987
988 #if ENABLE(DATALIST_ELEMENT)
989 LayoutUnit RenderTheme::sliderTickSnappingThreshold() const
990 {
991     return 0;
992 }
993
994 void RenderTheme::paintSliderTicks(RenderObject* o, const PaintInfo& paintInfo, const IntRect& rect)
995 {
996     Node* node = o->node();
997     if (!node)
998         return;
999
1000     HTMLInputElement* input = node->toInputElement();
1001     if (!input)
1002         return;
1003
1004     HTMLDataListElement* dataList = toHTMLDataListElement(input->list());
1005     if (!dataList)
1006         return;
1007
1008     double min = input->minimum();
1009     double max = input->maximum();
1010     ControlPart part = o->style().appearance();
1011     // We don't support ticks on alternate sliders like MediaVolumeSliders.
1012     if (part !=  SliderHorizontalPart && part != SliderVerticalPart)
1013         return;
1014     bool isHorizontal = part ==  SliderHorizontalPart;
1015
1016     IntSize thumbSize;
1017     RenderObject* thumbRenderer = input->sliderThumbElement()->renderer();
1018     if (thumbRenderer) {
1019         const RenderStyle& thumbStyle = thumbRenderer->style();
1020         int thumbWidth = thumbStyle.width().intValue();
1021         int thumbHeight = thumbStyle.height().intValue();
1022         thumbSize.setWidth(isHorizontal ? thumbWidth : thumbHeight);
1023         thumbSize.setHeight(isHorizontal ? thumbHeight : thumbWidth);
1024     }
1025
1026     IntSize tickSize = sliderTickSize();
1027     float zoomFactor = o->style().effectiveZoom();
1028     FloatRect tickRect;
1029     int tickRegionSideMargin = 0;
1030     int tickRegionWidth = 0;
1031     IntRect trackBounds;
1032     RenderObject* trackRenderer = input->sliderTrackElement()->renderer();
1033     // We can ignoring transforms because transform is handled by the graphics context.
1034     if (trackRenderer)
1035         trackBounds = trackRenderer->absoluteBoundingBoxRectIgnoringTransforms();
1036     IntRect sliderBounds = o->absoluteBoundingBoxRectIgnoringTransforms();
1037
1038     // Make position relative to the transformed ancestor element.
1039     trackBounds.setX(trackBounds.x() - sliderBounds.x() + rect.x());
1040     trackBounds.setY(trackBounds.y() - sliderBounds.y() + rect.y());
1041
1042     if (isHorizontal) {
1043         tickRect.setWidth(floor(tickSize.width() * zoomFactor));
1044         tickRect.setHeight(floor(tickSize.height() * zoomFactor));
1045         tickRect.setY(floor(rect.y() + rect.height() / 2.0 + sliderTickOffsetFromTrackCenter() * zoomFactor));
1046         tickRegionSideMargin = trackBounds.x() + (thumbSize.width() - tickSize.width() * zoomFactor) / 2.0;
1047         tickRegionWidth = trackBounds.width() - thumbSize.width();
1048     } else {
1049         tickRect.setWidth(floor(tickSize.height() * zoomFactor));
1050         tickRect.setHeight(floor(tickSize.width() * zoomFactor));
1051         tickRect.setX(floor(rect.x() + rect.width() / 2.0 + sliderTickOffsetFromTrackCenter() * zoomFactor));
1052         tickRegionSideMargin = trackBounds.y() + (thumbSize.width() - tickSize.width() * zoomFactor) / 2.0;
1053         tickRegionWidth = trackBounds.height() - thumbSize.width();
1054     }
1055     RefPtr<HTMLCollection> options = dataList->options();
1056     GraphicsContextStateSaver stateSaver(*paintInfo.context);
1057     paintInfo.context->setFillColor(o->style().visitedDependentColor(CSSPropertyColor), ColorSpaceDeviceRGB);
1058     for (unsigned i = 0; Node* node = options->item(i); i++) {
1059         ASSERT(isHTMLOptionElement(node));
1060         HTMLOptionElement* optionElement = toHTMLOptionElement(node);
1061         String value = optionElement->value();
1062         if (!input->isValidValue(value))
1063             continue;
1064         double parsedValue = parseToDoubleForNumberType(input->sanitizeValue(value));
1065         double tickFraction = (parsedValue - min) / (max - min);
1066         double tickRatio = isHorizontal && o->style().isLeftToRightDirection() ? tickFraction : 1.0 - tickFraction;
1067         double tickPosition = round(tickRegionSideMargin + tickRegionWidth * tickRatio);
1068         if (isHorizontal)
1069             tickRect.setX(tickPosition);
1070         else
1071             tickRect.setY(tickPosition);
1072         paintInfo.context->fillRect(tickRect);
1073     }
1074 }
1075 #endif
1076
1077 #if ENABLE(PROGRESS_ELEMENT)
1078 double RenderTheme::animationRepeatIntervalForProgressBar(RenderProgress*) const
1079 {
1080     return 0;
1081 }
1082
1083 double RenderTheme::animationDurationForProgressBar(RenderProgress*) const
1084 {
1085     return 0;
1086 }
1087
1088 void RenderTheme::adjustProgressBarStyle(StyleResolver*, RenderStyle*, Element*) const
1089 {
1090 }
1091
1092 IntRect RenderTheme::progressBarRectForBounds(const RenderObject*, const IntRect& bounds) const
1093 {
1094     return bounds;
1095 }
1096 #endif
1097
1098 bool RenderTheme::shouldHaveSpinButton(HTMLInputElement* inputElement) const
1099 {
1100     return inputElement->isSteppable() && !inputElement->isRangeControl();
1101 }
1102
1103 void RenderTheme::adjustMenuListButtonStyle(StyleResolver*, RenderStyle*, Element*) const
1104 {
1105 }
1106
1107 void RenderTheme::adjustMediaControlStyle(StyleResolver*, RenderStyle*, Element*) const
1108 {
1109 }
1110
1111 void RenderTheme::adjustSliderTrackStyle(StyleResolver*, RenderStyle*, Element*) const
1112 {
1113 }
1114
1115 void RenderTheme::adjustSliderThumbStyle(StyleResolver*, RenderStyle* style, Element* element) const
1116 {
1117     adjustSliderThumbSize(style, element);
1118 }
1119
1120 void RenderTheme::adjustSliderThumbSize(RenderStyle*, Element*) const
1121 {
1122 }
1123
1124 void RenderTheme::adjustSearchFieldStyle(StyleResolver*, RenderStyle*, Element*) const
1125 {
1126 }
1127
1128 void RenderTheme::adjustSearchFieldCancelButtonStyle(StyleResolver*, RenderStyle*, Element*) const
1129 {
1130 }
1131
1132 void RenderTheme::adjustSearchFieldDecorationPartStyle(StyleResolver*, RenderStyle*, Element*) const
1133 {
1134 }
1135
1136 void RenderTheme::adjustSearchFieldResultsDecorationPartStyle(StyleResolver*, RenderStyle*, Element*) const
1137 {
1138 }
1139
1140 void RenderTheme::adjustSearchFieldResultsButtonStyle(StyleResolver*, RenderStyle*, Element*) const
1141 {
1142 }
1143
1144 void RenderTheme::platformColorsDidChange()
1145 {
1146     m_activeSelectionForegroundColor = Color();
1147     m_inactiveSelectionForegroundColor = Color();
1148     m_activeSelectionBackgroundColor = Color();
1149     m_inactiveSelectionBackgroundColor = Color();
1150
1151     m_activeListBoxSelectionForegroundColor = Color();
1152     m_inactiveListBoxSelectionForegroundColor = Color();
1153     m_activeListBoxSelectionBackgroundColor = Color();
1154     m_inactiveListBoxSelectionForegroundColor = Color();
1155
1156     Page::updateStyleForAllPagesAfterGlobalChangeInEnvironment();
1157 }
1158
1159 Color RenderTheme::systemColor(CSSValueID cssValueId) const
1160 {
1161     switch (cssValueId) {
1162     case CSSValueActiveborder:
1163         return 0xFFFFFFFF;
1164     case CSSValueActivecaption:
1165         return 0xFFCCCCCC;
1166     case CSSValueAppworkspace:
1167         return 0xFFFFFFFF;
1168     case CSSValueBackground:
1169         return 0xFF6363CE;
1170     case CSSValueButtonface:
1171         return 0xFFC0C0C0;
1172     case CSSValueButtonhighlight:
1173         return 0xFFDDDDDD;
1174     case CSSValueButtonshadow:
1175         return 0xFF888888;
1176     case CSSValueButtontext:
1177         return 0xFF000000;
1178     case CSSValueCaptiontext:
1179         return 0xFF000000;
1180     case CSSValueGraytext:
1181         return 0xFF808080;
1182     case CSSValueHighlight:
1183         return 0xFFB5D5FF;
1184     case CSSValueHighlighttext:
1185         return 0xFF000000;
1186     case CSSValueInactiveborder:
1187         return 0xFFFFFFFF;
1188     case CSSValueInactivecaption:
1189         return 0xFFFFFFFF;
1190     case CSSValueInactivecaptiontext:
1191         return 0xFF7F7F7F;
1192     case CSSValueInfobackground:
1193         return 0xFFFBFCC5;
1194     case CSSValueInfotext:
1195         return 0xFF000000;
1196     case CSSValueMenu:
1197         return 0xFFC0C0C0;
1198     case CSSValueMenutext:
1199         return 0xFF000000;
1200     case CSSValueScrollbar:
1201         return 0xFFFFFFFF;
1202     case CSSValueText:
1203         return 0xFF000000;
1204     case CSSValueThreeddarkshadow:
1205         return 0xFF666666;
1206     case CSSValueThreedface:
1207         return 0xFFC0C0C0;
1208     case CSSValueThreedhighlight:
1209         return 0xFFDDDDDD;
1210     case CSSValueThreedlightshadow:
1211         return 0xFFC0C0C0;
1212     case CSSValueThreedshadow:
1213         return 0xFF888888;
1214     case CSSValueWindow:
1215         return 0xFFFFFFFF;
1216     case CSSValueWindowframe:
1217         return 0xFFCCCCCC;
1218     case CSSValueWindowtext:
1219         return 0xFF000000;
1220     default:
1221         break;
1222     }
1223     return Color();
1224 }
1225
1226 Color RenderTheme::platformActiveTextSearchHighlightColor() const
1227 {
1228     return Color(255, 150, 50); // Orange.
1229 }
1230
1231 Color RenderTheme::platformInactiveTextSearchHighlightColor() const
1232 {
1233     return Color(255, 255, 0); // Yellow.
1234 }
1235
1236 #if ENABLE(TOUCH_EVENTS)
1237 Color RenderTheme::tapHighlightColor()
1238 {
1239     return defaultTheme()->platformTapHighlightColor();
1240 }
1241 #endif
1242
1243 // Value chosen by observation. This can be tweaked.
1244 static const int minColorContrastValue = 1300;
1245 // For transparent or translucent background color, use lightening.
1246 static const int minDisabledColorAlphaValue = 128;
1247
1248 Color RenderTheme::disabledTextColor(const Color& textColor, const Color& backgroundColor) const
1249 {
1250     // The explicit check for black is an optimization for the 99% case (black on white).
1251     // This also means that black on black will turn into grey on black when disabled.
1252     Color disabledColor;
1253     if (textColor.rgb() == Color::black || backgroundColor.alpha() < minDisabledColorAlphaValue || differenceSquared(textColor, Color::white) > differenceSquared(backgroundColor, Color::white))
1254         disabledColor = textColor.light();
1255     else
1256         disabledColor = textColor.dark();
1257     
1258     // If there's not very much contrast between the disabled color and the background color,
1259     // just leave the text color alone. We don't want to change a good contrast color scheme so that it has really bad contrast.
1260     // If the the contrast was already poor, then it doesn't do any good to change it to a different poor contrast color scheme.
1261     if (differenceSquared(disabledColor, backgroundColor) < minColorContrastValue)
1262         return textColor;
1263     
1264     return disabledColor;
1265 }
1266
1267 void RenderTheme::setCustomFocusRingColor(const Color& c)
1268 {
1269     customFocusRingColor() = c;
1270 }
1271
1272 Color RenderTheme::focusRingColor()
1273 {
1274     return customFocusRingColor().isValid() ? customFocusRingColor() : defaultTheme()->platformFocusRingColor();
1275 }
1276
1277 String RenderTheme::fileListDefaultLabel(bool multipleFilesAllowed) const
1278 {
1279     if (multipleFilesAllowed)
1280         return fileButtonNoFilesSelectedLabel();
1281     return fileButtonNoFileSelectedLabel();
1282 }
1283
1284 String RenderTheme::fileListNameForWidth(const FileList* fileList, const Font& font, int width, bool multipleFilesAllowed) const
1285 {
1286     if (width <= 0)
1287         return String();
1288
1289     String string;
1290     if (fileList->isEmpty())
1291         string = fileListDefaultLabel(multipleFilesAllowed);
1292     else if (fileList->length() == 1)
1293         string = fileList->item(0)->name();
1294     else
1295         return StringTruncator::rightTruncate(multipleFileUploadText(fileList->length()), width, font, StringTruncator::EnableRoundingHacks);
1296
1297     return StringTruncator::centerTruncate(string, width, font, StringTruncator::EnableRoundingHacks);
1298 }
1299
1300 } // namespace WebCore