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