WebCore: https://bugs.webkit.org/show_bug.cgi?id=39420, :visited not working with...
authorhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 21 May 2010 20:56:24 +0000 (20:56 +0000)
committerhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 21 May 2010 20:56:24 +0000 (20:56 +0000)
Reviewed by Dan Bernstein.

Make the RenderStyle color accessors private.  This forces callers to use visitedDependentColor
instead (or to make the decision to become friends of the RenderStyle class in order to get access
to the real style information).

Modified history/self-is-visited.html to also test background colors.

* WebCore.base.exp:
* accessibility/AccessibilityTable.cpp:
(WebCore::AccessibilityTable::isTableExposableThroughAccessibility):
* accessibility/mac/AccessibilityObjectWrapper.mm:
(AXAttributeStringSetStyle):
* css/CSSComputedStyleDeclaration.cpp:
(WebCore::CSSComputedStyleDeclaration::currentColorOrValidColor):
* css/CSSComputedStyleDeclaration.h:
* css/SVGCSSStyleSelector.cpp:
(WebCore::colorFromSVGColorCSSValue):
* editing/ApplyStyleCommand.cpp:
(WebCore::ApplyStyleCommand::editingStyleAtPosition):
(WebCore::prepareEditingStyleToApplyAt):
(WebCore::removeStylesAddedByNode):
(WebCore::fontColorChangesComputedStyle):
(WebCore::ApplyStyleCommand::addInlineStyleIfNeeded):
* editing/ApplyStyleCommand.h:
(WebCore::):
* editing/CompositeEditCommand.cpp:
(WebCore::CompositeEditCommand::moveParagraphs):
(WebCore::CompositeEditCommand::breakOutOfEmptyListItem):
* editing/DeleteButtonController.cpp:
(WebCore::isDeletableElement):
* editing/DeleteSelectionCommand.cpp:
(WebCore::DeleteSelectionCommand::saveTypingStyleState):
* editing/InsertParagraphSeparatorCommand.cpp:
(WebCore::InsertParagraphSeparatorCommand::calculateStyleBeforeInsertion):
* editing/RemoveFormatCommand.cpp:
(WebCore::RemoveFormatCommand::doApply):
* editing/ReplaceSelectionCommand.cpp:
(WebCore::handleStyleSpansBeforeInsertion):
(WebCore::ReplaceSelectionCommand::handleStyleSpans):
(WebCore::ReplaceSelectionCommand::doApply):
* editing/SelectionController.cpp:
(WebCore::SelectionController::paintCaret):
* editing/markup.cpp:
(WebCore::createMarkup):
* page/animation/AnimationBase.cpp:
(WebCore::AnimationBase::ensurePropertyMap):
* page/animation/AnimationBase.h:
* page/mac/FrameMac.mm:
(WebCore::Frame::fontAttributesForSelectionStart):
* rendering/EllipsisBox.cpp:
(WebCore::EllipsisBox::paint):
(WebCore::EllipsisBox::paintSelection):
* rendering/InlineTextBox.cpp:
(WebCore::InlineTextBox::paint):
* rendering/RenderBox.cpp:
(WebCore::RenderBox::styleDidChange):
(WebCore::RenderBox::paintRootBoxDecorations):
(WebCore::RenderBox::paintBoxDecorationsWithSize):
* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::paintBoxShadow):
* rendering/RenderFieldset.cpp:
(WebCore::RenderFieldset::paintBoxDecorations):
* rendering/RenderFileUploadControl.cpp:
(WebCore::RenderFileUploadControl::paintObject):
* rendering/RenderFrameSet.cpp:
(WebCore::RenderFrameSet::paintColumnBorder):
(WebCore::RenderFrameSet::paintRowBorder):
* rendering/RenderImage.cpp:
(WebCore::RenderImage::paintReplaced):
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::rendererBackgroundColor):
* rendering/RenderLayerBacking.h:
* rendering/RenderListBox.cpp:
(WebCore::RenderListBox::paintItemForeground):
(WebCore::RenderListBox::paintItemBackground):
* rendering/RenderListMarker.cpp:
(WebCore::RenderListMarker::paint):
* rendering/RenderMenuList.cpp:
(WebCore::RenderMenuList::itemStyle):
(WebCore::RenderMenuList::itemBackgroundColor):
(WebCore::RenderMenuList::menuStyle):
* rendering/RenderObject.cpp:
(WebCore::RenderObject::selectionBackgroundColor):
(WebCore::RenderObject::selectionForegroundColor):
* rendering/RenderSVGResource.cpp:
(WebCore::RenderSVGResource::adjustColorForPseudoRules):
(WebCore::RenderSVGResource::fillPaintingResource):
(WebCore::RenderSVGResource::strokePaintingResource):
* rendering/RenderSVGResource.h:
* rendering/RenderTable.cpp:
(WebCore::RenderTable::paintBoxDecorations):
* rendering/RenderTable.h:
(WebCore::RenderTable::bgColor):
* rendering/RenderTableCell.cpp:
(WebCore::RenderTableCell::paintBackgroundsBehindCell):
* rendering/RenderTextControl.cpp:
(WebCore::RenderTextControl::adjustInnerTextStyle):
* rendering/RenderTextControlSingleLine.cpp:
(WebCore::RenderTextControlSingleLine::menuStyle):
* rendering/RenderTheme.cpp:
(WebCore::RenderTheme::isControlStyled):
* rendering/RenderThemeMac.mm:
(WebCore::RenderThemeMac::paintMenuListButton):
* rendering/RenderTreeAsText.cpp:
(WebCore::RenderTreeAsText::writeRenderObject):
(WebCore::write):
* rendering/RenderTreeAsText.h:
* rendering/SVGInlineTextBox.cpp:
(WebCore::SVGInlineTextBox::paintSelection):
* rendering/SVGRenderTreeAsText.cpp:
(WebCore::writeRenderSVGTextBox):
* rendering/style/RenderStyle.cpp:
(WebCore::RenderStyle::colorIncludingFallback):
(WebCore::RenderStyle::visitedDependentColor):
* rendering/style/RenderStyle.h:
(WebCore::):
(WebCore::InheritedFlags::hasBackground):
(WebCore::InheritedFlags::borderLeftStyle):
(WebCore::InheritedFlags::borderRightStyle):
(WebCore::InheritedFlags::borderTopStyle):
(WebCore::InheritedFlags::borderBottomStyle):
(WebCore::InheritedFlags::textShadow):
(WebCore::InheritedFlags::textStrokeWidth):
(WebCore::InheritedFlags::hasNormalColumnGap):
(WebCore::InheritedFlags::borderLeftColor):
(WebCore::InheritedFlags::borderRightColor):
(WebCore::InheritedFlags::borderTopColor):
(WebCore::InheritedFlags::borderBottomColor):
(WebCore::InheritedFlags::backgroundColor):
(WebCore::InheritedFlags::color):
(WebCore::InheritedFlags::columnRuleColor):
(WebCore::InheritedFlags::outlineColor):
(WebCore::InheritedFlags::textFillColor):
(WebCore::InheritedFlags::textStrokeColor):
* svg/SVGAnimationElement.cpp:
(WebCore::adjustForCurrentColor):

WebKit/mac: https://bugs.webkit.org/show_bug.cgi?id=39420

Reviewed by Dan Bernstein.

Make sure everyone who needs to is using visitedDependentColor rather than accessing styles
directly.

* Misc/WebNSAttributedStringExtras.mm:
(+[NSAttributedString _web_attributedStringFromRange:]):
* WebView/WebFrame.mm:
(-[WebFrame _bodyBackgroundColor]):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@59956 268f45cc-cd09-0410-ab3c-d52691b4dbfc

57 files changed:
LayoutTests/fast/history/self-is-visited.html
WebCore/ChangeLog
WebCore/WebCore.base.exp
WebCore/accessibility/AccessibilityTable.cpp
WebCore/accessibility/mac/AccessibilityObjectWrapper.mm
WebCore/css/CSSComputedStyleDeclaration.cpp
WebCore/css/CSSComputedStyleDeclaration.h
WebCore/css/SVGCSSStyleSelector.cpp
WebCore/editing/ApplyStyleCommand.cpp
WebCore/editing/ApplyStyleCommand.h
WebCore/editing/CompositeEditCommand.cpp
WebCore/editing/DeleteButtonController.cpp
WebCore/editing/DeleteSelectionCommand.cpp
WebCore/editing/InsertParagraphSeparatorCommand.cpp
WebCore/editing/RemoveFormatCommand.cpp
WebCore/editing/ReplaceSelectionCommand.cpp
WebCore/editing/SelectionController.cpp
WebCore/editing/markup.cpp
WebCore/page/animation/AnimationBase.cpp
WebCore/page/animation/AnimationBase.h
WebCore/page/mac/FrameMac.mm
WebCore/rendering/EllipsisBox.cpp
WebCore/rendering/InlineTextBox.cpp
WebCore/rendering/RenderBox.cpp
WebCore/rendering/RenderBoxModelObject.cpp
WebCore/rendering/RenderFieldset.cpp
WebCore/rendering/RenderFileUploadControl.cpp
WebCore/rendering/RenderFrameSet.cpp
WebCore/rendering/RenderImage.cpp
WebCore/rendering/RenderLayerBacking.cpp
WebCore/rendering/RenderLayerBacking.h
WebCore/rendering/RenderListBox.cpp
WebCore/rendering/RenderListMarker.cpp
WebCore/rendering/RenderMediaControlsChromium.cpp
WebCore/rendering/RenderMenuList.cpp
WebCore/rendering/RenderObject.cpp
WebCore/rendering/RenderObject.h
WebCore/rendering/RenderSVGResource.cpp
WebCore/rendering/RenderSVGResource.h
WebCore/rendering/RenderTable.cpp
WebCore/rendering/RenderTable.h
WebCore/rendering/RenderTableCell.cpp
WebCore/rendering/RenderTextControl.cpp
WebCore/rendering/RenderTextControlSingleLine.cpp
WebCore/rendering/RenderTheme.cpp
WebCore/rendering/RenderThemeChromiumSkia.cpp
WebCore/rendering/RenderThemeMac.mm
WebCore/rendering/RenderTreeAsText.cpp
WebCore/rendering/RenderTreeAsText.h
WebCore/rendering/SVGInlineTextBox.cpp
WebCore/rendering/SVGRenderTreeAsText.cpp
WebCore/rendering/style/RenderStyle.cpp
WebCore/rendering/style/RenderStyle.h
WebCore/svg/SVGAnimationElement.cpp
WebKit/mac/ChangeLog
WebKit/mac/Misc/WebNSAttributedStringExtras.mm
WebKit/mac/WebView/WebFrame.mm

index fb598b7..6d7a5bf 100644 (file)
@@ -11,7 +11,7 @@ function compareStyles()
     if (window.layoutTestController) {
         var firstStyle = window.layoutTestController.computedStyleIncludingVisitedInfo(document.getElementById('one'));
         var secondStyle = window.layoutTestController.computedStyleIncludingVisitedInfo(document.getElementById('two'));
-        if (firstStyle.color == secondStyle.color) {
+        if (firstStyle.color == secondStyle.color || firstStyle.backgroundColor == secondStyle.backgroundColor) {
             document.getElementById('result').innerHTML = 'FAIL';
             return;
         }
@@ -19,15 +19,15 @@ function compareStyles()
     
     var firstStyle = window.getComputedStyle(document.getElementById('one'), "");
     var secondStyle = window.getComputedStyle(document.getElementById('two'), "");
-    if (firstStyle.color != secondStyle.color) {
+    if (firstStyle.color != secondStyle.color || firstStyle.backgroundColor != secondStyle.backgroundColor) {
         document.getElementById('result').innerHTML = 'FAIL';
         return;
     }
 }
 </script>
 <style>
-:link { color: green }
-:visited { color: orange }
+:link { color: green; background-color: white }
+:visited { color: orange; background-color: black }
 </style>
 </head>
 <body onload="compareStyles()">
index 39f55c7..d2de1c8 100644 (file)
@@ -1,3 +1,145 @@
+2010-05-21  David Hyatt  <hyatt@apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        https://bugs.webkit.org/show_bug.cgi?id=39420, :visited not working with background-color.
+
+        Make the RenderStyle color accessors private.  This forces callers to use visitedDependentColor
+        instead (or to make the decision to become friends of the RenderStyle class in order to get access
+        to the real style information).
+
+        Modified history/self-is-visited.html to also test background colors.
+
+        * WebCore.base.exp:
+        * accessibility/AccessibilityTable.cpp:
+        (WebCore::AccessibilityTable::isTableExposableThroughAccessibility):
+        * accessibility/mac/AccessibilityObjectWrapper.mm:
+        (AXAttributeStringSetStyle):
+        * css/CSSComputedStyleDeclaration.cpp:
+        (WebCore::CSSComputedStyleDeclaration::currentColorOrValidColor):
+        * css/CSSComputedStyleDeclaration.h:
+        * css/SVGCSSStyleSelector.cpp:
+        (WebCore::colorFromSVGColorCSSValue):
+        * editing/ApplyStyleCommand.cpp:
+        (WebCore::ApplyStyleCommand::editingStyleAtPosition):
+        (WebCore::prepareEditingStyleToApplyAt):
+        (WebCore::removeStylesAddedByNode):
+        (WebCore::fontColorChangesComputedStyle):
+        (WebCore::ApplyStyleCommand::addInlineStyleIfNeeded):
+        * editing/ApplyStyleCommand.h:
+        (WebCore::):
+        * editing/CompositeEditCommand.cpp:
+        (WebCore::CompositeEditCommand::moveParagraphs):
+        (WebCore::CompositeEditCommand::breakOutOfEmptyListItem):
+        * editing/DeleteButtonController.cpp:
+        (WebCore::isDeletableElement):
+        * editing/DeleteSelectionCommand.cpp:
+        (WebCore::DeleteSelectionCommand::saveTypingStyleState):
+        * editing/InsertParagraphSeparatorCommand.cpp:
+        (WebCore::InsertParagraphSeparatorCommand::calculateStyleBeforeInsertion):
+        * editing/RemoveFormatCommand.cpp:
+        (WebCore::RemoveFormatCommand::doApply):
+        * editing/ReplaceSelectionCommand.cpp:
+        (WebCore::handleStyleSpansBeforeInsertion):
+        (WebCore::ReplaceSelectionCommand::handleStyleSpans):
+        (WebCore::ReplaceSelectionCommand::doApply):
+        * editing/SelectionController.cpp:
+        (WebCore::SelectionController::paintCaret):
+        * editing/markup.cpp:
+        (WebCore::createMarkup):
+        * page/animation/AnimationBase.cpp:
+        (WebCore::AnimationBase::ensurePropertyMap):
+        * page/animation/AnimationBase.h:
+        * page/mac/FrameMac.mm:
+        (WebCore::Frame::fontAttributesForSelectionStart):
+        * rendering/EllipsisBox.cpp:
+        (WebCore::EllipsisBox::paint):
+        (WebCore::EllipsisBox::paintSelection):
+        * rendering/InlineTextBox.cpp:
+        (WebCore::InlineTextBox::paint):
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::styleDidChange):
+        (WebCore::RenderBox::paintRootBoxDecorations):
+        (WebCore::RenderBox::paintBoxDecorationsWithSize):
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::RenderBoxModelObject::paintBoxShadow):
+        * rendering/RenderFieldset.cpp:
+        (WebCore::RenderFieldset::paintBoxDecorations):
+        * rendering/RenderFileUploadControl.cpp:
+        (WebCore::RenderFileUploadControl::paintObject):
+        * rendering/RenderFrameSet.cpp:
+        (WebCore::RenderFrameSet::paintColumnBorder):
+        (WebCore::RenderFrameSet::paintRowBorder):
+        * rendering/RenderImage.cpp:
+        (WebCore::RenderImage::paintReplaced):
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::rendererBackgroundColor):
+        * rendering/RenderLayerBacking.h:
+        * rendering/RenderListBox.cpp:
+        (WebCore::RenderListBox::paintItemForeground):
+        (WebCore::RenderListBox::paintItemBackground):
+        * rendering/RenderListMarker.cpp:
+        (WebCore::RenderListMarker::paint):
+        * rendering/RenderMenuList.cpp:
+        (WebCore::RenderMenuList::itemStyle):
+        (WebCore::RenderMenuList::itemBackgroundColor):
+        (WebCore::RenderMenuList::menuStyle):
+        * rendering/RenderObject.cpp:
+        (WebCore::RenderObject::selectionBackgroundColor):
+        (WebCore::RenderObject::selectionForegroundColor):
+        * rendering/RenderSVGResource.cpp:
+        (WebCore::RenderSVGResource::adjustColorForPseudoRules):
+        (WebCore::RenderSVGResource::fillPaintingResource):
+        (WebCore::RenderSVGResource::strokePaintingResource):
+        * rendering/RenderSVGResource.h:
+        * rendering/RenderTable.cpp:
+        (WebCore::RenderTable::paintBoxDecorations):
+        * rendering/RenderTable.h:
+        (WebCore::RenderTable::bgColor):
+        * rendering/RenderTableCell.cpp:
+        (WebCore::RenderTableCell::paintBackgroundsBehindCell):
+        * rendering/RenderTextControl.cpp:
+        (WebCore::RenderTextControl::adjustInnerTextStyle):
+        * rendering/RenderTextControlSingleLine.cpp:
+        (WebCore::RenderTextControlSingleLine::menuStyle):
+        * rendering/RenderTheme.cpp:
+        (WebCore::RenderTheme::isControlStyled):
+        * rendering/RenderThemeMac.mm:
+        (WebCore::RenderThemeMac::paintMenuListButton):
+        * rendering/RenderTreeAsText.cpp:
+        (WebCore::RenderTreeAsText::writeRenderObject):
+        (WebCore::write):
+        * rendering/RenderTreeAsText.h:
+        * rendering/SVGInlineTextBox.cpp:
+        (WebCore::SVGInlineTextBox::paintSelection):
+        * rendering/SVGRenderTreeAsText.cpp:
+        (WebCore::writeRenderSVGTextBox):
+        * rendering/style/RenderStyle.cpp:
+        (WebCore::RenderStyle::colorIncludingFallback):
+        (WebCore::RenderStyle::visitedDependentColor):
+        * rendering/style/RenderStyle.h:
+        (WebCore::):
+        (WebCore::InheritedFlags::hasBackground):
+        (WebCore::InheritedFlags::borderLeftStyle):
+        (WebCore::InheritedFlags::borderRightStyle):
+        (WebCore::InheritedFlags::borderTopStyle):
+        (WebCore::InheritedFlags::borderBottomStyle):
+        (WebCore::InheritedFlags::textShadow):
+        (WebCore::InheritedFlags::textStrokeWidth):
+        (WebCore::InheritedFlags::hasNormalColumnGap):
+        (WebCore::InheritedFlags::borderLeftColor):
+        (WebCore::InheritedFlags::borderRightColor):
+        (WebCore::InheritedFlags::borderTopColor):
+        (WebCore::InheritedFlags::borderBottomColor):
+        (WebCore::InheritedFlags::backgroundColor):
+        (WebCore::InheritedFlags::color):
+        (WebCore::InheritedFlags::columnRuleColor):
+        (WebCore::InheritedFlags::outlineColor):
+        (WebCore::InheritedFlags::textFillColor):
+        (WebCore::InheritedFlags::textStrokeColor):
+        * svg/SVGAnimationElement.cpp:
+        (WebCore::adjustForCurrentColor):
+
 2010-05-21  Beth Dakin  <bdakin@apple.com>
 
         Reviewed by Darin Adler.
index 3bc9f14..b555ded 100644 (file)
@@ -987,6 +987,7 @@ __ZNK7WebCore9FrameView20isSoftwareRenderableEv
 __ZNK7WebCore9FrameView28isEnclosedInCompositingLayerEv
 __ZNK7WebCore9PageCache10frameCountEv
 __ZNK7WebCore9PageCache21autoreleasedPageCountEv
+__ZNK7WebCore11RenderStyle21visitedDependentColorEi
 __ZTVN7WebCore12ChromeClientE
 __ZTVN7WebCore12PluginWidgetE
 __ZTVN7WebCore17FileChooserClientE
index aed8867..8e0562c 100644 (file)
@@ -126,7 +126,7 @@ bool AccessibilityTable::isTableExposableThroughAccessibility()
     RenderStyle* tableStyle = table->style();
     if (!tableStyle)
         return false;
-    Color tableBGColor = tableStyle->backgroundColor();
+    Color tableBGColor = tableStyle->visitedDependentColor(CSSPropertyBackgroundColor);
     
     // check enough of the cells to find if the table matches our criteria
     // Criteria: 
@@ -169,7 +169,7 @@ bool AccessibilityTable::isTableExposableThroughAccessibility()
             
             // if the cell has a different color from the table and there is cell spacing,
             // then it is probably a data table cell (spacing and colors take the place of borders)
-            Color cellColor = renderStyle->backgroundColor();
+            Color cellColor = renderStyle->visitedDependentColor(CSSPropertyBackgroundColor);
             if (table->hBorderSpacing() > 0 && table->vBorderSpacing() > 0
                 && tableBGColor != cellColor && cellColor.alpha() != 1)
                 backgroundDifferenceCellCount++;
index 97aaaf2..4734d4e 100644 (file)
@@ -315,8 +315,8 @@ static void AXAttributeStringSetStyle(NSMutableAttributedString* attrString, Ren
     AXAttributeStringSetFont(attrString, NSAccessibilityFontTextAttribute, style->font().primaryFont()->getNSFont(), range);
 
     // set basic colors
-    AXAttributeStringSetColor(attrString, NSAccessibilityForegroundColorTextAttribute, nsColor(style->color()), range);
-    AXAttributeStringSetColor(attrString, NSAccessibilityBackgroundColorTextAttribute, nsColor(style->backgroundColor()), range);
+    AXAttributeStringSetColor(attrString, NSAccessibilityForegroundColorTextAttribute, nsColor(style->visitedDependentColor(CSSPropertyColor)), range);
+    AXAttributeStringSetColor(attrString, NSAccessibilityBackgroundColorTextAttribute, nsColor(style->visitedDependentColor(CSSPropertyBackgroundColor)), range);
 
     // set super/sub scripting
     EVerticalAlign alignment = style->verticalAlign();
index ba503b8..b61a6b2 100644 (file)
@@ -374,8 +374,9 @@ static PassRefPtr<CSSValue> getPositionOffsetValue(RenderStyle* style, int prope
     return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
 }
 
-static PassRefPtr<CSSPrimitiveValue> currentColorOrValidColor(RenderStyle* style, const Color& color)
+PassRefPtr<CSSPrimitiveValue> CSSComputedStyleDeclaration::currentColorOrValidColor(RenderStyle* style, const Color& color) const
 {
+    // This function does NOT look at visited information, so that computed style doesn't expose that.
     if (!color.isValid())
         return CSSPrimitiveValue::createColor(style->color().rgb());
     return CSSPrimitiveValue::createColor(color.rgb());
index ba55d77..a2e8ba7 100644 (file)
@@ -27,7 +27,9 @@
 
 namespace WebCore {
 
+class Color;
 class CSSMutableStyleDeclaration;
+class CSSPrimitiveValue;
 class ShadowData;
 
 enum EUpdateLayout { DoNotUpdateLayout = false, UpdateLayout = true };
@@ -69,7 +71,8 @@ private:
     virtual void setProperty(int propertyId, const String& value, bool important, ExceptionCode&);
 
     PassRefPtr<CSSValue> valueForShadow(const ShadowData*, int) const;
-
+    PassRefPtr<CSSPrimitiveValue> currentColorOrValidColor(RenderStyle*, const Color&) const;
+    
     RefPtr<Node> m_node;
     PseudoId m_pseudoElementSpecifier;
     bool m_allowVisitedStyle;
index 75d48b7..1deb259 100644 (file)
@@ -90,13 +90,13 @@ static int angleToGlyphOrientation(float angle)
     return -1;
 }
 
-static Color colorFromSVGColorCSSValue(CSSValue* value, RenderStyle* style)
+static Color colorFromSVGColorCSSValue(CSSValue* value, const Color& fgColor)
 {
     ASSERT(value->isSVGColor());
     SVGColor* c = static_cast<SVGColor*>(value);
     Color color;
     if (c->colorType() == SVGColor::SVG_COLORTYPE_CURRENTCOLOR)
-        color = style->color();
+        color = fgColor;
     else
         color = c->color();
     return color;
@@ -454,13 +454,13 @@ void CSSStyleSelector::applySVGProperty(int id, CSSValue* value)
         case CSSPropertyStopColor:
         {
             HANDLE_INHERIT_AND_INITIAL(stopColor, StopColor);
-            svgstyle->setStopColor(colorFromSVGColorCSSValue(value, m_style.get()));
+            svgstyle->setStopColor(colorFromSVGColorCSSValue(value, m_style->color()));
             break;
         }
        case CSSPropertyLightingColor:
         {
             HANDLE_INHERIT_AND_INITIAL(lightingColor, LightingColor);
-            svgstyle->setLightingColor(colorFromSVGColorCSSValue(value, m_style.get()));
+            svgstyle->setLightingColor(colorFromSVGColorCSSValue(value, m_style->color()));
             break;
         }
         case CSSPropertyFloodOpacity:
@@ -487,7 +487,7 @@ void CSSStyleSelector::applySVGProperty(int id, CSSValue* value)
                 svgstyle->setFloodColor(SVGRenderStyle::initialFloodColor());
                 return;
             }
-            svgstyle->setFloodColor(colorFromSVGColorCSSValue(value, m_style.get()));
+            svgstyle->setFloodColor(colorFromSVGColorCSSValue(value, m_style->color()));
             break;
         }
         case CSSPropertyGlyphOrientationHorizontal:
index b6a0f66..c50c988 100644 (file)
@@ -416,7 +416,7 @@ static const int editingStyleProperties[] = {
 };
 size_t numEditingStyleProperties = sizeof(editingStyleProperties)/sizeof(editingStyleProperties[0]);
 
-PassRefPtr<CSSMutableStyleDeclaration> editingStyleAtPosition(Position pos, ShouldIncludeTypingStyle shouldIncludeTypingStyle)
+PassRefPtr<CSSMutableStyleDeclaration> ApplyStyleCommand::editingStyleAtPosition(Position pos, ShouldIncludeTypingStyle shouldIncludeTypingStyle)
 {
     RefPtr<CSSComputedStyleDeclaration> computedStyleAtPosition = pos.computedStyle();
     RefPtr<CSSMutableStyleDeclaration> style;
@@ -454,7 +454,7 @@ void prepareEditingStyleToApplyAt(CSSMutableStyleDeclaration* editingStyle, Posi
     // ReplaceSelectionCommand::handleStyleSpans() requires that this function only removes the editing style.
     // If this function was modified in the future to delete all redundant properties, then add a boolean value to indicate
     // which one of editingStyleAtPosition or computedStyle is called.
-    RefPtr<CSSMutableStyleDeclaration> style = editingStyleAtPosition(pos);
+    RefPtr<CSSMutableStyleDeclaration> style = ApplyStyleCommand::editingStyleAtPosition(pos);
     style->diff(editingStyle);
 
     // if alpha value is zero, we don't add the background color.
@@ -472,8 +472,8 @@ void removeStylesAddedByNode(CSSMutableStyleDeclaration* editingStyle, Node* nod
 {
     ASSERT(node);
     ASSERT(node->parentNode());
-    RefPtr<CSSMutableStyleDeclaration> parentStyle = editingStyleAtPosition(Position(node->parentNode(), 0));
-    RefPtr<CSSMutableStyleDeclaration> style = editingStyleAtPosition(Position(node, 0));
+    RefPtr<CSSMutableStyleDeclaration> parentStyle = ApplyStyleCommand::editingStyleAtPosition(Position(node->parentNode(), 0));
+    RefPtr<CSSMutableStyleDeclaration> style = ApplyStyleCommand::editingStyleAtPosition(Position(node, 0));
     parentStyle->diff(style.get());
     style->diff(editingStyle);
 }
@@ -1757,10 +1757,10 @@ void ApplyStyleCommand::addBlockStyle(const StyleChange& styleChange, HTMLElemen
     setNodeAttribute(block, styleAttr, cssText);
 }
 
-static bool fontColorChangesComputedStyle(RenderStyle* computedStyle, StyleChange styleChange)
+static bool fontColorChangesComputedStyle(const Color& computedStyleColor, StyleChange styleChange)
 {
     if (styleChange.applyFontColor()) {
-        if (Color(styleChange.fontColor()) != computedStyle->color())
+        if (Color(styleChange.fontColor()) != computedStyleColor)
             return true;
     }
     return false;
@@ -1801,7 +1801,7 @@ void ApplyStyleCommand::addInlineStyleIfNeeded(CSSMutableStyleDeclaration *style
         // We only want to insert a font element if it will end up changing the style of the
         // text somehow. Otherwise it will be a garbage node that will create problems for us
         // most notably when we apply a blockquote style for a message reply.
-        if (fontColorChangesComputedStyle(computedStyle, styleChange)
+        if (fontColorChangesComputedStyle(computedStyle->color(), styleChange)
                 || fontFaceChangesComputedStyle(computedStyle, styleChange)
                 || fontSizeChangesComputedStyle(computedStyle, styleChange)) {
             if (styleChange.applyFontColor())
index 2804604..8326329 100644 (file)
@@ -34,6 +34,11 @@ class CSSPrimitiveValue;
 class HTMLElement;
 class StyleChange;
 
+enum ShouldIncludeTypingStyle {
+    IncludeTypingStyle,
+    IgnoreTypingStyle
+};
+
 class ApplyStyleCommand : public CompositeEditCommand {
 public:
     enum EPropertyLevel { PropertyDefault, ForceBlockProperties };
@@ -50,6 +55,8 @@ public:
     {
         return adoptRef(new ApplyStyleCommand(element, removeOnly, action));
     }
+    
+    static PassRefPtr<CSSMutableStyleDeclaration> editingStyleAtPosition(Position pos, ShouldIncludeTypingStyle shouldIncludeTypingStyle = IgnoreTypingStyle);
 
 private:
     ApplyStyleCommand(Document*, CSSStyleDeclaration*, EditAction, EPropertyLevel);
@@ -117,12 +124,6 @@ bool isStyleSpan(const Node*);
 PassRefPtr<HTMLElement> createStyleSpanElement(Document*);
 RefPtr<CSSMutableStyleDeclaration> getPropertiesNotInComputedStyle(CSSStyleDeclaration* style, CSSComputedStyleDeclaration* computedStyle);
 
-enum ShouldIncludeTypingStyle {
-    IncludeTypingStyle,
-    IgnoreTypingStyle
-};
-
-PassRefPtr<CSSMutableStyleDeclaration> editingStyleAtPosition(Position, ShouldIncludeTypingStyle = IgnoreTypingStyle);
 void prepareEditingStyleToApplyAt(CSSMutableStyleDeclaration*, Position);
 void removeStylesAddedByNode(CSSMutableStyleDeclaration*, Node*);
 
index 9dc918d..e33f143 100644 (file)
@@ -940,7 +940,7 @@ void CompositeEditCommand::moveParagraphs(const VisiblePosition& startOfParagrap
     // too, <div><b><br></b></div> for example.  Save it so that we can preserve it later.
     RefPtr<CSSMutableStyleDeclaration> styleInEmptyParagraph;
     if (startOfParagraphToMove == endOfParagraphToMove && preserveStyle) {
-        styleInEmptyParagraph = editingStyleAtPosition(startOfParagraphToMove.deepEquivalent(), IncludeTypingStyle);
+        styleInEmptyParagraph = ApplyStyleCommand::editingStyleAtPosition(startOfParagraphToMove.deepEquivalent(), IncludeTypingStyle);
         // The moved paragraph should assume the block style of the destination.
         styleInEmptyParagraph->removeBlockProperties();
     }
@@ -1003,7 +1003,7 @@ bool CompositeEditCommand::breakOutOfEmptyListItem()
     if (!emptyListItem)
         return false;
 
-    RefPtr<CSSMutableStyleDeclaration> style = editingStyleAtPosition(endingSelection().start(), IncludeTypingStyle);
+    RefPtr<CSSMutableStyleDeclaration> style = ApplyStyleCommand::editingStyleAtPosition(endingSelection().start(), IncludeTypingStyle);
 
     Node* listNode = emptyListItem->parentNode();
     // FIXME: Can't we do something better when the immediate parent wasn't a list node?
index d999f84..24c8270 100644 (file)
@@ -133,7 +133,7 @@ static bool isDeletableElement(const Node* node)
         if (!parentStyle)
             return false;
 
-        if (style->hasBackground() && (!parentStyle->hasBackground() || style->backgroundColor() != parentStyle->backgroundColor()))
+        if (renderer->hasBackground() && (!parentRenderer->hasBackground() || style->visitedDependentColor(CSSPropertyBackgroundColor) != parentStyle->visitedDependentColor(CSSPropertyBackgroundColor)))
             return true;
     }
 
index 5e81d50..623b188 100644 (file)
@@ -294,14 +294,14 @@ void DeleteSelectionCommand::saveTypingStyleState()
         return;
 
     // Figure out the typing style in effect before the delete is done.
-    m_typingStyle = editingStyleAtPosition(positionBeforeTabSpan(m_selectionToDelete.start()));
+    m_typingStyle = ApplyStyleCommand::editingStyleAtPosition(positionBeforeTabSpan(m_selectionToDelete.start()));
 
     removeEnclosingAnchorStyle(m_typingStyle.get(), m_selectionToDelete.start());
 
     // If we're deleting into a Mail blockquote, save the style at end() instead of start()
     // We'll use this later in computeTypingStyleAfterDelete if we end up outside of a Mail blockquote
     if (nearestMailBlockquote(m_selectionToDelete.start().node()))
-        m_deleteIntoBlockquoteStyle = editingStyleAtPosition(m_selectionToDelete.end());
+        m_deleteIntoBlockquoteStyle = ApplyStyleCommand::editingStyleAtPosition(m_selectionToDelete.end());
     else
         m_deleteIntoBlockquoteStyle = 0;
 }
index affb639..47c6efd 100644 (file)
@@ -82,7 +82,7 @@ void InsertParagraphSeparatorCommand::calculateStyleBeforeInsertion(const Positi
     if (!isStartOfParagraph(visiblePos) && !isEndOfParagraph(visiblePos))
         return;
     
-    m_style = editingStyleAtPosition(pos, IncludeTypingStyle);
+    m_style = ApplyStyleCommand::editingStyleAtPosition(pos, IncludeTypingStyle);
 }
 
 void InsertParagraphSeparatorCommand::applyStyleAfterInsertion(Node* originalEnclosingBlock)
index 9243adc..e456df6 100644 (file)
@@ -56,7 +56,7 @@ void RemoveFormatCommand::doApply()
     // Get the default style for this editable root, it's the style that we'll give the
     // content that we're operating on.
     Node* root = frame->selection()->rootEditableElement();
-    RefPtr<CSSMutableStyleDeclaration> defaultStyle = editingStyleAtPosition(Position(root, 0));
+    RefPtr<CSSMutableStyleDeclaration> defaultStyle = ApplyStyleCommand::editingStyleAtPosition(Position(root, 0));
 
     // Delete the selected content.
     // FIXME: We should be able to leave this to insertText, but its delete operation
index e4acf85..2f0bddf 100644 (file)
@@ -577,7 +577,7 @@ static bool handleStyleSpansBeforeInsertion(ReplacementFragment& fragment, const
     Node* sourceDocumentStyleSpan = topNode;
     RefPtr<Node> copiedRangeStyleSpan = sourceDocumentStyleSpan->firstChild();
 
-    RefPtr<CSSMutableStyleDeclaration> styleAtInsertionPos = editingStyleAtPosition(rangeCompliantEquivalent(insertionPos));
+    RefPtr<CSSMutableStyleDeclaration> styleAtInsertionPos = ApplyStyleCommand::editingStyleAtPosition(rangeCompliantEquivalent(insertionPos));
 
     String styleText = styleAtInsertionPos->cssText();
     
@@ -634,8 +634,8 @@ void ReplaceSelectionCommand::handleStyleSpans()
     // styles from blockquoteNode are allowed to override those from the source document, see <rdar://problem/4930986> and <rdar://problem/5089327>.
     Node* blockquoteNode = isMailPasteAsQuotationNode(context) ? context : nearestMailBlockquote(context);
     if (blockquoteNode) {
-        RefPtr<CSSMutableStyleDeclaration> blockquoteStyle = editingStyleAtPosition(Position(blockquoteNode, 0));
-        RefPtr<CSSMutableStyleDeclaration> parentStyle = editingStyleAtPosition(Position(blockquoteNode->parentNode(), 0));
+        RefPtr<CSSMutableStyleDeclaration> blockquoteStyle = ApplyStyleCommand::editingStyleAtPosition(Position(blockquoteNode, 0));
+        RefPtr<CSSMutableStyleDeclaration> parentStyle = ApplyStyleCommand::editingStyleAtPosition(Position(blockquoteNode->parentNode(), 0));
         parentStyle->diff(blockquoteStyle.get());
 
         CSSMutableStyleDeclaration::const_iterator end = blockquoteStyle->end();
@@ -794,7 +794,7 @@ void ReplaceSelectionCommand::doApply()
         return;
     
     if (m_matchStyle)
-        m_insertionStyle = editingStyleAtPosition(selection.start(), IncludeTypingStyle);
+        m_insertionStyle = ApplyStyleCommand::editingStyleAtPosition(selection.start(), IncludeTypingStyle);
     
     VisiblePosition visibleStart = selection.visibleStart();
     VisiblePosition visibleEnd = selection.visibleEnd();
index 002226d..db0e04d 100644 (file)
@@ -1082,7 +1082,7 @@ void SelectionController::paintCaret(GraphicsContext* context, int tx, int ty, c
     ColorSpace colorSpace = DeviceColorSpace;
     Element* element = rootEditableElement();
     if (element && element->renderer()) {
-        caretColor = element->renderer()->style()->color();
+        caretColor = element->renderer()->style()->visitedDependentColor(CSSPropertyColor);
         colorSpace = element->renderer()->style()->colorSpace();
     }
 
index 9f5d4e8..46f0e94 100644 (file)
@@ -1019,7 +1019,7 @@ String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc
     // Add a wrapper span with the styles that all of the nodes in the markup inherit.
     Node* parentOfLastClosed = lastClosed ? lastClosed->parentNode() : 0;
     if (parentOfLastClosed && parentOfLastClosed->renderer()) {
-        RefPtr<CSSMutableStyleDeclaration> style = editingStyleAtPosition(Position(parentOfLastClosed, 0));
+        RefPtr<CSSMutableStyleDeclaration> style = ApplyStyleCommand::editingStyleAtPosition(Position(parentOfLastClosed, 0));
 
         // Styles that Mail blockquotes contribute should only be placed on the Mail blockquote, to help
         // us differentiate those styles from ones that the user has applied.  This helps us
@@ -1043,7 +1043,7 @@ String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc
         // Add a style span with the document's default styles.  We add these in a separate
         // span so that at paste time we can differentiate between document defaults and user
         // applied styles.
-        RefPtr<CSSMutableStyleDeclaration> defaultStyle = editingStyleAtPosition(Position(document->documentElement(), 0));
+        RefPtr<CSSMutableStyleDeclaration> defaultStyle = ApplyStyleCommand::editingStyleAtPosition(Position(document->documentElement(), 0));
 
         if (defaultStyle->length() > 0)
             addStyleMarkup(preMarkups, markups, defaultStyle.get(), document);
index a49c754..6ab56e9 100644 (file)
@@ -562,7 +562,7 @@ static int gPropertyWrapperMap[numCSSProperties];
 static const int cInvalidPropertyWrapperIndex = -1;
 
 
-static void ensurePropertyMap()
+void AnimationBase::ensurePropertyMap()
 {
     // FIXME: This data is never destroyed. Maybe we should ref count it and toss it when the last AnimationController is destroyed?
     if (gPropertyWrappers == 0) {
index a957119..ac55a2b 100644 (file)
@@ -225,6 +225,9 @@ protected:
     double m_totalDuration, m_nextIterationDuration;
     
     AnimationBase* m_next;
+    
+private:
+    static void ensurePropertyMap();
 };
 
 } // namespace WebCore
index 356503f..bb11ac9 100644 (file)
@@ -407,14 +407,14 @@ NSDictionary* Frame::fontAttributesForSelectionStart() const
 
     NSMutableDictionary* result = [NSMutableDictionary dictionary];
 
-    if (style->backgroundColor().isValid() && style->backgroundColor().alpha() != 0)
-        [result setObject:nsColor(style->backgroundColor()) forKey:NSBackgroundColorAttributeName];
+    if (style->visitedDependentColor(CSSPropertyBackgroundColor).isValid() && style->visitedDependentColor(CSSPropertyBackgroundColor).alpha() != 0)
+        [result setObject:nsColor(style->visitedDependentColor(CSSPropertyBackgroundColor)) forKey:NSBackgroundColorAttributeName];
 
     if (style->font().primaryFont()->getNSFont())
         [result setObject:style->font().primaryFont()->getNSFont() forKey:NSFontAttributeName];
 
-    if (style->color().isValid() && style->color() != Color::black)
-        [result setObject:nsColor(style->color()) forKey:NSForegroundColorAttributeName];
+    if (style->visitedDependentColor(CSSPropertyColor).isValid() && style->visitedDependentColor(CSSPropertyColor) != Color::black)
+        [result setObject:nsColor(style->visitedDependentColor(CSSPropertyColor)) forKey:NSForegroundColorAttributeName];
 
     const ShadowData* shadow = style->textShadow();
     if (shadow) {
index 6f25861..6cb9063 100644 (file)
@@ -31,7 +31,7 @@ void EllipsisBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
 {
     GraphicsContext* context = paintInfo.context;
     RenderStyle* style = m_renderer->style(m_firstLine);
-    Color textColor = style->color();
+    Color textColor = style->visitedDependentColor(CSSPropertyColor);
     if (textColor != context->fillColor())
         context->setFillColor(textColor, style->colorSpace());
     bool setShadow = false;
@@ -78,7 +78,7 @@ IntRect EllipsisBox::selectionRect(int tx, int ty)
 
 void EllipsisBox::paintSelection(GraphicsContext* context, int tx, int ty, RenderStyle* style, const Font& font)
 {
-    Color textColor = style->color();
+    Color textColor = style->visitedDependentColor(CSSPropertyColor);
     Color c = m_renderer->selectionBackgroundColor();
     if (!c.isValid() || !c.alpha())
         return;
index ca2f48c..d58fb4e 100644 (file)
@@ -455,9 +455,7 @@ void InlineTextBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
                 selectionStrokeWidth = strokeWidth;
             }
 
-            Color stroke = paintInfo.forceBlackText ? Color::black : pseudoStyle->textStrokeColor();
-            if (!stroke.isValid())
-                stroke = pseudoStyle->color();
+            Color stroke = paintInfo.forceBlackText ? Color::black : pseudoStyle->visitedDependentColor(CSSPropertyWebkitTextStrokeColor);
             if (stroke != selectionStrokeColor) {
                 if (!paintSelectedTextOnly)
                     paintSelectedTextSeparately = true;
index 96f0f5a..24ff664 100644 (file)
@@ -184,7 +184,7 @@ void RenderBox::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle
 
     // Set the text color if we're the body.
     if (isBody())
-        document()->setTextColor(style()->color());
+        document()->setTextColor(style()->visitedDependentColor(CSSPropertyColor));
 }
 
 void RenderBox::updateBoxModelInfoFromStyle()
@@ -577,9 +577,9 @@ void RenderBox::paint(PaintInfo& paintInfo, int tx, int ty)
 void RenderBox::paintRootBoxDecorations(PaintInfo& paintInfo, int tx, int ty)
 {
     const FillLayer* bgLayer = style()->backgroundLayers();
-    Color bgColor = style()->backgroundColor();
+    Color bgColor = style()->visitedDependentColor(CSSPropertyBackgroundColor);
     RenderObject* bodyObject = 0;
-    if (!style()->hasBackground() && node() && node()->hasTagName(HTMLNames::htmlTag)) {
+    if (!hasBackground() && node() && node()->hasTagName(HTMLNames::htmlTag)) {
         // Locate the <body> element using the DOM.  This is easier than trying
         // to crawl around a render tree with potential :before/:after content and
         // anonymous blocks created by inline <body> tags etc.  We can locate the <body>
@@ -588,7 +588,7 @@ void RenderBox::paintRootBoxDecorations(PaintInfo& paintInfo, int tx, int ty)
         bodyObject = (body && body->hasLocalName(bodyTag)) ? body->renderer() : 0;
         if (bodyObject) {
             bgLayer = bodyObject->style()->backgroundLayers();
-            bgColor = bodyObject->style()->backgroundColor();
+            bgColor = bodyObject->style()->visitedDependentColor(CSSPropertyBackgroundColor);
         }
     }
 
@@ -649,8 +649,8 @@ void RenderBox::paintBoxDecorationsWithSize(PaintInfo& paintInfo, int tx, int ty
         // The <body> only paints its background if the root element has defined a background
         // independent of the body.  Go through the DOM to get to the root element's render object,
         // since the root could be inline and wrapped in an anonymous block.
-        if (!isBody() || document()->documentElement()->renderer()->style()->hasBackground())
-            paintFillLayers(paintInfo, style()->backgroundColor(), style()->backgroundLayers(), tx, ty, width, height);
+        if (!isBody() || document()->documentElement()->renderer()->hasBackground())
+            paintFillLayers(paintInfo, style()->visitedDependentColor(CSSPropertyBackgroundColor), style()->backgroundLayers(), tx, ty, width, height);
         if (style()->hasAppearance())
             theme()->paintDecorations(this, paintInfo, IntRect(tx, ty, width, height));
     }
@@ -796,7 +796,7 @@ bool RenderBox::repaintLayerRectsForImage(WrappedImagePtr image, const FillLayer
             // Now that we know this image is being used, compute the renderer and the rect
             // if we haven't already
             if (!layerRenderer) {
-                bool drawingRootBackground = drawingBackground && (isRoot() || (isBody() && !document()->documentElement()->renderer()->style()->hasBackground()));
+                bool drawingRootBackground = drawingBackground && (isRoot() || (isBody() && !document()->documentElement()->renderer()->hasBackground()));
                 if (drawingRootBackground) {
                     layerRenderer = view();
 
index 9caf46f..1a72957 100644 (file)
@@ -304,7 +304,7 @@ void RenderBoxModelObject::updateBoxModelInfoFromStyle()
 {
     // Set the appropriate bits for a box model object.  Since all bits are cleared in styleWillChange,
     // we only check for bits that could possibly be set to true.
-    setHasBoxDecorations(style()->hasBorder() || style()->hasBackground() || style()->hasAppearance() || style()->boxShadow());
+    setHasBoxDecorations(hasBackground() || style()->hasBorder() || style()->hasAppearance() || style()->boxShadow());
     setInline(style()->isDisplayInlineType());
     setRelPositioned(style()->position() == RelativePosition);
 }
@@ -1321,7 +1321,7 @@ void RenderBoxModelObject::paintBoxShadow(GraphicsContext* context, int tx, int
         rect.setHeight(rect.height() - borderTop() - borderBottom());
     }
 
-    bool hasOpaqueBackground = s->backgroundColor().isValid() && s->backgroundColor().alpha() == 255;
+    bool hasOpaqueBackground = s->visitedDependentColor(CSSPropertyBackgroundColor).isValid() && s->visitedDependentColor(CSSPropertyBackgroundColor).alpha() == 255;
     for (const ShadowData* shadow = s->boxShadow(); shadow; shadow = shadow->next()) {
         if (shadow->style() != shadowStyle)
             continue;
index 306e111..734c348 100644 (file)
@@ -136,7 +136,7 @@ void RenderFieldset::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty)
 
     paintBoxShadow(paintInfo.context, tx, ty, w, h, style(), Normal);
 
-    paintFillLayers(paintInfo, style()->backgroundColor(), style()->backgroundLayers(), tx, ty, w, h);
+    paintFillLayers(paintInfo, style()->visitedDependentColor(CSSPropertyBackgroundColor), style()->backgroundLayers(), tx, ty, w, h);
     paintBoxShadow(paintInfo.context, tx, ty, w, h, style(), Inset);
 
     if (!style()->hasBorder())
index fa2a998..1ae149b 100644 (file)
@@ -228,7 +228,7 @@ void RenderFileUploadControl::paintObject(PaintInfo& paintInfo, int tx, int ty)
             + buttonRenderer->marginTop() + buttonRenderer->borderTop() + buttonRenderer->paddingTop()
             + buttonRenderer->baselinePosition(true, false);
 
-        paintInfo.context->setFillColor(style()->color(), style()->colorSpace());
+        paintInfo.context->setFillColor(style()->visitedDependentColor(CSSPropertyColor), style()->colorSpace());
         
         // Draw the filename
         paintInfo.context->drawBidiText(style()->font(), textRun, IntPoint(textX, textY));
index 7855b2d..afe1954 100644 (file)
@@ -87,7 +87,7 @@ void RenderFrameSet::paintColumnBorder(const PaintInfo& paintInfo, const IntRect
     // Fill first.
     GraphicsContext* context = paintInfo.context;
     ColorSpace colorSpace = style()->colorSpace();
-    context->fillRect(borderRect, frameSet()->hasBorderColor() ? style()->borderLeftColor() : borderFillColor(), colorSpace);
+    context->fillRect(borderRect, frameSet()->hasBorderColor() ? style()->visitedDependentColor(CSSPropertyBorderLeftColor) : borderFillColor(), colorSpace);
     
     // Now stroke the edges but only if we have enough room to paint both edges with a little
     // bit of the fill color showing through.
@@ -107,7 +107,7 @@ void RenderFrameSet::paintRowBorder(const PaintInfo& paintInfo, const IntRect& b
     // Fill first.
     GraphicsContext* context = paintInfo.context;
     ColorSpace colorSpace = style()->colorSpace();
-    context->fillRect(borderRect, frameSet()->hasBorderColor() ? style()->borderLeftColor() : borderFillColor(), colorSpace);
+    context->fillRect(borderRect, frameSet()->hasBorderColor() ? style()->visitedDependentColor(CSSPropertyBorderLeftColor) : borderFillColor(), colorSpace);
 
     // Now stroke the edges but only if we have enough room to paint both edges with a little
     // bit of the fill color showing through.
index f338d43..a0fba96 100644 (file)
@@ -397,7 +397,7 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
 
             if (!m_altText.isEmpty()) {
                 String text = document()->displayStringModifiedByEncoding(m_altText);
-                context->setFillColor(style()->color(), style()->colorSpace());
+                context->setFillColor(style()->visitedDependentColor(CSSPropertyColor), style()->colorSpace());
                 int ax = tx + leftBorder + leftPad;
                 int ay = ty + topBorder + topPad;
                 const Font& font = style()->font();
index 61bc7a3..97c5544 100644 (file)
@@ -62,7 +62,7 @@ namespace WebCore {
 using namespace HTMLNames;
 
 static bool hasBorderOutlineOrShadow(const RenderStyle*);
-static bool hasBoxDecorationsOrBackground(const RenderStyle*);
+static bool hasBoxDecorationsOrBackground(const RenderObject*);
 static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle*);
 
 static inline bool is3DCanvas(RenderObject* renderer)
@@ -533,9 +533,9 @@ static bool hasBorderOutlineOrShadow(const RenderStyle* style)
     return style->hasBorder() || style->hasBorderRadius() || style->hasOutline() || style->hasAppearance() || style->boxShadow();
 }
 
-static bool hasBoxDecorationsOrBackground(const RenderStyle* style)
+static bool hasBoxDecorationsOrBackground(const RenderObject* renderer)
 {
-    return hasBorderOutlineOrShadow(style) || style->hasBackground();
+    return hasBorderOutlineOrShadow(renderer->style()) || renderer->hasBackground();
 }
 
 static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle* style)
@@ -551,36 +551,32 @@ bool RenderLayerBacking::rendererHasBackground() const
         if (!htmlObject)
             return false;
         
-        RenderStyle* style = htmlObject->style();
-        if (style->hasBackground())
+        if (htmlObject->hasBackground())
             return true;
         
         RenderObject* bodyObject = htmlObject->firstChild();
         if (!bodyObject)
             return false;
         
-        style = bodyObject->style();
-        return style->hasBackground();
+        return bodyObject->hasBackground();
     }
     
-    return renderer()->style()->hasBackground();
+    return renderer()->hasBackground();
 }
 
-const Color& RenderLayerBacking::rendererBackgroundColor() const
+const Color RenderLayerBacking::rendererBackgroundColor() const
 {
     // FIXME: share more code here
     if (renderer()->node() && renderer()->node()->isDocumentNode()) {
         RenderObject* htmlObject = renderer()->firstChild();
-        RenderStyle* style = htmlObject->style();
-        if (style->hasBackground())
-            return style->backgroundColor();
+        if (htmlObject->hasBackground())
+            return htmlObject->style()->visitedDependentColor(CSSPropertyBackgroundColor);
 
         RenderObject* bodyObject = htmlObject->firstChild();
-        style = bodyObject->style();
-        return style->backgroundColor();
+        return bodyObject->style()->visitedDependentColor(CSSPropertyBackgroundColor);
     }
 
-    return renderer()->style()->backgroundColor();
+    return renderer()->style()->visitedDependentColor(CSSPropertyBackgroundColor);
 }
 
 // A "simple container layer" is a RenderLayer which has no visible content to render.
@@ -598,7 +594,7 @@ bool RenderLayerBacking::isSimpleContainerCompositingLayer() const
     // Reject anything that has a border, a border-radius or outline,
     // or any background (color or image).
     // FIXME: we could optimize layers for simple backgrounds.
-    if (hasBoxDecorationsOrBackground(style))
+    if (hasBoxDecorationsOrBackground(renderObject))
         return false;
 
     // If we have got this far and the renderer has no children, then we're ok.
@@ -708,7 +704,7 @@ bool RenderLayerBacking::containsPaintedContent() const
     // FIXME: we could optimize cases where the image, video or canvas is known to fill the border box entirely,
     // and set background color on the layer in that case, instead of allocating backing store and painting.
     if (renderer()->isVideo() || is3DCanvas(renderer()))
-        return hasBoxDecorationsOrBackground(renderer()->style());
+        return hasBoxDecorationsOrBackground(renderer());
 
     return true;
 }
@@ -718,7 +714,7 @@ bool RenderLayerBacking::containsPaintedContent() const
 bool RenderLayerBacking::isDirectlyCompositedImage() const
 {
     RenderObject* renderObject = renderer();
-    return renderObject->isImage() && !hasBoxDecorationsOrBackground(renderObject->style());
+    return renderObject->isImage() && !hasBoxDecorationsOrBackground(renderObject);
 }
 
 void RenderLayerBacking::rendererContentChanged()
index 7cc5307..faa553c 100644 (file)
@@ -159,7 +159,7 @@ private:
     void updateImageContents();
 
     bool rendererHasBackground() const;
-    const Color& rendererBackgroundColor() const;
+    const Color rendererBackgroundColor() const;
 
     bool hasNonCompositingContent() const;
     
index 68591d6..1c21af4 100644 (file)
@@ -312,7 +312,7 @@ void RenderListBox::paintItemForeground(PaintInfo& paintInfo, int tx, int ty, in
     if (!itemStyle)
         itemStyle = style();
     
-    Color textColor = element->renderStyle() ? element->renderStyle()->color() : style()->color();
+    Color textColor = element->renderStyle() ? element->renderStyle()->visitedDependentColor(CSSPropertyColor) : style()->visitedDependentColor(CSSPropertyColor);
     if (optionElement && optionElement->selected()) {
         if (document()->frame()->selection()->isFocusedAndActive() && document()->focusedNode() == node())
             textColor = theme()->activeListBoxSelectionForegroundColor();
@@ -355,7 +355,7 @@ void RenderListBox::paintItemBackground(PaintInfo& paintInfo, int tx, int ty, in
         else
             backColor = theme()->inactiveListBoxSelectionBackgroundColor();
     } else
-        backColor = element->renderStyle() ? element->renderStyle()->backgroundColor() : style()->backgroundColor();
+        backColor = element->renderStyle() ? element->renderStyle()->visitedDependentColor(CSSPropertyBackgroundColor) : style()->visitedDependentColor(CSSPropertyBackgroundColor);
 
     // Draw the background for this list box item
     if (!element->renderStyle() || element->renderStyle()->visibility() != HIDDEN) {
index 6c8f769..e148c81 100644 (file)
@@ -1009,7 +1009,7 @@ void RenderListMarker::paint(PaintInfo& paintInfo, int tx, int ty)
         context->fillRect(selRect, selectionBackgroundColor(), style()->colorSpace());
     }
 
-    const Color color(style()->color());
+    const Color color(style()->visitedDependentColor(CSSPropertyColor));
     context->setStrokeColor(color, style()->colorSpace());
     context->setStrokeStyle(SolidStroke);
     context->setStrokeThickness(1.0f);
index 0f2ada8..ede3d11 100644 (file)
@@ -120,9 +120,9 @@ static bool paintMediaSlider(RenderObject* object, const RenderObject::PaintInfo
     context->save();
     context->setShouldAntialias(true);
     context->setStrokeStyle(SolidStroke);
-    context->setStrokeColor(style->borderLeftColor(), DeviceColorSpace);
+    context->setStrokeColor(style->visitedDependentColor(CSSPropertyBorderLeftColor), DeviceColorSpace);
     context->setStrokeThickness(style->borderLeftWidth());
-    context->setFillColor(style->backgroundColor(), DeviceColorSpace);
+    context->setFillColor(style->visitedDependentColor(CSSPropertyBackgroundColor), DeviceColorSpace);
     context->drawRect(rect);
     context->restore();
 
@@ -150,7 +150,7 @@ static bool paintMediaSlider(RenderObject* object, const RenderObject::PaintInfo
         sliderTopRight.move(0, bufferedRect.height());
 
         RefPtr<Gradient> gradient = Gradient::create(sliderTopLeft, sliderTopRight);
-        Color startColor = object->style()->color();
+        Color startColor = object->style()->visitedDependentColor(CSSPropertyColor);
         gradient->addColorStop(0.0, startColor);
         gradient->addColorStop(1.0, Color(startColor.red() / 2, startColor.green() / 2, startColor.blue() / 2, startColor.alpha()));
 
@@ -224,13 +224,13 @@ static bool paintMediaTimelineContainer(RenderObject* object, const RenderObject
 
         // Draw the left border using CSS defined width and color.
         context->setStrokeThickness(object->style()->borderLeftWidth());
-        context->setStrokeColor(object->style()->borderLeftColor().rgb(), DeviceColorSpace);
+        context->setStrokeColor(object->style()->visitedDependentColor(CSSPropertyBorderLeftColor).rgb(), DeviceColorSpace);
         context->drawLine(IntPoint(rect.x() + 1, rect.y()),
                           IntPoint(rect.x() + 1, rect.y() + rect.height()));
 
         // Draw the right border using CSS defined width and color.
         context->setStrokeThickness(object->style()->borderRightWidth());
-        context->setStrokeColor(object->style()->borderRightColor().rgb(), DeviceColorSpace);
+        context->setStrokeColor(object->style()->visitedDependentColor(CSSPropertyBorderRightColor).rgb(), DeviceColorSpace);
         context->drawLine(IntPoint(rect.x() + rect.width() - 1, rect.y()),
                           IntPoint(rect.x() + rect.width() - 1, rect.y() + rect.height()));
 
index e2c6fd5..871c10f 100644 (file)
@@ -409,7 +409,7 @@ PopupMenuStyle RenderMenuList::itemStyle(unsigned listIndex) const
     Element* element = listItems[listIndex];
     
     RenderStyle* style = element->renderStyle() ? element->renderStyle() : element->computedStyle();
-    return style ? PopupMenuStyle(style->color(), itemBackgroundColor(listIndex), style->font(), style->visibility() == VISIBLE, style->textIndent(), style->direction()) : menuStyle();
+    return style ? PopupMenuStyle(style->visitedDependentColor(CSSPropertyColor), itemBackgroundColor(listIndex), style->font(), style->visibility() == VISIBLE, style->textIndent(), style->direction()) : menuStyle();
 }
 
 Color RenderMenuList::itemBackgroundColor(unsigned listIndex) const
@@ -417,18 +417,18 @@ Color RenderMenuList::itemBackgroundColor(unsigned listIndex) const
     SelectElement* select = toSelectElement(static_cast<Element*>(node()));
     const Vector<Element*>& listItems = select->listItems();
     if (listIndex >= listItems.size())
-        return style()->backgroundColor();
+        return style()->visitedDependentColor(CSSPropertyBackgroundColor);
     Element* element = listItems[listIndex];
 
     Color backgroundColor;
     if (element->renderStyle())
-        backgroundColor = element->renderStyle()->backgroundColor();
+        backgroundColor = element->renderStyle()->visitedDependentColor(CSSPropertyBackgroundColor);
     // If the item has an opaque background color, return that.
     if (!backgroundColor.hasAlpha())
         return backgroundColor;
 
     // Otherwise, the item's background is overlayed on top of the menu background.
-    backgroundColor = style()->backgroundColor().blend(backgroundColor);
+    backgroundColor = style()->visitedDependentColor(CSSPropertyBackgroundColor).blend(backgroundColor);
     if (!backgroundColor.hasAlpha())
         return backgroundColor;
 
@@ -439,7 +439,7 @@ Color RenderMenuList::itemBackgroundColor(unsigned listIndex) const
 PopupMenuStyle RenderMenuList::menuStyle() const
 {
     RenderStyle* s = m_innerBlock ? m_innerBlock->style() : style();
-    return PopupMenuStyle(s->color(), s->backgroundColor(), s->font(), s->visibility() == VISIBLE, s->textIndent(), s->direction());
+    return PopupMenuStyle(s->visitedDependentColor(CSSPropertyColor), s->visitedDependentColor(CSSPropertyBackgroundColor), s->font(), s->visibility() == VISIBLE, s->textIndent(), s->direction());
 }
 
 HostWindow* RenderMenuList::hostWindow() const
index ade6cc9..3d7cc7f 100644 (file)
@@ -1382,9 +1382,9 @@ Color RenderObject::selectionBackgroundColor() const
 {
     Color color;
     if (style()->userSelect() != SELECT_NONE) {
-         RefPtr<RenderStyle> pseudoStyle = getUncachedPseudoStyle(SELECTION);
-        if (pseudoStyle && pseudoStyle->backgroundColor().isValid())
-            color = pseudoStyle->backgroundColor().blendWithWhite();
+        RefPtr<RenderStyle> pseudoStyle = getUncachedPseudoStyle(SELECTION);
+        if (pseudoStyle && pseudoStyle->visitedDependentColor(CSSPropertyBackgroundColor).isValid())
+            color = pseudoStyle->visitedDependentColor(CSSPropertyBackgroundColor).blendWithWhite();
         else
             color = document()->frame()->selection()->isFocusedAndActive() ?
                     theme()->activeSelectionBackgroundColor() :
@@ -1401,9 +1401,9 @@ Color RenderObject::selectionForegroundColor() const
         return color;
 
     if (RefPtr<RenderStyle> pseudoStyle = getUncachedPseudoStyle(SELECTION)) {
-        color = pseudoStyle->textFillColor();
+        color = pseudoStyle->visitedDependentColor(CSSPropertyWebkitTextFillColor);
         if (!color.isValid())
-            color = pseudoStyle->color();
+            color = pseudoStyle->visitedDependentColor(CSSPropertyColor);
     } else
         color = document()->frame()->selection()->isFocusedAndActive() ?
                 theme()->activeSelectionForegroundColor() :
index cfcc507..9b393b6 100644 (file)
@@ -401,6 +401,13 @@ public:
     
     bool hasBoxDecorations() const { return m_paintBackground; }
     bool mustRepaintBackgroundOrBorder() const;
+    bool hasBackground() const
+    {
+        Color color = style()->visitedDependentColor(CSSPropertyBackgroundColor);
+        if (color.isValid() && color.alpha() > 0)
+            return true;
+        return style()->hasBackgroundImage();
+    }
 
     bool needsLayout() const { return m_needsLayout || m_normalChildNeedsLayout || m_posChildNeedsLayout || m_needsPositionedMovementLayout; }
     bool selfNeedsLayout() const { return m_needsLayout; }
index 821e58a..129d800 100644 (file)
@@ -44,7 +44,7 @@ static inline void registerPendingResource(const AtomicString& id, const SVGPain
     object->document()->accessSVGExtensions()->addPendingResource(id, static_cast<SVGStyledElement*>(svgElement));
 }
 
-static inline void adjustColorForPseudoRules(const RenderStyle* style, bool useFillPaint, Color& color)
+inline void RenderSVGResource::adjustColorForPseudoRules(const RenderStyle* style, bool useFillPaint, Color& color)
 {
     if (style->insideLink() != InsideVisitedLink)
         return;
@@ -95,7 +95,7 @@ RenderSVGResource* RenderSVGResource::fillPaintingResource(const RenderObject* o
 
         Color fillColor;
         if (fillPaint->paintType() == SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR)
-            fillColor = style->color();
+            fillColor = style->visitedDependentColor(CSSPropertyColor);
         else
             fillColor = fillPaint->color();
 
@@ -149,7 +149,7 @@ RenderSVGResource* RenderSVGResource::strokePaintingResource(const RenderObject*
 
         Color strokeColor;
         if (strokePaint->paintType() == SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR)
-            strokeColor = style->color();
+            strokeColor = style->visitedDependentColor(CSSPropertyColor);
         else
             strokeColor = strokePaint->color();
 
index 4e33e55..5334025 100644 (file)
@@ -44,6 +44,7 @@ enum RenderSVGResourceMode {
     ApplyToTextMode    = 1 << 3 // used in combination with ApplyTo{Fill|Stroke}Mode
 };
 
+class Color;
 class FloatRect;
 class GraphicsContext;
 class RenderObject;
@@ -78,6 +79,9 @@ public:
     static RenderSVGResource* strokePaintingResource(const RenderObject*, const RenderStyle*);
     static RenderSVGResourceSolidColor* sharedSolidPaintingResource();
 
+private:
+    static void adjustColorForPseudoRules(const RenderStyle*, bool useFillPaint, Color&);
+    
 protected:
     void markForLayoutAndResourceInvalidation(RenderObject*);
 };
index 5c7f91c..7d553ea 100644 (file)
@@ -501,7 +501,7 @@ void RenderTable::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty)
 
     paintBoxShadow(paintInfo.context, tx, ty, w, h, style(), Normal);
     
-    paintFillLayers(paintInfo, style()->backgroundColor(), style()->backgroundLayers(), tx, ty, w, h);
+    paintFillLayers(paintInfo, style()->visitedDependentColor(CSSPropertyBackgroundColor), style()->backgroundLayers(), tx, ty, w, h);
     paintBoxShadow(paintInfo.context, tx, ty, w, h, style(), Inset);
 
     if (style()->hasBorder() && !collapseBorders())
index 5978c0b..ea08673 100644 (file)
@@ -25,6 +25,7 @@
 #ifndef RenderTable_h
 #define RenderTable_h
 
+#include "CSSPropertyNames.h"
 #include "RenderBlock.h"
 #include <wtf/Vector.h>
 
@@ -50,7 +51,7 @@ public:
     int borderTop() const;
     int borderBottom() const;
     
-    const Color& bgColor() const { return style()->backgroundColor(); }
+    const Color bgColor() const { return style()->visitedDependentColor(CSSPropertyBackgroundColor); }
 
     int outerBorderTop() const;
     int outerBorderBottom() const;
index cb51f13..81852b7 100644 (file)
@@ -849,7 +849,7 @@ void RenderTableCell::paintBackgroundsBehindCell(PaintInfo& paintInfo, int tx, i
     int w = width();
     int h = height();
 
-    Color c = backgroundObject->style()->backgroundColor();
+    Color c = backgroundObject->style()->visitedDependentColor(CSSPropertyBackgroundColor);
     const FillLayer* bgLayer = backgroundObject->style()->backgroundLayers();
 
     if (bgLayer->hasImage() || c.isValid()) {
index 1e80ff0..deb7168 100644 (file)
@@ -134,7 +134,7 @@ void RenderTextControl::adjustInnerTextStyle(const RenderStyle* startStyle, Rend
 
     bool disabled = updateUserModifyProperty(node(), textBlockStyle);
     if (disabled)
-        textBlockStyle->setColor(disabledTextColor(textBlockStyle->color(), startStyle->backgroundColor()));
+        textBlockStyle->setColor(disabledTextColor(textBlockStyle->visitedDependentColor(CSSPropertyColor), startStyle->visitedDependentColor(CSSPropertyBackgroundColor)));
 }
 
 void RenderTextControl::createSubtreeIfNeeded(TextControlInnerElement* innerBlock)
index 41328cc..7f40944 100644 (file)
@@ -788,7 +788,7 @@ PopupMenuStyle RenderTextControlSingleLine::itemStyle(unsigned) const
 
 PopupMenuStyle RenderTextControlSingleLine::menuStyle() const
 {
-    return PopupMenuStyle(style()->color(), style()->backgroundColor(), style()->font(), style()->visibility() == VISIBLE, style()->textIndent(), style()->direction());
+    return PopupMenuStyle(style()->visitedDependentColor(CSSPropertyColor), style()->visitedDependentColor(CSSPropertyBackgroundColor), style()->font(), style()->visibility() == VISIBLE, style()->textIndent(), style()->direction());
 }
 
 int RenderTextControlSingleLine::clientInsetLeft() const
index 96d37c3..445e637 100644 (file)
@@ -642,7 +642,7 @@ bool RenderTheme::isControlStyled(const RenderStyle* style, const BorderData& bo
             // Test the style to see if the UA border and background match.
             return (style->border() != border ||
                     *style->backgroundLayers() != background ||
-                    style->backgroundColor() != backgroundColor);
+                    style->visitedDependentColor(CSSPropertyBackgroundColor) != backgroundColor);
         default:
             return false;
     }
index 8b3b388..0956e38 100644 (file)
@@ -308,8 +308,8 @@ static void paintButtonLike(RenderTheme* theme, RenderObject* o, const RenderObj
     const int right = rect.x() + rect.width();
     const int bottom = rect.y() + rect.height();
     SkColor baseColor = SkColorSetARGB(0xff, 0xdd, 0xdd, 0xdd);
-    if (o->style()->hasBackground())
-        baseColor = o->style()->backgroundColor().rgb();
+    if (o->hasBackground())
+        baseColor = o->style()->visitedDependentColor(CSSPropertyBackgroundColor).rgb();
     double h, s, l;
     Color(baseColor).getHSL(h, s, l);
     // Our standard gradient is from 0xdd to 0xf8. This is the amount of
index d1a3965..f1de775 100644 (file)
@@ -994,7 +994,7 @@ bool RenderThemeMac::paintMenuListButton(RenderObject* o, const RenderObject::Pa
     
     paintInfo.context->save();
 
-    paintInfo.context->setFillColor(o->style()->color(), o->style()->colorSpace());
+    paintInfo.context->setFillColor(o->style()->visitedDependentColor(CSSPropertyColor), o->style()->colorSpace());
     paintInfo.context->setStrokeStyle(NoStroke);
 
     FloatPoint arrow1[3];
index fd63c0e..cf76f0b 100644 (file)
@@ -180,7 +180,7 @@ String quoteAndEscapeNonPrintables(const String& s)
     return String::adopt(result);
 }
 
-static void writeRenderObject(TextStream& ts, const RenderObject& o, RenderAsTextBehavior behavior)
+void RenderTreeAsText::writeRenderObject(TextStream& ts, const RenderObject& o, RenderAsTextBehavior behavior)
 {
     ts << o.renderName();
 
@@ -429,7 +429,7 @@ void write(TextStream& ts, const RenderObject& o, int indent, RenderAsTextBehavi
 
     writeIndent(ts, indent);
 
-    writeRenderObject(ts, o, behavior);
+    RenderTreeAsText::writeRenderObject(ts, o, behavior);
     ts << "\n";
 
     if (o.isText() && !o.isBR()) {
index ecee7f9..1635e79 100644 (file)
@@ -49,6 +49,14 @@ String externalRepresentation(Frame*, RenderAsTextBehavior = RenderAsTextBehavio
 void write(TextStream&, const RenderObject&, int indent = 0, RenderAsTextBehavior = RenderAsTextBehaviorNormal);
 void writeIndent(TextStream&, int indent);
 
+class RenderTreeAsText {
+// FIXME: This is a cheesy hack to allow easy access to RenderStyle colors.  It won't be needed if we convert
+// it to use visitedDependentColor instead. (This just involves rebaselining many results though, so for now it's
+// not being done).
+public:
+static void writeRenderObject(TextStream& ts, const RenderObject& o, RenderAsTextBehavior behavior);
+};
+
 // Helper function shared with SVGRenderTreeAsText
 String quoteAndEscapeNonPrintables(const String&);
 
index 3ae272e..8bd7fef 100644 (file)
@@ -477,7 +477,7 @@ void SVGInlineTextBox::paintSelection(int boxStartOffset, const SVGChar& svgChar
     if (startPos >= endPos)
         return;
 
-    Color textColor = style->color();
+    Color textColor = style->visitedDependentColor(CSSPropertyColor);
     Color color = renderer()->selectionBackgroundColor();
     if (!color.isValid() || !color.alpha())
         return;
index 8b4c563..8668780 100644 (file)
@@ -433,8 +433,8 @@ static void writeRenderSVGTextBox(TextStream& ts, const RenderBlock& text)
     Vector<SVGTextChunk>& chunks = const_cast<Vector<SVGTextChunk>& >(box->svgTextChunks());
     ts << " at (" << text.x() << "," << text.y() << ") size " << box->width() << "x" << box->height() << " contains " << chunks.size() << " chunk(s)";
 
-    if (text.parent() && (text.parent()->style()->color() != text.style()->color()))
-        writeNameValuePair(ts, "color", text.style()->color().name());
+    if (text.parent() && (text.parent()->style()->visitedDependentColor(CSSPropertyColor) != text.style()->visitedDependentColor(CSSPropertyColor)))
+        writeNameValuePair(ts, "color", text.style()->visitedDependentColor(CSSPropertyColor).name());
 }
 
 static inline bool containsInlineTextBox(SVGTextChunk& chunk, SVGInlineTextBox* box)
index 7ef580f..220e657 100644 (file)
@@ -995,42 +995,42 @@ static EBorderStyle borderStyleForColorProperty(const RenderStyle* style, int co
     return borderStyle;
 }
 
-static Color colorIncludingFallback(const RenderStyle* style, int colorProperty, EBorderStyle borderStyle)
+const Color RenderStyle::colorIncludingFallback(int colorProperty, EBorderStyle borderStyle) const
 {
     Color result;
     switch (colorProperty) {
     case CSSPropertyBackgroundColor:
-        return style->backgroundColor(); // Background color doesn't fall back.
+        return backgroundColor(); // Background color doesn't fall back.
     case CSSPropertyBorderLeftColor:
-        result = style->borderLeftColor();
-        borderStyle = style->borderLeftStyle();
+        result = borderLeftColor();
+        borderStyle = borderLeftStyle();
         break;
     case CSSPropertyBorderRightColor:
-        result = style->borderRightColor();
-        borderStyle = style->borderRightStyle();
+        result = borderRightColor();
+        borderStyle = borderRightStyle();
         break;
     case CSSPropertyBorderTopColor:
-        result = style->borderTopColor();
-        borderStyle = style->borderTopStyle();
+        result = borderTopColor();
+        borderStyle = borderTopStyle();
         break;
     case CSSPropertyBorderBottomColor:
-        result = style->borderBottomColor();
-        borderStyle = style->borderBottomStyle();
+        result = borderBottomColor();
+        borderStyle = borderBottomStyle();
         break;
     case CSSPropertyColor:
-        result = style->color();
+        result = color();
         break;
     case CSSPropertyOutlineColor:
-        result = style->outlineColor();
+        result = outlineColor();
         break;
     case CSSPropertyWebkitColumnRuleColor:
-        result = style->columnRuleColor();
+        result = columnRuleColor();
         break;
     case CSSPropertyWebkitTextFillColor:
-        result = style->textFillColor();
+        result = textFillColor();
         break;
     case CSSPropertyWebkitTextStrokeColor:
-        result = style->textStrokeColor();
+        result = textStrokeColor();
         break;
     default:
         ASSERT_NOT_REACHED();
@@ -1043,23 +1043,23 @@ static Color colorIncludingFallback(const RenderStyle* style, int colorProperty,
             && (borderStyle == INSET || borderStyle == OUTSET || borderStyle == RIDGE || borderStyle == GROOVE))
             result.setRGB(238, 238, 238);
         else
-            result = style->color();
+            result = color();
     }
 
     return result;
 }
 
-Color RenderStyle::visitedDependentColor(int colorProperty) const
+const Color RenderStyle::visitedDependentColor(int colorProperty) const
 {
     EBorderStyle borderStyle = borderStyleForColorProperty(this, colorProperty);
-    Color unvisitedColor = colorIncludingFallback(this, colorProperty, borderStyle);
+    Color unvisitedColor = colorIncludingFallback(colorProperty, borderStyle);
     if (insideLink() != InsideVisitedLink)
         return unvisitedColor;
 
     RenderStyle* visitedStyle = getCachedPseudoStyle(VISITED_LINK);
     if (!visitedStyle)
         return unvisitedColor;
-    Color visitedColor = colorIncludingFallback(visitedStyle, colorProperty, borderStyle);
+    Color visitedColor = visitedStyle->colorIncludingFallback(colorProperty, borderStyle);
 
     // Take the alpha from the unvisited color, but get the RGB values from the visited color.
     return Color(visitedColor.red(), visitedColor.green(), visitedColor.blue(), unvisitedColor.alpha());
index 95d4b2e..e99e7ff 100644 (file)
@@ -32,6 +32,7 @@
 #include "CSSHelper.h"
 #include "CSSImageGeneratorValue.h"
 #include "CSSPrimitiveValue.h"
+#include "CSSPropertyNames.h"
 #include "CSSReflectionDirection.h"
 #include "CSSValueList.h"
 #include "CachedImage.h"
@@ -113,7 +114,13 @@ class StyleImage;
 typedef Vector<RefPtr<RenderStyle>, 4> PseudoStyleCache;
 
 class RenderStyle: public RefCounted<RenderStyle> {
-    friend class CSSStyleSelector;
+    friend class AnimationBase; // Used by CSS animations. We can't allow them to animate based off visited colors.
+    friend class ApplyStyleCommand; // Editing has to only reveal unvisited info.
+    friend class CSSStyleSelector; // Sets members directly.
+    friend class CSSComputedStyleDeclaration; // Ignores visited styles, so needs to be able to see unvisited info.
+    friend class PropertyWrapperMaybeInvalidColor; // Used by CSS animations. We can't allow them to animate based off visited colors.
+    friend class RenderSVGResource; // FIXME: Needs to alter the visited state by hand. Should clean the SVG code up and move it into RenderStyle perhaps.
+    friend class RenderTreeAsText; // FIXME: Only needed so the render tree can keep lying and dump the wrong colors.  Rebaselining would allow this to be yanked.
 protected:
 
     // The following bitfield is 32-bits long, which optimizes padding with the
@@ -341,12 +348,6 @@ public:
     bool hasPadding() const { return surround->padding.nonZero(); }
     bool hasOffset() const { return surround->offset.nonZero(); }
 
-    bool hasBackground() const
-    {
-        if (backgroundColor().isValid() && backgroundColor().alpha() > 0)
-            return true;
-        return m_background->background().hasImage();
-    }
     bool hasBackgroundImage() const { return m_background->background().hasImage(); }
     bool hasFixedBackgroundImage() const { return m_background->background().hasFixedImage(); }
     bool hasAppearance() const { return appearance() != NoControlPart; }
@@ -401,19 +402,15 @@ public:
 
     unsigned short borderLeftWidth() const { return surround->border.borderLeftWidth(); }
     EBorderStyle borderLeftStyle() const { return surround->border.left().style(); }
-    const Color& borderLeftColor() const { return surround->border.left().color(); }
     bool borderLeftIsTransparent() const { return surround->border.left().isTransparent(); }
     unsigned short borderRightWidth() const { return surround->border.borderRightWidth(); }
     EBorderStyle borderRightStyle() const { return surround->border.right().style(); }
-    const Color& borderRightColor() const { return surround->border.right().color(); }
     bool borderRightIsTransparent() const { return surround->border.right().isTransparent(); }
     unsigned short borderTopWidth() const { return surround->border.borderTopWidth(); }
     EBorderStyle borderTopStyle() const { return surround->border.top().style(); }
-    const Color& borderTopColor() const { return surround->border.top().color(); }
     bool borderTopIsTransparent() const { return surround->border.top().isTransparent(); }
     unsigned short borderBottomWidth() const { return surround->border.borderBottomWidth(); }
     EBorderStyle borderBottomStyle() const { return surround->border.bottom().style(); }
-    const Color& borderBottomColor() const { return surround->border.bottom().color(); }
     bool borderBottomIsTransparent() const { return surround->border.bottom().isTransparent(); }
 
     unsigned short outlineSize() const { return max(0, outlineWidth() + outlineOffset()); }
@@ -426,8 +423,7 @@ public:
     bool hasOutline() const { return outlineWidth() > 0 && outlineStyle() > BHIDDEN; }
     EBorderStyle outlineStyle() const { return m_background->outline().style(); }
     bool outlineStyleIsAuto() const { return m_background->outline().isAuto(); }
-    const Color& outlineColor() const { return m_background->outline().color(); }
-
+    
     EOverflow overflowX() const { return static_cast<EOverflow>(noninherited_flags._overflowX); }
     EOverflow overflowY() const { return static_cast<EOverflow>(noninherited_flags._overflowY); }
 
@@ -451,7 +447,6 @@ public:
     const FontDescription& fontDescription() const { return inherited->font.fontDescription(); }
     int fontSize() const { return inherited->font.pixelSize(); }
 
-    const Color& color() const { return inherited->color; }
     Length textIndent() const { return rareInheritedData->indent; }
     ETextAlign textAlign() const { return static_cast<ETextAlign>(inherited_flags._text_align); }
     ETextTransform textTransform() const { return static_cast<ETextTransform>(inherited_flags._text_transform); }
@@ -535,7 +530,6 @@ public:
         return wordBreak() == BreakWordBreak || wordWrap() == BreakWordWrap;
     }
 
-    const Color& backgroundColor() const { return m_background->color(); }
     StyleImage* backgroundImage() const { return m_background->background().image(); }
     EFillRepeat backgroundRepeatX() const { return static_cast<EFillRepeat>(m_background->background().repeatX()); }
     EFillRepeat backgroundRepeatY() const { return static_cast<EFillRepeat>(m_background->background().repeatY()); }
@@ -616,9 +610,7 @@ public:
     }
 
     const ShadowData* textShadow() const { return rareInheritedData->textShadow; }
-    const Color& textStrokeColor() const { return rareInheritedData->textStrokeColor; }
     float textStrokeWidth() const { return rareInheritedData->textStrokeWidth; }
-    const Color& textFillColor() const { return rareInheritedData->textFillColor; }
     ColorSpace colorSpace() const { return static_cast<ColorSpace>(rareInheritedData->colorSpace); }
     float opacity() const { return rareNonInheritedData->opacity; }
     ControlPart appearance() const { return static_cast<ControlPart>(rareNonInheritedData->m_appearance); }
@@ -664,7 +656,6 @@ public:
     bool specifiesColumns() const { return !hasAutoColumnCount() || !hasAutoColumnWidth(); }
     float columnGap() const { return rareNonInheritedData->m_multiCol->m_gap; }
     bool hasNormalColumnGap() const { return rareNonInheritedData->m_multiCol->m_normalGap; }
-    const Color& columnRuleColor() const { return rareNonInheritedData->m_multiCol->m_rule.color(); }
     EBorderStyle columnRuleStyle() const { return rareNonInheritedData->m_multiCol->m_rule.style(); }
     unsigned short columnRuleWidth() const { return rareNonInheritedData->m_multiCol->ruleWidth(); }
     bool columnRuleIsTransparent() const { return rareNonInheritedData->m_multiCol->m_rule.isTransparent(); }
@@ -1112,7 +1103,7 @@ public:
     unsigned childIndex() const { return m_childIndex; }
     void setChildIndex(unsigned index) { m_childIndex = index; }
 
-    Color visitedDependentColor(int colorProperty) const;
+    const Color visitedDependentColor(int colorProperty) const;
 
     // Initial values for all the properties
     static bool initialBorderCollapse() { return false; }
@@ -1212,6 +1203,21 @@ public:
     static const Vector<StyleDashboardRegion>& initialDashboardRegions();
     static const Vector<StyleDashboardRegion>& noneDashboardRegions();
 #endif
+
+private:
+    // Color accessors are all private to make sure callers use visitedDependentColor instead to access them.
+    const Color& borderLeftColor() const { return surround->border.left().color(); }
+    const Color& borderRightColor() const { return surround->border.right().color(); }
+    const Color& borderTopColor() const { return surround->border.top().color(); }
+    const Color& borderBottomColor() const { return surround->border.bottom().color(); }
+    const Color& backgroundColor() const { return m_background->color(); }
+    const Color& color() const { return inherited->color; }
+    const Color& columnRuleColor() const { return rareNonInheritedData->m_multiCol->m_rule.color(); }
+    const Color& outlineColor() const { return m_background->outline().color(); }
+    const Color& textFillColor() const { return rareInheritedData->textFillColor; }
+    const Color& textStrokeColor() const { return rareInheritedData->textStrokeColor; }
+    
+    const Color colorIncludingFallback(int colorProperty, EBorderStyle borderStyle) const;
 };
 
 } // namespace WebCore
index 880be29..48e0880 100644 (file)
@@ -502,7 +502,7 @@ static inline void adjustForCurrentColor(String& value, SVGElement* target)
         return;
 
     if (RenderObject* targetRenderer = target->renderer())
-        value = targetRenderer->style()->color().name();
+        value = targetRenderer->style()->visitedDependentColor(CSSPropertyColor).name();
 }
     
 void SVGAnimationElement::startedActiveInterval()
index f44e13c..510ccfd 100644 (file)
@@ -1,3 +1,17 @@
+2010-05-21  David Hyatt  <hyatt@apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        https://bugs.webkit.org/show_bug.cgi?id=39420
+
+        Make sure everyone who needs to is using visitedDependentColor rather than accessing styles
+        directly.
+
+        * Misc/WebNSAttributedStringExtras.mm:
+        (+[NSAttributedString _web_attributedStringFromRange:]):
+        * WebView/WebFrame.mm:
+        (-[WebFrame _bodyBackgroundColor]):
+
 2010-05-21  Oliver Hunt  <oliver@apple.com>
 
         Reviewed by Geoffrey Garen.
index eb422f1..35b2524 100644 (file)
@@ -154,12 +154,12 @@ static NSFileWrapper *fileWrapperForElement(Element* e)
         RenderStyle* style = renderer->style();
         NSFont *font = style->font().primaryFont()->getNSFont();
         [attrs.get() setObject:font forKey:NSFontAttributeName];
-        if (style->color().isValid())
-            [attrs.get() setObject:nsColor(style->color()) forKey:NSForegroundColorAttributeName];
+        if (style->visitedDependentColor(CSSPropertyColor).isValid())
+            [attrs.get() setObject:nsColor(style->visitedDependentColor(CSSPropertyColor)) forKey:NSForegroundColorAttributeName];
         else
             [attrs.get() removeObjectForKey:NSForegroundColorAttributeName];
-        if (style->backgroundColor().isValid())
-            [attrs.get() setObject:nsColor(style->backgroundColor()) forKey:NSBackgroundColorAttributeName];
+        if (style->visitedDependentColor(CSSPropertyBackgroundColor).isValid())
+            [attrs.get() setObject:nsColor(style->visitedDependentColor(CSSPropertyBackgroundColor)) forKey:NSBackgroundColorAttributeName];
         else
             [attrs.get() removeObjectForKey:NSBackgroundColorAttributeName];
 
index 5d0b02a..999f177 100644 (file)
@@ -1037,7 +1037,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader)
     RenderObject* bodyRenderer = body->renderer();
     if (!bodyRenderer)
         return nil;
-    Color color = bodyRenderer->style()->backgroundColor();
+    Color color = bodyRenderer->style()->visitedDependentColor(CSSPropertyBackgroundColor);
     if (!color.isValid())
         return nil;
     return nsColor(color);