1 /**
2 * This file is part of the theme implementation for form controls in WebCore.
3 *
4 * Copyright (C) 2005, 2006, 2007, 2008 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 "FocusController.h"
28 #include "FontSelector.h"
29 #include "Frame.h"
30 #include "GraphicsContext.h"
31 #include "HTMLInputElement.h"
32 #include "HTMLNames.h"
33 #include "Page.h"
34 #include "RenderStyle.h"
35 #include "RenderView.h"
36 #include "SelectionController.h"
37 #include "Settings.h"
38
39 // The methods in this file are shared by all themes on every platform.
40
41 namespace WebCore {
42
43 using namespace HTMLNames;
44
customFocusRingColor()45 static Color& customFocusRingColor()
46 {
47 DEFINE_STATIC_LOCAL(Color, color, ());
48 return color;
49 }
50
RenderTheme()51 RenderTheme::RenderTheme()
52 #if USE(NEW_THEME)
53 : m_theme(platformTheme())
54 #endif
55 {
56 }
57
adjustStyle(CSSStyleSelector * selector,RenderStyle * style,Element * e,bool UAHasAppearance,const BorderData & border,const FillLayer & background,const Color & backgroundColor)58 void RenderTheme::adjustStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e,
59 bool UAHasAppearance, const BorderData& border, const FillLayer& background, const Color& backgroundColor)
60 {
61 // Force inline and table display styles to be inline-block (except for table- which is block)
62 ControlPart part = style->appearance();
63 if (style->display() == INLINE || style->display() == INLINE_TABLE || style->display() == TABLE_ROW_GROUP ||
64 style->display() == TABLE_HEADER_GROUP || style->display() == TABLE_FOOTER_GROUP ||
65 style->display() == TABLE_ROW || style->display() == TABLE_COLUMN_GROUP || style->display() == TABLE_COLUMN ||
66 style->display() == TABLE_CELL || style->display() == TABLE_CAPTION)
67 style->setDisplay(INLINE_BLOCK);
68 else if (style->display() == COMPACT || style->display() == RUN_IN || style->display() == LIST_ITEM || style->display() == TABLE)
69 style->setDisplay(BLOCK);
70
71 if (UAHasAppearance && isControlStyled(style, border, background, backgroundColor)) {
72 if (part == MenulistPart) {
73 style->setAppearance(MenulistButtonPart);
74 part = MenulistButtonPart;
75 } else
76 style->setAppearance(NoControlPart);
77 }
78
79 if (!style->hasAppearance())
80 return;
81
82 // Never support box-shadow on native controls.
83 style->setBoxShadow(0);
84
85 #if USE(NEW_THEME)
86 switch (part) {
87 case CheckboxPart:
88 case RadioPart:
89 case PushButtonPart:
90 case SquareButtonPart:
91 case DefaultButtonPart:
92 case ButtonPart: {
93 // Border
94 LengthBox borderBox(style->borderTopWidth(), style->borderRightWidth(), style->borderBottomWidth(), style->borderLeftWidth());
95 borderBox = m_theme->controlBorder(part, style->font(), borderBox, style->effectiveZoom());
96 if (borderBox.top().value() != style->borderTopWidth()) {
97 if (borderBox.top().value())
98 style->setBorderTopWidth(borderBox.top().value());
99 else
100 style->resetBorderTop();
101 }
102 if (borderBox.right().value() != style->borderRightWidth()) {
103 if (borderBox.right().value())
104 style->setBorderRightWidth(borderBox.right().value());
105 else
106 style->resetBorderRight();
107 }
108 if (borderBox.bottom().value() != style->borderBottomWidth()) {
109 style->setBorderBottomWidth(borderBox.bottom().value());
110 if (borderBox.bottom().value())
111 style->setBorderBottomWidth(borderBox.bottom().value());
112 else
113 style->resetBorderBottom();
114 }
115 if (borderBox.left().value() != style->borderLeftWidth()) {
116 style->setBorderLeftWidth(borderBox.left().value());
117 if (borderBox.left().value())
118 style->setBorderLeftWidth(borderBox.left().value());
119 else
120 style->resetBorderLeft();
121 }
122
123 // Padding
124 LengthBox paddingBox = m_theme->controlPadding(part, style->font(), style->paddingBox(), style->effectiveZoom());
125 if (paddingBox != style->paddingBox())
126 style->setPaddingBox(paddingBox);
127
128 // Whitespace
129 if (m_theme->controlRequiresPreWhiteSpace(part))
130 style->setWhiteSpace(PRE);
131
132 // Width / Height
133 // The width and height here are affected by the zoom.
134 // FIXME: Check is flawed, since it doesn't take min-width/max-width into account.
135 LengthSize controlSize = m_theme->controlSize(part, style->font(), LengthSize(style->width(), style->height()), style->effectiveZoom());
136 if (controlSize.width() != style->width())
137 style->setWidth(controlSize.width());
138 if (controlSize.height() != style->height())
139 style->setHeight(controlSize.height());
140
141 // Min-Width / Min-Height
142 LengthSize minControlSize = m_theme->minimumControlSize(part, style->font(), style->effectiveZoom());
143 if (minControlSize.width() != style->minWidth())
144 style->setMinWidth(minControlSize.width());
145 if (minControlSize.height() != style->minHeight())
146 style->setMinHeight(minControlSize.height());
147
148 // Font
149 FontDescription controlFont = m_theme->controlFont(part, style->font(), style->effectiveZoom());
150 if (controlFont != style->font().fontDescription()) {
151 // Reset our line-height
152 style->setLineHeight(RenderStyle::initialLineHeight());
153
154 // Now update our font.
155 if (style->setFontDescription(controlFont))
156 style->font().update(0);
157 }
158 }
159 default:
160 break;
161 }
162 #endif
163
164 // Call the appropriate style adjustment method based off the appearance value.
165 switch (style->appearance()) {
166 #if !USE(NEW_THEME)
167 case CheckboxPart:
168 return adjustCheckboxStyle(selector, style, e);
169 case RadioPart:
170 return adjustRadioStyle(selector, style, e);
171 case PushButtonPart:
172 case SquareButtonPart:
173 case DefaultButtonPart:
174 case ButtonPart:
175 return adjustButtonStyle(selector, style, e);
176 #endif
177 case TextFieldPart:
178 return adjustTextFieldStyle(selector, style, e);
179 case TextAreaPart:
180 return adjustTextAreaStyle(selector, style, e);
181 #ifdef ANDROID_LISTBOX_USES_MENU_LIST
182 case ListboxPart:
183 return adjustListboxStyle(selector, style, e);
184 #endif
185 case MenulistPart:
186 return adjustMenuListStyle(selector, style, e);
187 case MenulistButtonPart:
188 return adjustMenuListButtonStyle(selector, style, e);
189 case MediaSliderPart:
190 case SliderHorizontalPart:
191 case SliderVerticalPart:
192 return adjustSliderTrackStyle(selector, style, e);
193 case SliderThumbHorizontalPart:
194 case SliderThumbVerticalPart:
195 return adjustSliderThumbStyle(selector, style, e);
196 case SearchFieldPart:
197 return adjustSearchFieldStyle(selector, style, e);
198 case SearchFieldCancelButtonPart:
199 return adjustSearchFieldCancelButtonStyle(selector, style, e);
200 case SearchFieldDecorationPart:
201 return adjustSearchFieldDecorationStyle(selector, style, e);
202 case SearchFieldResultsDecorationPart:
203 return adjustSearchFieldResultsDecorationStyle(selector, style, e);
204 case SearchFieldResultsButtonPart:
205 return adjustSearchFieldResultsButtonStyle(selector, style, e);
206 default:
207 break;
208 }
209 }
210
paint(RenderObject * o,const RenderObject::PaintInfo & paintInfo,const IntRect & r)211 bool RenderTheme::paint(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
212 {
213 // If painting is disabled, but we aren't updating control tints, then just bail.
214 // If we are updating control tints, just schedule a repaint if the theme supports tinting
215 // for that control.
216 if (paintInfo.context->updatingControlTints()) {
217 if (controlSupportsTints(o))
218 o->repaint();
219 return false;
220 }
221 if (paintInfo.context->paintingDisabled())
222 return false;
223
224 ControlPart part = o->style()->appearance();
225
226 #if USE(NEW_THEME)
227 switch (part) {
228 case CheckboxPart:
229 case RadioPart:
230 case PushButtonPart:
231 case SquareButtonPart:
232 case DefaultButtonPart:
233 case ButtonPart:
234 m_theme->paint(part, controlStatesForRenderer(o), const_cast<GraphicsContext*>(paintInfo.context), r, o->style()->effectiveZoom(), o->view()->frameView());
235 return false;
236 default:
237 break;
238 }
239 #endif
240
241 // Call the appropriate paint method based off the appearance value.
242 switch (part) {
243 #if !USE(NEW_THEME)
244 case CheckboxPart:
245 return paintCheckbox(o, paintInfo, r);
246 case RadioPart:
247 return paintRadio(o, paintInfo, r);
248 case PushButtonPart:
249 case SquareButtonPart:
250 case DefaultButtonPart:
251 case ButtonPart:
252 return paintButton(o, paintInfo, r);
253 #endif
254 case MenulistPart:
255 return paintMenuList(o, paintInfo, r);
256 case SliderHorizontalPart:
257 case SliderVerticalPart:
258 return paintSliderTrack(o, paintInfo, r);
259 case SliderThumbHorizontalPart:
260 case SliderThumbVerticalPart:
261 if (o->parent()->isSlider())
262 return paintSliderThumb(o, paintInfo, r);
263 // We don't support drawing a slider thumb without a parent slider
264 break;
265 case MediaFullscreenButtonPart:
266 return paintMediaFullscreenButton(o, paintInfo, r);
267 case MediaPlayButtonPart:
268 return paintMediaPlayButton(o, paintInfo, r);
269 case MediaMuteButtonPart:
270 return paintMediaMuteButton(o, paintInfo, r);
271 case MediaSeekBackButtonPart:
272 return paintMediaSeekBackButton(o, paintInfo, r);
273 case MediaSeekForwardButtonPart:
274 return paintMediaSeekForwardButton(o, paintInfo, r);
275 case MediaRewindButtonPart:
276 return paintMediaRewindButton(o, paintInfo, r);
277 case MediaReturnToRealtimeButtonPart:
278 return paintMediaReturnToRealtimeButton(o, paintInfo, r);
279 case MediaSliderPart:
280 return paintMediaSliderTrack(o, paintInfo, r);
281 case MediaSliderThumbPart:
282 if (o->parent()->isSlider())
283 return paintMediaSliderThumb(o, paintInfo, r);
284 break;
285 case MediaTimeRemainingPart:
286 return paintMediaTimeRemaining(o, paintInfo, r);
287 case MediaCurrentTimePart:
288 return paintMediaCurrentTime(o, paintInfo, r);
289 case MediaControlsBackgroundPart:
290 return paintMediaControlsBackground(o, paintInfo, r);
291 case MenulistButtonPart:
292 case TextFieldPart:
293 case TextAreaPart:
294 case ListboxPart:
295 return true;
296 case SearchFieldPart:
297 return paintSearchField(o, paintInfo, r);
298 case SearchFieldCancelButtonPart:
299 return paintSearchFieldCancelButton(o, paintInfo, r);
300 case SearchFieldDecorationPart:
301 return paintSearchFieldDecoration(o, paintInfo, r);
302 case SearchFieldResultsDecorationPart:
303 return paintSearchFieldResultsDecoration(o, paintInfo, r);
304 case SearchFieldResultsButtonPart:
305 return paintSearchFieldResultsButton(o, paintInfo, r);
306 default:
307 break;
308 }
309
310 return true; // We don't support the appearance, so let the normal background/border paint.
311 }
312
paintBorderOnly(RenderObject * o,const RenderObject::PaintInfo & paintInfo,const IntRect & r)313 bool RenderTheme::paintBorderOnly(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
314 {
315 if (paintInfo.context->paintingDisabled())
316 return false;
317
318 // Call the appropriate paint method based off the appearance value.
319 switch (o->style()->appearance()) {
320 case TextFieldPart:
321 return paintTextField(o, paintInfo, r);
322 case ListboxPart:
323 case TextAreaPart:
324 return paintTextArea(o, paintInfo, r);
325 case MenulistButtonPart:
326 case SearchFieldPart:
327 return true;
328 case CheckboxPart:
329 case RadioPart:
330 case PushButtonPart:
331 case SquareButtonPart:
332 case DefaultButtonPart:
333 case ButtonPart:
334 case MenulistPart:
335 case SliderHorizontalPart:
336 case SliderVerticalPart:
337 case SliderThumbHorizontalPart:
338 case SliderThumbVerticalPart:
339 case SearchFieldCancelButtonPart:
340 case SearchFieldDecorationPart:
341 case SearchFieldResultsDecorationPart:
342 case SearchFieldResultsButtonPart:
343 default:
344 break;
345 }
346
347 return false;
348 }
349
paintDecorations(RenderObject * o,const RenderObject::PaintInfo & paintInfo,const IntRect & r)350 bool RenderTheme::paintDecorations(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
351 {
352 if (paintInfo.context->paintingDisabled())
353 return false;
354
355 // Call the appropriate paint method based off the appearance value.
356 switch (o->style()->appearance()) {
357 case MenulistButtonPart:
358 return paintMenuListButton(o, paintInfo, r);
359 case TextFieldPart:
360 case TextAreaPart:
361 case ListboxPart:
362 case CheckboxPart:
363 case RadioPart:
364 case PushButtonPart:
365 case SquareButtonPart:
366 case DefaultButtonPart:
367 case ButtonPart:
368 case MenulistPart:
369 case SliderHorizontalPart:
370 case SliderVerticalPart:
371 case SliderThumbHorizontalPart:
372 case SliderThumbVerticalPart:
373 case SearchFieldPart:
374 case SearchFieldCancelButtonPart:
375 case SearchFieldDecorationPart:
376 case SearchFieldResultsDecorationPart:
377 case SearchFieldResultsButtonPart:
378 default:
379 break;
380 }
381
382 return false;
383 }
384
385 #if ENABLE(VIDEO)
hitTestMediaControlPart(RenderObject * o,const IntPoint & absPoint)386 bool RenderTheme::hitTestMediaControlPart(RenderObject* o, const IntPoint& absPoint)
387 {
388 if (!o->isBox())
389 return false;
390
391 FloatPoint localPoint = o->absoluteToLocal(absPoint, false, true); // respect transforms
392 return toRenderBox(o)->borderBoxRect().contains(roundedIntPoint(localPoint));
393 }
394 #endif
395
activeSelectionBackgroundColor() const396 Color RenderTheme::activeSelectionBackgroundColor() const
397 {
398 if (!m_activeSelectionBackgroundColor.isValid())
399 m_activeSelectionBackgroundColor = platformActiveSelectionBackgroundColor().blendWithWhite();
400 return m_activeSelectionBackgroundColor;
401 }
402
inactiveSelectionBackgroundColor() const403 Color RenderTheme::inactiveSelectionBackgroundColor() const
404 {
405 if (!m_inactiveSelectionBackgroundColor.isValid())
406 m_inactiveSelectionBackgroundColor = platformInactiveSelectionBackgroundColor().blendWithWhite();
407 return m_inactiveSelectionBackgroundColor;
408 }
409
activeSelectionForegroundColor() const410 Color RenderTheme::activeSelectionForegroundColor() const
411 {
412 if (!m_activeSelectionForegroundColor.isValid() && supportsSelectionForegroundColors())
413 m_activeSelectionForegroundColor = platformActiveSelectionForegroundColor();
414 return m_activeSelectionForegroundColor;
415 }
416
inactiveSelectionForegroundColor() const417 Color RenderTheme::inactiveSelectionForegroundColor() const
418 {
419 if (!m_inactiveSelectionForegroundColor.isValid() && supportsSelectionForegroundColors())
420 m_inactiveSelectionForegroundColor = platformInactiveSelectionForegroundColor();
421 return m_inactiveSelectionForegroundColor;
422 }
423
activeListBoxSelectionBackgroundColor() const424 Color RenderTheme::activeListBoxSelectionBackgroundColor() const
425 {
426 if (!m_activeListBoxSelectionBackgroundColor.isValid())
427 m_activeListBoxSelectionBackgroundColor = platformActiveListBoxSelectionBackgroundColor();
428 return m_activeListBoxSelectionBackgroundColor;
429 }
430
inactiveListBoxSelectionBackgroundColor() const431 Color RenderTheme::inactiveListBoxSelectionBackgroundColor() const
432 {
433 if (!m_inactiveListBoxSelectionBackgroundColor.isValid())
434 m_inactiveListBoxSelectionBackgroundColor = platformInactiveListBoxSelectionBackgroundColor();
435 return m_inactiveListBoxSelectionBackgroundColor;
436 }
437
activeListBoxSelectionForegroundColor() const438 Color RenderTheme::activeListBoxSelectionForegroundColor() const
439 {
440 if (!m_activeListBoxSelectionForegroundColor.isValid() && supportsListBoxSelectionForegroundColors())
441 m_activeListBoxSelectionForegroundColor = platformActiveListBoxSelectionForegroundColor();
442 return m_activeListBoxSelectionForegroundColor;
443 }
444
inactiveListBoxSelectionForegroundColor() const445 Color RenderTheme::inactiveListBoxSelectionForegroundColor() const
446 {
447 if (!m_inactiveListBoxSelectionForegroundColor.isValid() && supportsListBoxSelectionForegroundColors())
448 m_inactiveListBoxSelectionForegroundColor = platformInactiveListBoxSelectionForegroundColor();
449 return m_inactiveListBoxSelectionForegroundColor;
450 }
451
platformActiveSelectionBackgroundColor() const452 Color RenderTheme::platformActiveSelectionBackgroundColor() const
453 {
454 // Use a blue color by default if the platform theme doesn't define anything.
455 return Color(0, 0, 255);
456 }
457
platformActiveSelectionForegroundColor() const458 Color RenderTheme::platformActiveSelectionForegroundColor() const
459 {
460 // Use a white color by default if the platform theme doesn't define anything.
461 return Color::white;
462 }
463
platformInactiveSelectionBackgroundColor() const464 Color RenderTheme::platformInactiveSelectionBackgroundColor() const
465 {
466 // Use a grey color by default if the platform theme doesn't define anything.
467 // This color matches Firefox's inactive color.
468 return Color(176, 176, 176);
469 }
470
platformInactiveSelectionForegroundColor() const471 Color RenderTheme::platformInactiveSelectionForegroundColor() const
472 {
473 // Use a black color by default.
474 return Color::black;
475 }
476
platformActiveListBoxSelectionBackgroundColor() const477 Color RenderTheme::platformActiveListBoxSelectionBackgroundColor() const
478 {
479 return platformActiveSelectionBackgroundColor();
480 }
481
platformActiveListBoxSelectionForegroundColor() const482 Color RenderTheme::platformActiveListBoxSelectionForegroundColor() const
483 {
484 return platformActiveSelectionForegroundColor();
485 }
486
platformInactiveListBoxSelectionBackgroundColor() const487 Color RenderTheme::platformInactiveListBoxSelectionBackgroundColor() const
488 {
489 return platformInactiveSelectionBackgroundColor();
490 }
491
platformInactiveListBoxSelectionForegroundColor() const492 Color RenderTheme::platformInactiveListBoxSelectionForegroundColor() const
493 {
494 return platformInactiveSelectionForegroundColor();
495 }
496
baselinePosition(const RenderObject * o) const497 int RenderTheme::baselinePosition(const RenderObject* o) const
498 {
499 if (!o->isBox())
500 return 0;
501
502 const RenderBox* box = toRenderBox(o);
503
504 #if USE(NEW_THEME)
505 return box->height() + box->marginTop() + m_theme->baselinePositionAdjustment(o->style()->appearance()) * o->style()->effectiveZoom();
506 #else
507 return box->height() + box->marginTop();
508 #endif
509 }
510
isControlContainer(ControlPart appearance) const511 bool RenderTheme::isControlContainer(ControlPart appearance) const
512 {
513 // There are more leaves than this, but we'll patch this function as we add support for
514 // more controls.
515 return appearance != CheckboxPart && appearance != RadioPart;
516 }
517
isControlStyled(const RenderStyle * style,const BorderData & border,const FillLayer & background,const Color & backgroundColor) const518 bool RenderTheme::isControlStyled(const RenderStyle* style, const BorderData& border, const FillLayer& background,
519 const Color& backgroundColor) const
520 {
521 switch (style->appearance()) {
522 case PushButtonPart:
523 case SquareButtonPart:
524 case DefaultButtonPart:
525 case ButtonPart:
526 case ListboxPart:
527 case MenulistPart:
528 // FIXME: Uncomment this when making search fields style-able.
529 // case SearchFieldPart:
530 case TextFieldPart:
531 case TextAreaPart:
532 // Test the style to see if the UA border and background match.
533 return (style->border() != border ||
534 *style->backgroundLayers() != background ||
535 style->backgroundColor() != backgroundColor);
536 default:
537 return false;
538 }
539 }
540
adjustRepaintRect(const RenderObject * o,IntRect & r)541 void RenderTheme::adjustRepaintRect(const RenderObject* o, IntRect& r)
542 {
543 #if USE(NEW_THEME)
544 m_theme->inflateControlPaintRect(o->style()->appearance(), controlStatesForRenderer(o), r, o->style()->effectiveZoom());
545 #endif
546 }
547
supportsFocusRing(const RenderStyle * style) const548 bool RenderTheme::supportsFocusRing(const RenderStyle* style) const
549 {
550 return (style->hasAppearance() && style->appearance() != TextFieldPart && style->appearance() != TextAreaPart && style->appearance() != MenulistButtonPart && style->appearance() != ListboxPart);
551 }
552
stateChanged(RenderObject * o,ControlState state) const553 bool RenderTheme::stateChanged(RenderObject* o, ControlState state) const
554 {
555 // Default implementation assumes the controls dont respond to changes in :hover state
556 if (state == HoverState && !supportsHover(o->style()))
557 return false;
558
559 // Assume pressed state is only responded to if the control is enabled.
560 if (state == PressedState && !isEnabled(o))
561 return false;
562
563 // Repaint the control.
564 o->repaint();
565 return true;
566 }
567
controlStatesForRenderer(const RenderObject * o) const568 ControlStates RenderTheme::controlStatesForRenderer(const RenderObject* o) const
569 {
570 ControlStates result = 0;
571 if (isHovered(o))
572 result |= HoverState;
573 if (isPressed(o))
574 result |= PressedState;
575 if (isFocused(o) && o->style()->outlineStyleIsAuto())
576 result |= FocusState;
577 if (isEnabled(o))
578 result |= EnabledState;
579 if (isChecked(o))
580 result |= CheckedState;
581 if (isReadOnlyControl(o))
582 result |= ReadOnlyState;
583 if (isDefault(o))
584 result |= DefaultState;
585 if (!isActive(o))
586 result |= WindowInactiveState;
587 if (isIndeterminate(o))
588 result |= IndeterminateState;
589 return result;
590 }
591
isActive(const RenderObject * o) const592 bool RenderTheme::isActive(const RenderObject* o) const
593 {
594 Node* node = o->node();
595 if (!node)
596 return false;
597
598 Frame* frame = node->document()->frame();
599 if (!frame)
600 return false;
601
602 Page* page = frame->page();
603 if (!page)
604 return false;
605
606 return page->focusController()->isActive();
607 }
608
isChecked(const RenderObject * o) const609 bool RenderTheme::isChecked(const RenderObject* o) const
610 {
611 if (!o->node() || !o->node()->isElementNode())
612 return false;
613
614 InputElement* inputElement = toInputElement(static_cast<Element*>(o->node()));
615 if (!inputElement)
616 return false;
617
618 return inputElement->isChecked();
619 }
620
isIndeterminate(const RenderObject * o) const621 bool RenderTheme::isIndeterminate(const RenderObject* o) const
622 {
623 if (!o->node() || !o->node()->isElementNode())
624 return false;
625
626 InputElement* inputElement = toInputElement(static_cast<Element*>(o->node()));
627 if (!inputElement)
628 return false;
629
630 return inputElement->isIndeterminate();
631 }
632
isEnabled(const RenderObject * o) const633 bool RenderTheme::isEnabled(const RenderObject* o) const
634 {
635 Node* node = o->node();
636 if (!node || !node->isElementNode())
637 return true;
638 return static_cast<Element*>(node)->isEnabledFormControl();
639 }
640
isFocused(const RenderObject * o) const641 bool RenderTheme::isFocused(const RenderObject* o) const
642 {
643 Node* node = o->node();
644 if (!node)
645 return false;
646 Document* document = node->document();
647 Frame* frame = document->frame();
648 return node == document->focusedNode() && frame && frame->selection()->isFocusedAndActive();
649 }
650
isPressed(const RenderObject * o) const651 bool RenderTheme::isPressed(const RenderObject* o) const
652 {
653 if (!o->node())
654 return false;
655 return o->node()->active();
656 }
657
isReadOnlyControl(const RenderObject * o) const658 bool RenderTheme::isReadOnlyControl(const RenderObject* o) const
659 {
660 Node* node = o->node();
661 if (!node || !node->isElementNode())
662 return false;
663 return static_cast<Element*>(node)->isReadOnlyFormControl();
664 }
665
isHovered(const RenderObject * o) const666 bool RenderTheme::isHovered(const RenderObject* o) const
667 {
668 if (!o->node())
669 return false;
670 return o->node()->hovered();
671 }
672
isDefault(const RenderObject * o) const673 bool RenderTheme::isDefault(const RenderObject* o) const
674 {
675 if (!o->document())
676 return false;
677
678 Settings* settings = o->document()->settings();
679 if (!settings || !settings->inApplicationChromeMode())
680 return false;
681
682 return o->style()->appearance() == DefaultButtonPart;
683 }
684
685 #if !USE(NEW_THEME)
686
adjustCheckboxStyle(CSSStyleSelector *,RenderStyle * style,Element *) const687 void RenderTheme::adjustCheckboxStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
688 {
689 // A summary of the rules for checkbox designed to match WinIE:
690 // width/height - honored (WinIE actually scales its control for small widths, but lets it overflow for small heights.)
691 // font-size - not honored (control has no text), but we use it to decide which control size to use.
692 setCheckboxSize(style);
693
694 // padding - not honored by WinIE, needs to be removed.
695 style->resetPadding();
696
697 // border - honored by WinIE, but looks terrible (just paints in the control box and turns off the Windows XP theme)
698 // for now, we will not honor it.
699 style->resetBorder();
700
701 style->setBoxShadow(0);
702 }
703
adjustRadioStyle(CSSStyleSelector *,RenderStyle * style,Element *) const704 void RenderTheme::adjustRadioStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
705 {
706 // A summary of the rules for checkbox designed to match WinIE:
707 // width/height - honored (WinIE actually scales its control for small widths, but lets it overflow for small heights.)
708 // font-size - not honored (control has no text), but we use it to decide which control size to use.
709 setRadioSize(style);
710
711 // padding - not honored by WinIE, needs to be removed.
712 style->resetPadding();
713
714 // border - honored by WinIE, but looks terrible (just paints in the control box and turns off the Windows XP theme)
715 // for now, we will not honor it.
716 style->resetBorder();
717
718 style->setBoxShadow(0);
719 }
720
adjustButtonStyle(CSSStyleSelector *,RenderStyle * style,Element *) const721 void RenderTheme::adjustButtonStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
722 {
723 // Most platforms will completely honor all CSS, and so we have no need to adjust the style
724 // at all by default. We will still allow the theme a crack at setting up a desired vertical size.
725 setButtonSize(style);
726 }
727
728 #endif
729
adjustTextFieldStyle(CSSStyleSelector *,RenderStyle *,Element *) const730 void RenderTheme::adjustTextFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const
731 {
732 }
733
adjustTextAreaStyle(CSSStyleSelector *,RenderStyle *,Element *) const734 void RenderTheme::adjustTextAreaStyle(CSSStyleSelector*, RenderStyle*, Element*) const
735 {
736 }
737
adjustMenuListStyle(CSSStyleSelector *,RenderStyle *,Element *) const738 void RenderTheme::adjustMenuListStyle(CSSStyleSelector*, RenderStyle*, Element*) const
739 {
740 }
741
adjustMenuListButtonStyle(CSSStyleSelector *,RenderStyle *,Element *) const742 void RenderTheme::adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const
743 {
744 }
745
adjustSliderTrackStyle(CSSStyleSelector *,RenderStyle *,Element *) const746 void RenderTheme::adjustSliderTrackStyle(CSSStyleSelector*, RenderStyle*, Element*) const
747 {
748 }
749
adjustSliderThumbStyle(CSSStyleSelector *,RenderStyle *,Element *) const750 void RenderTheme::adjustSliderThumbStyle(CSSStyleSelector*, RenderStyle*, Element*) const
751 {
752 }
753
adjustSliderThumbSize(RenderObject *) const754 void RenderTheme::adjustSliderThumbSize(RenderObject*) const
755 {
756 }
757
adjustSearchFieldStyle(CSSStyleSelector *,RenderStyle *,Element *) const758 void RenderTheme::adjustSearchFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const
759 {
760 }
761
adjustSearchFieldCancelButtonStyle(CSSStyleSelector *,RenderStyle *,Element *) const762 void RenderTheme::adjustSearchFieldCancelButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const
763 {
764 }
765
adjustSearchFieldDecorationStyle(CSSStyleSelector *,RenderStyle *,Element *) const766 void RenderTheme::adjustSearchFieldDecorationStyle(CSSStyleSelector*, RenderStyle*, Element*) const
767 {
768 }
769
adjustSearchFieldResultsDecorationStyle(CSSStyleSelector *,RenderStyle *,Element *) const770 void RenderTheme::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector*, RenderStyle*, Element*) const
771 {
772 }
773
adjustSearchFieldResultsButtonStyle(CSSStyleSelector *,RenderStyle *,Element *) const774 void RenderTheme::adjustSearchFieldResultsButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const
775 {
776 }
777
platformColorsDidChange()778 void RenderTheme::platformColorsDidChange()
779 {
780 m_activeSelectionForegroundColor = Color();
781 m_inactiveSelectionForegroundColor = Color();
782 m_activeSelectionBackgroundColor = Color();
783 m_inactiveSelectionBackgroundColor = Color();
784
785 m_activeListBoxSelectionForegroundColor = Color();
786 m_inactiveListBoxSelectionForegroundColor = Color();
787 m_activeListBoxSelectionBackgroundColor = Color();
788 m_inactiveListBoxSelectionForegroundColor = Color();
789 }
790
systemColor(int cssValueId) const791 Color RenderTheme::systemColor(int cssValueId) const
792 {
793 switch (cssValueId) {
794 case CSSValueActiveborder:
795 return 0xFFFFFFFF;
796 case CSSValueActivecaption:
797 return 0xFFCCCCCC;
798 case CSSValueAppworkspace:
799 return 0xFFFFFFFF;
800 case CSSValueBackground:
801 return 0xFF6363CE;
802 case CSSValueButtonface:
803 return 0xFFC0C0C0;
804 case CSSValueButtonhighlight:
805 return 0xFFDDDDDD;
806 case CSSValueButtonshadow:
807 return 0xFF888888;
808 case CSSValueButtontext:
809 return 0xFF000000;
810 case CSSValueCaptiontext:
811 return 0xFF000000;
812 case CSSValueGraytext:
813 return 0xFF808080;
814 case CSSValueHighlight:
815 return 0xFFB5D5FF;
816 case CSSValueHighlighttext:
817 return 0xFF000000;
818 case CSSValueInactiveborder:
819 return 0xFFFFFFFF;
820 case CSSValueInactivecaption:
821 return 0xFFFFFFFF;
822 case CSSValueInactivecaptiontext:
823 return 0xFF7F7F7F;
824 case CSSValueInfobackground:
825 return 0xFFFBFCC5;
826 case CSSValueInfotext:
827 return 0xFF000000;
828 case CSSValueMenu:
829 return 0xFFC0C0C0;
830 case CSSValueMenutext:
831 return 0xFF000000;
832 case CSSValueScrollbar:
833 return 0xFFFFFFFF;
834 case CSSValueText:
835 return 0xFF000000;
836 case CSSValueThreeddarkshadow:
837 return 0xFF666666;
838 case CSSValueThreedface:
839 return 0xFFC0C0C0;
840 case CSSValueThreedhighlight:
841 return 0xFFDDDDDD;
842 case CSSValueThreedlightshadow:
843 return 0xFFC0C0C0;
844 case CSSValueThreedshadow:
845 return 0xFF888888;
846 case CSSValueWindow:
847 return 0xFFFFFFFF;
848 case CSSValueWindowframe:
849 return 0xFFCCCCCC;
850 case CSSValueWindowtext:
851 return 0xFF000000;
852 }
853 return Color();
854 }
855
platformActiveTextSearchHighlightColor() const856 Color RenderTheme::platformActiveTextSearchHighlightColor() const
857 {
858 return Color(255, 150, 50); // Orange.
859 }
860
platformInactiveTextSearchHighlightColor() const861 Color RenderTheme::platformInactiveTextSearchHighlightColor() const
862 {
863 return Color(255, 255, 0); // Yellow.
864 }
865
setCustomFocusRingColor(const Color & c)866 void RenderTheme::setCustomFocusRingColor(const Color& c)
867 {
868 customFocusRingColor() = c;
869 }
870
focusRingColor()871 Color RenderTheme::focusRingColor()
872 {
873 return customFocusRingColor().isValid() ? customFocusRingColor() : defaultTheme()->platformFocusRingColor();
874 }
875
876 } // namespace WebCore
877