Changeset 57292 in webkit


Ignore:
Timestamp:
Apr 8, 2010 2:29:39 PM (14 years ago)
Author:
hyatt@apple.com
Message:

WebCore: https://bugs.webkit.org/show_bug.cgi?id=24300, don't leak history info via CSS :visited.

Reviewed by Oliver Hunt.

This patch implements the policy described by David Baron here:

http://dbaron.org/mozilla/visited-privacy

Added new tests in fast/history.

  • WebCore.base.exp:

Expose functions needed for the WebKit SPI used by layout tests.

  • WebCore.xcodeproj/project.pbxproj:
  • accessibility/AccessibilityRenderObject.cpp:

(WebCore::AccessibilityRenderObject::isVisited):
Make sure accessibility objects still return visited information.

  • css/CSSComputedStyleDeclaration.cpp:

(WebCore::CSSComputedStyleDeclaration::CSSComputedStyleDeclaration):
(WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue):

  • css/CSSComputedStyleDeclaration.h:

(WebCore::computedStyle):
Add a boolean to computed style declarations that - if set - causes the computed style
to still return :visited information. For normal Web pages, this will be false. It is set
to true for the Web Inspector and by the WebKit SPI used by the layout tests.

  • css/CSSStyleSelector.cpp:

(WebCore::CSSStyleSelector::initElement):
(WebCore::CSSStyleSelector::SelectorChecker::SelectorChecker):
(WebCore::CSSStyleSelector::SelectorChecker::determineLinkState):
(WebCore::CSSStyleSelector::SelectorChecker::checkSelector):
(WebCore::CSSStyleSelector::canShareStyleWithElement):
(WebCore::CSSStyleSelector::styleForElement):
(WebCore::CSSStyleSelector::keyframeStylesForAnimation):
(WebCore::CSSStyleSelector::pseudoStyleForElement):
(WebCore::CSSStyleSelector::pseudoStyleRulesForElement):
(WebCore::CSSStyleSelector::checkSelector):
(WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector):
(WebCore::CSSStyleSelector::applyPropertyToStyle):
(WebCore::CSSStyleSelector::getColorFromPrimitiveValue):

  • css/CSSStyleSelector.h:

Rework the style selector to resolve two styles instead of one. The first forces the link to
be unvisited, and the second forces the link to be visited. The real state of the link is
cached on the principal (unvisited) style. The visited style hangs off the principal style
as a pseudo style (VISITED_LINK).

  • dom/Element.cpp:

(WebCore::Element::pseudoStyleCacheIsInvalid):
Make sure to deal with the VISITED_LINK pseudo to know when only :visited style info changed.

  • inspector/InspectorDOMAgent.cpp:

(WebCore::InspectorDOMAgent::getStyles):
Let the Web Inspector see :visited computed styles by default.

  • platform/LinkHash.cpp:

(WebCore::visitedURL):
Fix an issue where <a href=""> is not hashed properly to the document's base URI, so it wasn't
correctly reported as :visited.

  • rendering/InlineFlowBox.cpp:

(WebCore::InlineFlowBox::paintBoxDecorations):
(WebCore::InlineFlowBox::paintTextDecorations):

  • rendering/InlineTextBox.cpp:

(WebCore::InlineTextBox::paint):
(WebCore::InlineTextBox::paintSelection):

  • rendering/RenderBlock.cpp:

(WebCore::RenderBlock::paintColumnRules):
(WebCore::RenderBlock::paintObject):

  • rendering/RenderBoxModelObject.cpp:

(WebCore::RenderBoxModelObject::paintBorder):

  • rendering/RenderFieldset.cpp:

(WebCore::RenderFieldset::paintBorderMinusLegend):

  • rendering/RenderImage.cpp:

(WebCore::RenderImage::paintFocusRings):

  • rendering/RenderInline.cpp:

(WebCore::RenderInline::paintOutline):
(WebCore::RenderInline::paintOutlineForLine):

  • rendering/RenderObject.cpp:

(WebCore::RenderObject::drawLineForBoxSide):
(WebCore::RenderObject::drawArcForBoxSide):
(WebCore::RenderObject::paintOutline):
(WebCore::decorationColor):
(WebCore::RenderObject::getTextDecorationColors):

  • rendering/RenderObject.h:
  • rendering/RenderPath.cpp:

(WebCore::RenderPath::paint):

  • rendering/RenderReplaced.cpp:

(WebCore::RenderReplaced::paint):

  • rendering/RenderSVGContainer.cpp:

(WebCore::RenderSVGContainer::paint):

  • rendering/RenderSVGImage.cpp:

(WebCore::RenderSVGImage::paint):

  • rendering/RenderSVGRoot.cpp:

(WebCore::RenderSVGRoot::paint):

  • rendering/RenderTableCell.cpp:

(WebCore::RenderTableCell::collapsedLeftBorder):
(WebCore::RenderTableCell::collapsedRightBorder):
(WebCore::RenderTableCell::collapsedTopBorder):
(WebCore::RenderTableCell::collapsedBottomBorder):
(WebCore::RenderTableCell::paintCollapsedBorder):

  • rendering/style/CollapsedBorderValue.h:

(WebCore::CollapsedBorderValue::CollapsedBorderValue):
(WebCore::CollapsedBorderValue::color):
(WebCore::CollapsedBorderValue::operator==):
Patch painting code to fetch visitedDependentColors from the RenderStyle. Properties that
are honored include background-color, color, border colors, outline color, column rules,
and fill and stroke (both SVG and our custom versions).

  • rendering/style/RenderStyle.cpp:

(WebCore::RenderStyle::RenderStyle):
(WebCore::RenderStyle::diff):
(WebCore::borderStyleForColorProperty):
(WebCore::colorIncludingFallback):
(WebCore::RenderStyle::visitedDependentColor):

  • rendering/style/RenderStyle.h:

(WebCore::):
(WebCore::InheritedFlags::NonInheritedFlags::operator==):
(WebCore::InheritedFlags::setBitDefaults):
(WebCore::InheritedFlags::insideLink):
(WebCore::InheritedFlags::isLink):
(WebCore::InheritedFlags::setInsideLink):
(WebCore::InheritedFlags::setIsLink):

  • rendering/style/RenderStyleConstants.h:

Change how link information is stored. The noninherited flags now have a bit set for if you're a link
or not. The inherited flags now cache whether you're inside a visited or unvisited link (or no link at
all).

(WebCore::):

  • svg/graphics/SVGPaintServer.cpp:

(WebCore::SVGPaintServer::fillPaintServer):
(WebCore::SVGPaintServer::strokePaintServer):
Patch SVG fill/stroke painting to honor :visited.

WebKit/mac: https://bugs.webkit.org/show_bug.cgi?id=24300, don't expose history info via CSS

Reviewed by Oliver Hunt.

Add SPI so that layout tests can access computed style including :visited information.

  • WebView/WebRenderNode.mm:

(copyRenderNode):

  • WebView/WebView.mm:

(-[WebView _computedStyleIncludingVisitedInfo:forElement:]):

  • WebView/WebViewInternal.h:
  • WebView/WebViewPrivate.h:

WebKitTools: https://bugs.webkit.org/show_bug.cgi?id=24300, don't expose history info via CSS. Add a new method for
obtaining computed style with :visited info included. This allows layout tests to actually tell that
:visited is in effect.

Reviewed by Oliver Hunt.

  • DumpRenderTree/LayoutTestController.cpp:

(computedStyleIncludingVisitedInfoCallback):
(LayoutTestController::staticFunctions):

  • DumpRenderTree/LayoutTestController.h:
  • DumpRenderTree/mac/LayoutTestControllerMac.mm:

(LayoutTestController::computedStyleIncludingVisitedInfo):

LayoutTests: https://bugs.webkit.org/show_bug.cgi?id=24300, don't expose history info via CSS

Reviewed by Oliver Hunt.

  • fast/history/clicked-link-is-visited.html: Removed.
  • fast/history/nested-visited-test-expected.txt: Added.
  • fast/history/nested-visited-test.html: Added.
  • fast/history/resources/dummy.html: Added.
  • fast/history/self-is-visited-expected.txt: Added.
  • fast/history/self-is-visited.html: Added.
  • fast/history/sibling-visited-test-expected.txt: Added.
  • fast/history/sibling-visited-test.html: Added.
  • fast/history/subframe-is-visited-expected.txt: Removed.
  • fast/history/subframe-is-visited.html: Removed.
Location:
trunk
Files:
7 added
3 deleted
44 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r57291 r57292  
     12010-04-07  David Hyatt  <hyatt@apple.com>
     2
     3        Reviewed by Oliver Hunt.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=24300, don't expose history info via CSS
     6
     7        * fast/history/clicked-link-is-visited.html: Removed.
     8        * fast/history/nested-visited-test-expected.txt: Added.
     9        * fast/history/nested-visited-test.html: Added.
     10        * fast/history/resources/dummy.html: Added.
     11        * fast/history/self-is-visited-expected.txt: Added.
     12        * fast/history/self-is-visited.html: Added.
     13        * fast/history/sibling-visited-test-expected.txt: Added.
     14        * fast/history/sibling-visited-test.html: Added.
     15        * fast/history/subframe-is-visited-expected.txt: Removed.
     16        * fast/history/subframe-is-visited.html: Removed.
     17
    1182010-04-08  Ojan Vafai  <ojan@chromium.org>
    219
  • trunk/WebCore/ChangeLog

    r57288 r57292  
     12010-04-07  David Hyatt  <hyatt@apple.com>
     2
     3        Reviewed by Oliver Hunt.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=24300, don't leak history info via CSS :visited.
     6
     7        This patch implements the policy described by David Baron here:
     8       
     9        http://dbaron.org/mozilla/visited-privacy
     10       
     11        Added new tests in fast/history.
     12
     13        * WebCore.base.exp:
     14        Expose functions needed for the WebKit SPI used by layout tests.
     15
     16        * WebCore.xcodeproj/project.pbxproj:
     17        * accessibility/AccessibilityRenderObject.cpp:
     18        (WebCore::AccessibilityRenderObject::isVisited):
     19        Make sure accessibility objects still return visited information.
     20       
     21        * css/CSSComputedStyleDeclaration.cpp:
     22        (WebCore::CSSComputedStyleDeclaration::CSSComputedStyleDeclaration):
     23        (WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue):
     24        * css/CSSComputedStyleDeclaration.h:
     25        (WebCore::computedStyle):
     26        Add a boolean to computed style declarations that - if set - causes the computed style
     27        to still return :visited information.  For normal Web pages, this will be false.  It is set
     28        to true for the Web Inspector and by the WebKit SPI used by the layout tests.
     29
     30        * css/CSSStyleSelector.cpp:
     31        (WebCore::CSSStyleSelector::initElement):
     32        (WebCore::CSSStyleSelector::SelectorChecker::SelectorChecker):
     33        (WebCore::CSSStyleSelector::SelectorChecker::determineLinkState):
     34        (WebCore::CSSStyleSelector::SelectorChecker::checkSelector):
     35        (WebCore::CSSStyleSelector::canShareStyleWithElement):
     36        (WebCore::CSSStyleSelector::styleForElement):
     37        (WebCore::CSSStyleSelector::keyframeStylesForAnimation):
     38        (WebCore::CSSStyleSelector::pseudoStyleForElement):
     39        (WebCore::CSSStyleSelector::pseudoStyleRulesForElement):
     40        (WebCore::CSSStyleSelector::checkSelector):
     41        (WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector):
     42        (WebCore::CSSStyleSelector::applyPropertyToStyle):
     43        (WebCore::CSSStyleSelector::getColorFromPrimitiveValue):
     44        * css/CSSStyleSelector.h:
     45        Rework the style selector to resolve two styles instead of one.  The first forces the link to
     46        be unvisited, and the second forces the link to be visited.  The real state of the link is
     47        cached on the principal (unvisited) style.  The visited style hangs off the principal style
     48        as a pseudo style (VISITED_LINK).
     49
     50        * dom/Element.cpp:
     51        (WebCore::Element::pseudoStyleCacheIsInvalid):
     52        Make sure to deal with the VISITED_LINK pseudo to know when only :visited style info changed.
     53
     54        * inspector/InspectorDOMAgent.cpp:
     55        (WebCore::InspectorDOMAgent::getStyles):
     56        Let the Web Inspector see :visited computed styles by default.
     57       
     58        * platform/LinkHash.cpp:
     59        (WebCore::visitedURL):
     60        Fix an issue where <a href=""> is not hashed properly to the document's base URI, so it wasn't
     61        correctly reported as :visited.
     62
     63        * rendering/InlineFlowBox.cpp:
     64        (WebCore::InlineFlowBox::paintBoxDecorations):
     65        (WebCore::InlineFlowBox::paintTextDecorations):
     66        * rendering/InlineTextBox.cpp:
     67        (WebCore::InlineTextBox::paint):
     68        (WebCore::InlineTextBox::paintSelection):
     69        * rendering/RenderBlock.cpp:
     70        (WebCore::RenderBlock::paintColumnRules):
     71        (WebCore::RenderBlock::paintObject):
     72        * rendering/RenderBoxModelObject.cpp:
     73        (WebCore::RenderBoxModelObject::paintBorder):
     74        * rendering/RenderFieldset.cpp:
     75        (WebCore::RenderFieldset::paintBorderMinusLegend):
     76        * rendering/RenderImage.cpp:
     77        (WebCore::RenderImage::paintFocusRings):
     78        * rendering/RenderInline.cpp:
     79        (WebCore::RenderInline::paintOutline):
     80        (WebCore::RenderInline::paintOutlineForLine):
     81        * rendering/RenderObject.cpp:
     82        (WebCore::RenderObject::drawLineForBoxSide):
     83        (WebCore::RenderObject::drawArcForBoxSide):
     84        (WebCore::RenderObject::paintOutline):
     85        (WebCore::decorationColor):
     86        (WebCore::RenderObject::getTextDecorationColors):
     87        * rendering/RenderObject.h:
     88        * rendering/RenderPath.cpp:
     89        (WebCore::RenderPath::paint):
     90        * rendering/RenderReplaced.cpp:
     91        (WebCore::RenderReplaced::paint):
     92        * rendering/RenderSVGContainer.cpp:
     93        (WebCore::RenderSVGContainer::paint):
     94        * rendering/RenderSVGImage.cpp:
     95        (WebCore::RenderSVGImage::paint):
     96        * rendering/RenderSVGRoot.cpp:
     97        (WebCore::RenderSVGRoot::paint):
     98        * rendering/RenderTableCell.cpp:
     99        (WebCore::RenderTableCell::collapsedLeftBorder):
     100        (WebCore::RenderTableCell::collapsedRightBorder):
     101        (WebCore::RenderTableCell::collapsedTopBorder):
     102        (WebCore::RenderTableCell::collapsedBottomBorder):
     103        (WebCore::RenderTableCell::paintCollapsedBorder):
     104        * rendering/style/CollapsedBorderValue.h:
     105        (WebCore::CollapsedBorderValue::CollapsedBorderValue):
     106        (WebCore::CollapsedBorderValue::color):
     107        (WebCore::CollapsedBorderValue::operator==):
     108        Patch painting code to fetch visitedDependentColors from the RenderStyle.  Properties that
     109        are honored include background-color, color, border colors, outline color, column rules,
     110        and fill and stroke (both SVG and our custom versions).
     111   
     112        * rendering/style/RenderStyle.cpp:
     113        (WebCore::RenderStyle::RenderStyle):
     114        (WebCore::RenderStyle::diff):
     115        (WebCore::borderStyleForColorProperty):
     116        (WebCore::colorIncludingFallback):
     117        (WebCore::RenderStyle::visitedDependentColor):
     118        * rendering/style/RenderStyle.h:
     119        (WebCore::):
     120        (WebCore::InheritedFlags::NonInheritedFlags::operator==):
     121        (WebCore::InheritedFlags::setBitDefaults):
     122        (WebCore::InheritedFlags::insideLink):
     123        (WebCore::InheritedFlags::isLink):
     124        (WebCore::InheritedFlags::setInsideLink):
     125        (WebCore::InheritedFlags::setIsLink):
     126        * rendering/style/RenderStyleConstants.h:
     127        Change how link information is stored.  The noninherited flags now have a bit set for if you're a link
     128        or not.  The inherited flags now cache whether you're inside a visited or unvisited link (or no link at
     129        all).
     130
     131        (WebCore::):
     132        * svg/graphics/SVGPaintServer.cpp:
     133        (WebCore::SVGPaintServer::fillPaintServer):
     134        (WebCore::SVGPaintServer::strokePaintServer):
     135        Patch SVG fill/stroke painting to honor :visited.
     136
    11372010-04-08  Benjamin Otte  <otte@gnome.org>
    2138
  • trunk/WebCore/WebCore.base.exp

    r57277 r57292  
    367367__ZN7WebCore15GraphicsContextD1Ev
    368368__ZN7WebCore15JSDOMWindowBase18commonJSGlobalDataEv
     369__ZN7WebCore9JSElement6s_infoE
    369370__ZN7WebCore15ScrollAlignment17alignCenterAlwaysE
    370371__ZN7WebCore15ScrollAlignment19alignToEdgeIfNeededE
     
    477478__ZN7WebCore26usesTestModeFocusRingColorEv
    478479__ZN7WebCore27applicationIsAdobeInstallerEv
     480__ZN7WebCore27CSSComputedStyleDeclarationC1EN3WTF10PassRefPtrINS_4NodeEEEb
    479481__ZN7WebCore29isCharacterSmartReplaceExemptEib
    480482__ZN7WebCore29setUsesTestModeFocusRingColorEb
     
    10241026__ZTVN7WebCore17FrameLoaderClientE
    10251027__ZTVN7WebCore25HistoryPropertyListWriterE
     1028__ZN7WebCore4toJSEPN3JSC9ExecStateEPNS_17JSDOMGlobalObjectEPNS_19CSSStyleDeclarationE
    10261029_filenameByFixingIllegalCharacters
    10271030_hasCaseInsensitiveSubstring
  • trunk/WebCore/WebCore.xcodeproj/project.pbxproj

    r57229 r57292  
    222222                1419D2C50CEA6F6100FF507A /* TreeShared.h in Headers */ = {isa = PBXBuildFile; fileRef = 1419D2C40CEA6F6100FF507A /* TreeShared.h */; settings = {ATTRIBUTES = (Private, ); }; };
    223223                142011B60A003133008303F9 /* JSCSSStyleDeclaration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 142011B40A003133008303F9 /* JSCSSStyleDeclaration.cpp */; };
    224                 142011B70A003133008303F9 /* JSCSSStyleDeclaration.h in Headers */ = {isa = PBXBuildFile; fileRef = 142011B50A003133008303F9 /* JSCSSStyleDeclaration.h */; };
     224                142011B70A003133008303F9 /* JSCSSStyleDeclaration.h in Headers */ = {isa = PBXBuildFile; fileRef = 142011B50A003133008303F9 /* JSCSSStyleDeclaration.h */; settings = {ATTRIBUTES = (Private, ); }; };
    225225                1432E8470C51493800B1500F /* GCController.h in Headers */ = {isa = PBXBuildFile; fileRef = 1432E8460C51493800B1500F /* GCController.h */; settings = {ATTRIBUTES = (Private, ); }; };
    226226                1432E8490C51493F00B1500F /* GCController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1432E8480C51493F00B1500F /* GCController.cpp */; };
     
    12391239                65DF31F809D1CC60000BE325 /* JSDOMImplementation.h in Headers */ = {isa = PBXBuildFile; fileRef = 65DF31E409D1CC60000BE325 /* JSDOMImplementation.h */; };
    12401240                65DF31F909D1CC60000BE325 /* JSElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65DF31E509D1CC60000BE325 /* JSElement.cpp */; };
    1241                 65DF31FA09D1CC60000BE325 /* JSElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 65DF31E609D1CC60000BE325 /* JSElement.h */; };
     1241                65DF31FA09D1CC60000BE325 /* JSElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 65DF31E609D1CC60000BE325 /* JSElement.h */; settings = {ATTRIBUTES = (Private, ); }; };
    12421242                65DF31FB09D1CC60000BE325 /* JSMutationEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65DF31E709D1CC60000BE325 /* JSMutationEvent.cpp */; };
    12431243                65DF31FC09D1CC60000BE325 /* JSMutationEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 65DF31E809D1CC60000BE325 /* JSMutationEvent.h */; };
     
    44634463                BC926F800C0552470082776B /* JSHTMLFrameSetElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC926F7E0C0552470082776B /* JSHTMLFrameSetElement.cpp */; };
    44644464                BC926F810C0552470082776B /* JSHTMLFrameSetElement.h in Headers */ = {isa = PBXBuildFile; fileRef = BC926F7F0C0552470082776B /* JSHTMLFrameSetElement.h */; };
     4465                BC9439C3116CF4940048C750 /* JSNodeCustom.h in Headers */ = {isa = PBXBuildFile; fileRef = BC9439C2116CF4940048C750 /* JSNodeCustom.h */; settings = {ATTRIBUTES = (Private, ); }; };
    44654466                BC9462D8107A7B4C00857193 /* BeforeLoadEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = BC9462D7107A7B4C00857193 /* BeforeLoadEvent.h */; };
    44664467                BC946346107A934B00857193 /* JSBeforeLoadEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC946345107A934B00857193 /* JSBeforeLoadEvent.cpp */; };
     
    46164617                BCE99EC40DCA624100182683 /* JSXSLTProcessorConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BCE99EC20DCA624100182683 /* JSXSLTProcessorConstructor.h */; };
    46174618                BCEA478F097CAAC80094C9E4 /* CSSComputedStyleDeclaration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEA477C097CAAC80094C9E4 /* CSSComputedStyleDeclaration.cpp */; };
    4618                 BCEA4790097CAAC80094C9E4 /* CSSComputedStyleDeclaration.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEA477D097CAAC80094C9E4 /* CSSComputedStyleDeclaration.h */; };
     4619                BCEA4790097CAAC80094C9E4 /* CSSComputedStyleDeclaration.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEA477D097CAAC80094C9E4 /* CSSComputedStyleDeclaration.h */; settings = {ATTRIBUTES = (Private, ); }; };
    46194620                BCEA4852097D93020094C9E4 /* RenderBlockLineLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEA4813097D93020094C9E4 /* RenderBlockLineLayout.cpp */; };
    46204621                BCEA4854097D93020094C9E4 /* break_lines.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEA4815097D93020094C9E4 /* break_lines.cpp */; };
     
    98109811                BC926F7E0C0552470082776B /* JSHTMLFrameSetElement.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLFrameSetElement.cpp; sourceTree = "<group>"; };
    98119812                BC926F7F0C0552470082776B /* JSHTMLFrameSetElement.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSHTMLFrameSetElement.h; sourceTree = "<group>"; };
     9813                BC9439C2116CF4940048C750 /* JSNodeCustom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSNodeCustom.h; sourceTree = "<group>"; };
    98129814                BC9462CB107A7A3900857193 /* BeforeLoadEvent.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = BeforeLoadEvent.idl; sourceTree = "<group>"; };
    98139815                BC9462D7107A7B4C00857193 /* BeforeLoadEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BeforeLoadEvent.h; sourceTree = "<group>"; };
     
    1501815020                                A9C6E6480D7465D8006442E9 /* JSNavigatorCustom.cpp */,
    1501915021                                BCD9C2600C17AA67005C90A2 /* JSNodeCustom.cpp */,
     15022                                BC9439C2116CF4940048C750 /* JSNodeCustom.h */,
    1502015023                                BCB773600C17853D00132BA4 /* JSNodeFilterCustom.cpp */,
    1502115024                                1A750DD30A90E729000FF215 /* JSNodeIteratorCustom.cpp */,
     
    1882318826                                97C078501165D5BE003A32EF /* SuffixTree.h in Headers */,
    1882418827                                2542F4DB1166C25A00E89A86 /* UserGestureIndicator.h in Headers */,
     18828                                BC9439C3116CF4940048C750 /* JSNodeCustom.h in Headers */,
    1882518829                                C5D4AA7A116BAFB60069CA93 /* GlyphMetricsMap.h in Headers */,
    1882618830                                895253D8116C4C6800CABF00 /* FileStream.h in Headers */,
  • trunk/WebCore/accessibility/AccessibilityRenderObject.cpp

    r57093 r57292  
    18071807bool AccessibilityRenderObject::isVisited() const
    18081808{
    1809     return m_renderer->style()->pseudoState() == PseudoVisited;
     1809    // FIXME: Is it a privacy violation to expose visited information to accessibility APIs?
     1810    return m_renderer->style()->isLink() && m_renderer->style()->insideLink() == InsideVisitedLink;
    18101811}
    18111812   
  • trunk/WebCore/css/CSSComputedStyleDeclaration.cpp

    r56171 r57292  
    501501}
    502502
    503 CSSComputedStyleDeclaration::CSSComputedStyleDeclaration(PassRefPtr<Node> n)
     503CSSComputedStyleDeclaration::CSSComputedStyleDeclaration(PassRefPtr<Node> n, bool allowVisitedStyle)
    504504    : m_node(n)
     505    , m_allowVisitedStyle(allowVisitedStyle)
    505506{
    506507}
     
    676677
    677678        case CSSPropertyBackgroundColor:
    678             return CSSPrimitiveValue::createColor(style->backgroundColor().rgb());
     679            return CSSPrimitiveValue::createColor(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor).rgb() : style->backgroundColor().rgb());
    679680        case CSSPropertyBackgroundImage:
    680681            if (style->backgroundImage())
     
    733734            return CSSPrimitiveValue::create(style->verticalBorderSpacing(), CSSPrimitiveValue::CSS_PX);
    734735        case CSSPropertyBorderTopColor:
    735             return currentColorOrValidColor(style.get(), style->borderTopColor());
     736            return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyBorderTopColor).rgb()) : currentColorOrValidColor(style.get(), style->borderTopColor());
    736737        case CSSPropertyBorderRightColor:
    737             return currentColorOrValidColor(style.get(), style->borderRightColor());
     738            return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyBorderRightColor).rgb()) : currentColorOrValidColor(style.get(), style->borderRightColor());
    738739        case CSSPropertyBorderBottomColor:
    739             return currentColorOrValidColor(style.get(), style->borderBottomColor());
     740            return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyBorderBottomColor).rgb()) : currentColorOrValidColor(style.get(), style->borderBottomColor());
    740741        case CSSPropertyBorderLeftColor:
    741             return currentColorOrValidColor(style.get(), style->borderLeftColor());
     742            return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyBorderLeftColor).rgb()) : currentColorOrValidColor(style.get(), style->borderLeftColor());
    742743        case CSSPropertyBorderTopStyle:
    743744            return CSSPrimitiveValue::create(style->borderTopStyle());
     
    789790            return CSSPrimitiveValue::create(style->clear());
    790791        case CSSPropertyColor:
    791             return CSSPrimitiveValue::createColor(style->color().rgb());
     792            return CSSPrimitiveValue::createColor(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor).rgb() : style->color().rgb());
    792793        case CSSPropertyWebkitColumnCount:
    793794            if (style->hasAutoColumnCount())
     
    799800            return CSSPrimitiveValue::create(style->columnGap(), CSSPrimitiveValue::CSS_NUMBER);
    800801        case CSSPropertyWebkitColumnRuleColor:
    801             return currentColorOrValidColor(style.get(), style->columnRuleColor());
     802            return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->columnRuleColor());
    802803        case CSSPropertyWebkitColumnRuleStyle:
    803804            return CSSPrimitiveValue::create(style->columnRuleStyle());
     
    10091010            return CSSPrimitiveValue::create(style->orphans(), CSSPrimitiveValue::CSS_NUMBER);
    10101011        case CSSPropertyOutlineColor:
    1011             return currentColorOrValidColor(style.get(), style->outlineColor());
     1012            return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->outlineColor());
    10121013        case CSSPropertyOutlineStyle:
    10131014            if (style->outlineStyleIsAuto())
  • trunk/WebCore/css/CSSComputedStyleDeclaration.h

    r49959 r57292  
    3434class CSSComputedStyleDeclaration : public CSSStyleDeclaration {
    3535public:
    36     friend PassRefPtr<CSSComputedStyleDeclaration> computedStyle(PassRefPtr<Node>);
     36    friend PassRefPtr<CSSComputedStyleDeclaration> computedStyle(PassRefPtr<Node>, bool allowVisitedStyle = false);
    3737    virtual ~CSSComputedStyleDeclaration();
    3838
     
    6161
    6262private:
    63     CSSComputedStyleDeclaration(PassRefPtr<Node>);
     63    CSSComputedStyleDeclaration(PassRefPtr<Node>, bool allowVisitedStyle);
    6464
    6565    virtual void setCssText(const String&, ExceptionCode&);
     
    7171
    7272    RefPtr<Node> m_node;
     73    bool m_allowVisitedStyle;
    7374};
    7475
    75 inline PassRefPtr<CSSComputedStyleDeclaration> computedStyle(PassRefPtr<Node> node)
     76inline PassRefPtr<CSSComputedStyleDeclaration> computedStyle(PassRefPtr<Node> node, bool allowVisitedStyle)
    7677{
    77     return adoptRef(new CSSComputedStyleDeclaration(node));
     78    return adoptRef(new CSSComputedStyleDeclaration(node, allowVisitedStyle));
    7879}
    7980
  • trunk/WebCore/css/CSSStyleSelector.cpp

    r56846 r57292  
    383383RenderStyle* CSSStyleSelector::s_styleNotYetAvailable;
    384384
    385 static PseudoState pseudoState;
    386 
    387385static void loadFullDefaultStyle();
    388386static void loadSimpleDefaultStyle();
     
    803801}
    804802
    805 void CSSStyleSelector::initElementAndPseudoState(Element* e)
     803void CSSStyleSelector::initElement(Element* e)
    806804{
    807805    m_element = e;
    808     if (m_element && m_element->isStyledElement())
    809         m_styledElement = static_cast<StyledElement*>(m_element);
    810     else
    811         m_styledElement = 0;
    812     pseudoState = PseudoUnknown;
     806    m_styledElement = m_element && m_element->isStyledElement() ? static_cast<StyledElement*>(m_element) : 0;
    813807}
    814808
     
    877871    , m_pseudoStyle(NOPSEUDO)
    878872    , m_documentIsHTML(document->isHTMLDocument())
    879 {
    880 }
    881 
    882 PseudoState CSSStyleSelector::SelectorChecker::checkPseudoState(Element* element, bool checkVisited) const
    883 {
     873    , m_matchVisitedPseudoClass(false)
     874{
     875}
     876
     877EInsideLink CSSStyleSelector::SelectorChecker::determineLinkState(Element* element) const
     878{
     879    if (!element->isLink())
     880        return NotInsideLink;
     881   
    884882    const AtomicString* attr = linkAttribute(element);
    885883    if (!attr || attr->isNull())
    886         return PseudoNone;
    887 
    888     if (!checkVisited)
    889         return PseudoAnyLink;
     884        return NotInsideLink;
    890885
    891886#if PLATFORM(QT)
     
    893888    visitedURL(m_document->baseURL(), *attr, url);
    894889    if (url.isEmpty())
    895         return PseudoLink;
     890        return InsideUnvisitedLink;
    896891
    897892    // If the Qt4.4 interface for the history is used, we will have to fallback
     
    899894    QWebHistoryInterface* iface = QWebHistoryInterface::defaultInterface();
    900895    if (iface)
    901         return iface->historyContains(QString(reinterpret_cast<QChar*>(url.data()), url.size())) ? PseudoVisited : PseudoLink;
     896        return iface->historyContains(QString(reinterpret_cast<QChar*>(url.data()), url.size())) ? InsideVisitedLink : InsideUnvisitedLink;
    902897
    903898    LinkHash hash = visitedLinkHash(url.data(), url.size());
    904899    if (!hash)
    905         return PseudoLink;
     900        return InsideUnvisitedLink;
    906901#else
    907902    LinkHash hash = visitedLinkHash(m_document->baseURL(), *attr);
    908903    if (!hash)
    909         return PseudoLink;
     904        return InsideUnvisitedLink;
    910905#endif
    911906
    912907    Frame* frame = m_document->frame();
    913908    if (!frame)
    914         return PseudoLink;
     909        return InsideUnvisitedLink;
    915910
    916911    Page* page = frame->page();
    917912    if (!page)
    918         return PseudoLink;
     913        return InsideUnvisitedLink;
    919914
    920915    m_linksCheckedForVisitedState.add(hash);
    921     return page->group().isLinkVisited(hash) ? PseudoVisited : PseudoLink;
     916    return page->group().isLinkVisited(hash) ? InsideVisitedLink : InsideUnvisitedLink;
    922917}
    923918
    924919bool CSSStyleSelector::SelectorChecker::checkSelector(CSSSelector* sel, Element* element) const
    925920{
    926     pseudoState = PseudoUnknown;
    927921    PseudoId dynamicPseudo = NOPSEUDO;
    928922
     
    10321026                    mappedAttrsMatch = s->mappedAttributes()->mapsEquivalent(m_styledElement->mappedAttributes());
    10331027                if (mappedAttrsMatch) {
    1034                     bool linksMatch = true;
    1035 
    10361028                    if (s->isLink()) {
    1037                         // We need to check to see if the visited state matches.
    1038                         if (pseudoState == PseudoUnknown) {
    1039                             const Color& linkColor = m_element->document()->linkColor();
    1040                             const Color& visitedColor = m_element->document()->visitedLinkColor();
    1041                             pseudoState = m_checker.checkPseudoState(m_element, style->pseudoState() != PseudoAnyLink || linkColor != visitedColor);
    1042                         }
    1043                         linksMatch = (pseudoState == style->pseudoState());
     1029                        if (m_checker.determineLinkState(m_element) != style->insideLink())
     1030                            return false;
    10441031                    }
    1045                    
    1046                     if (linksMatch)
    1047                         return true;
     1032                    return true;
    10481033                }
    10491034            }
     
    11351120// relative units are interpreted according to document root element style, styled only with UA stylesheet
    11361121
    1137 PassRefPtr<RenderStyle> CSSStyleSelector::styleForElement(Element* e, RenderStyle* defaultParent, bool allowSharing, bool resolveForRootDefault)
     1122PassRefPtr<RenderStyle> CSSStyleSelector::styleForElement(Element* e, RenderStyle* defaultParent, bool allowSharing, bool resolveForRootDefault, bool matchVisitedRules)
    11381123{
    11391124    // Once an element has a renderer, we don't try to destroy it, since otherwise the renderer
     
    11511136    }
    11521137
    1153     initElementAndPseudoState(e);
     1138    initElement(e);
    11541139    if (allowSharing) {
    11551140        RenderStyle* sharedStyle = locateSharedStyle();
     
    11581143    }
    11591144    initForStyleResolve(e, defaultParent);
     1145   
     1146    m_checker.m_matchVisitedPseudoClass = matchVisitedRules;
    11601147
    11611148    m_style = RenderStyle::create();
     
    11661153        m_parentStyle = style();
    11671154
     1155    if (e->isLink()) {
     1156        m_style->setIsLink(true);
     1157        m_style->setInsideLink(m_checker.determineLinkState(e));
     1158    }
     1159   
    11681160    if (simpleDefaultStyleSheet && !elementCanUseSimpleDefaultStyle(e))
    11691161        loadFullDefaultStyle();
     
    12771269    }
    12781270
     1271    // Reset the value back before applying properties, so that -webkit-link knows what color to use.
     1272    m_checker.m_matchVisitedPseudoClass = matchVisitedRules;
     1273   
    12791274    // Now we have all of the matched rules in the appropriate order.  Walk the rules and apply
    12801275    // high-priority properties first, i.e., those properties that other properties depend on.
     
    13191314    adjustRenderStyle(style(), e);
    13201315
    1321     // If we are a link, cache the determined pseudo-state.
    1322     if (e->isLink())
    1323         m_style->setPseudoState(pseudoState);
    1324 
    13251316    // If we have first-letter pseudo style, do not share this style
    13261317    if (m_style->hasPseudoStyle(FIRST_LETTER))
    13271318        m_style->setUnique();
    13281319
     1320    // Compute our style allowing :visited to match.
     1321    if (!matchVisitedRules && m_style->insideLink()) {
     1322        // Fetch our parent style.
     1323        RenderStyle* parentStyle = m_parentStyle;
     1324        if (!m_style->isLink()) {
     1325            // Use the parent's visited style if one exists.
     1326            RenderStyle* parentVisitedStyle = m_parentStyle->getCachedPseudoStyle(VISITED_LINK);
     1327            if (parentVisitedStyle)
     1328                parentStyle = parentVisitedStyle;
     1329        }
     1330        RefPtr<RenderStyle> resultStyle = m_style.release();
     1331        PassRefPtr<RenderStyle> visitedStyle = styleForElement(e, parentStyle, false, false, true);
     1332        visitedStyle->setStyleType(VISITED_LINK);
     1333        resultStyle->addCachedPseudoStyle(visitedStyle);
     1334        return resultStyle.release();
     1335    }
     1336
    13291337    // Now return the style.
    13301338    return m_style.release();
     
    13491357    for (unsigned i = 0; i < rule->length(); ++i) {
    13501358        // Apply the declaration to the style. This is a simplified version of the logic in styleForElement
    1351         initElementAndPseudoState(e);
     1359        initElement(e);
    13521360        initForStyleResolve(e);
    13531361       
     
    14131421}
    14141422
    1415 PassRefPtr<RenderStyle> CSSStyleSelector::pseudoStyleForElement(PseudoId pseudo, Element* e, RenderStyle* parentStyle)
     1423PassRefPtr<RenderStyle> CSSStyleSelector::pseudoStyleForElement(PseudoId pseudo, Element* e, RenderStyle* parentStyle, bool matchVisitedLinks)
    14161424{
    14171425    if (!e)
    14181426        return 0;
    14191427
    1420     initElementAndPseudoState(e);
     1428    initElement(e);
    14211429    initForStyleResolve(e, parentStyle, pseudo);
    14221430    m_style = parentStyle;
     
    14411449        m_style->inheritFrom(parentStyle);
    14421450
    1443     m_style->noninherited_flags._styleType = pseudo;
     1451    m_style->setStyleType(pseudo);
    14441452   
    14451453    m_lineHeightValue = 0;
     
    14751483    // Clean up our style object's display and text decorations (among other fixups).
    14761484    adjustRenderStyle(style(), 0);
     1485
     1486    // Compute our :visited style.
     1487    if (!matchVisitedLinks && m_style->insideLink()) {
     1488        // Fetch our parent style.
     1489        RenderStyle* parentStyle = m_parentStyle;
     1490        if (parentStyle) {
     1491            RenderStyle* parentVisitedStyle = m_parentStyle->getCachedPseudoStyle(VISITED_LINK);
     1492            if (parentVisitedStyle)
     1493                parentStyle = parentVisitedStyle;
     1494        }
     1495        RefPtr<RenderStyle> resultStyle = m_style.release();
     1496        RefPtr<RenderStyle> visitedStyle = pseudoStyleForElement(pseudo, e, parentStyle, true);
     1497        visitedStyle->setStyleType(VISITED_LINK);
     1498        resultStyle->addCachedPseudoStyle(visitedStyle.release());
     1499        return resultStyle.release();
     1500    }
    14771501
    14781502    // Now return the style.
     
    17331757    m_checker.m_collectRulesOnly = true;
    17341758
    1735     initElementAndPseudoState(e);
     1759    initElement(e);
    17361760    initForStyleResolve(e, 0, pseudoId);
    17371761
     
    17641788
    17651789    // Check the selector
    1766     SelectorMatch match = m_checker.checkSelector(sel, m_element, &m_selectorAttrs, m_dynamicPseudo, true, false, style(), m_parentStyle);
     1790    SelectorMatch match = m_checker.checkSelector(sel, m_element, &m_selectorAttrs, m_dynamicPseudo, false, false, style(), m_parentStyle);
    17671791    if (match != SelectorMatches)
    17681792        return false;
     
    17791803// * SelectorFailsLocally    - the selector fails for the element e
    17801804// * SelectorFailsCompletely - the selector fails for e and any sibling or ancestor of e
    1781 CSSStyleSelector::SelectorMatch CSSStyleSelector::SelectorChecker::checkSelector(CSSSelector* sel, Element* e, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isAncestor, bool isSubSelector, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const
     1805CSSStyleSelector::SelectorMatch CSSStyleSelector::SelectorChecker::checkSelector(CSSSelector* sel, Element* e, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const
    17821806{
    17831807#if ENABLE(SVG)
     
    17891813
    17901814    // first selector has to match
    1791     if (!checkOneSelector(sel, e, selectorAttrs, dynamicPseudo, isAncestor, isSubSelector, elementStyle, elementParentStyle))
     1815    if (!checkOneSelector(sel, e, selectorAttrs, dynamicPseudo, isSubSelector, elementStyle, elementParentStyle))
    17921816        return SelectorFailsLocally;
    17931817
     
    18041828        if (m_pseudoStyle != NOPSEUDO && m_pseudoStyle != dynamicPseudo)
    18051829            return SelectorFailsCompletely;
     1830
     1831    // Check for nested links.
     1832    if (m_matchVisitedPseudoClass) {
     1833        RenderStyle* currentStyle = elementStyle ? elementStyle : e->renderStyle();
     1834        if (currentStyle && currentStyle->insideLink() && e->isLink()) {
     1835            if (encounteredLink)
     1836                m_matchVisitedPseudoClass = false; // This link is not relevant to the style being resolved, so disable matching.
     1837            else
     1838                encounteredLink = true;
     1839        }
     1840    }
    18061841
    18071842    switch (relation) {
     
    18121847                    return SelectorFailsCompletely;
    18131848                e = static_cast<Element*>(n);
    1814                 SelectorMatch match = checkSelector(sel, e, selectorAttrs, dynamicPseudo, true, false);
     1849                SelectorMatch match = checkSelector(sel, e, selectorAttrs, dynamicPseudo, false, encounteredLink);
    18151850                if (match != SelectorFailsLocally)
    18161851                    return match;
     
    18231858                return SelectorFailsCompletely;
    18241859            e = static_cast<Element*>(n);
    1825             return checkSelector(sel, e, selectorAttrs, dynamicPseudo, true, false);
     1860            return checkSelector(sel, e, selectorAttrs, dynamicPseudo, false, encounteredLink);
    18261861        }
    18271862        case CSSSelector::DirectAdjacent:
     
    18381873                return SelectorFailsLocally;
    18391874            e = static_cast<Element*>(n);
    1840             return checkSelector(sel, e, selectorAttrs, dynamicPseudo, false, false);
     1875            m_matchVisitedPseudoClass = false;
     1876            return checkSelector(sel, e, selectorAttrs, dynamicPseudo, false, encounteredLink);
    18411877        }
    18421878        case CSSSelector::IndirectAdjacent:
     
    18531889                    return SelectorFailsLocally;
    18541890                e = static_cast<Element*>(n);
    1855                 SelectorMatch match = checkSelector(sel, e, selectorAttrs, dynamicPseudo, false, false);
     1891                m_matchVisitedPseudoClass = false;
     1892                SelectorMatch match = checkSelector(sel, e, selectorAttrs, dynamicPseudo, false, encounteredLink);
    18561893                if (match != SelectorFailsLocally)
    18571894                    return match;
     
    18651902                !((RenderScrollbar::scrollbarForStyleResolve() || dynamicPseudo == SCROLLBAR_CORNER || dynamicPseudo == RESIZER) && sel->m_match == CSSSelector::PseudoClass))
    18661903                return SelectorFailsCompletely;
    1867             return checkSelector(sel, e, selectorAttrs, dynamicPseudo, isAncestor, true, elementStyle, elementParentStyle);
     1904            return checkSelector(sel, e, selectorAttrs, dynamicPseudo, true, encounteredLink, elementStyle, elementParentStyle);
    18681905    }
    18691906
     
    19381975}
    19391976
    1940 bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Element* e, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isAncestor, bool isSubSelector, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const
     1977bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Element* e, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isSubSelector, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const
    19411978{
    19421979    if (!e)
     
    20392076                ASSERT(!subSel->simpleSelector());
    20402077
    2041                 if (!checkOneSelector(subSel, e, selectorAttrs, dynamicPseudo, isAncestor, true, elementStyle, elementParentStyle))
     2078                if (!checkOneSelector(subSel, e, selectorAttrs, dynamicPseudo, true, elementStyle, elementParentStyle))
    20422079                    return true;
    20432080            }
     
    23472384                break;
    23482385            case CSSSelector::PseudoAnyLink:
    2349                 if (pseudoState == PseudoUnknown)
    2350                     pseudoState = checkPseudoState(e, false);
    2351                 if (pseudoState == PseudoAnyLink || pseudoState == PseudoLink || pseudoState == PseudoVisited)
     2386                if (e && e->isLink())
    23522387                    return true;
    23532388                break;
     
    23602395            }
    23612396            case CSSSelector::PseudoLink:
    2362                 if (pseudoState == PseudoUnknown || pseudoState == PseudoAnyLink)
    2363                     pseudoState = checkPseudoState(e);
    2364                 if (pseudoState == PseudoLink)
    2365                     return true;
     2397                if (e && e->isLink())
     2398                    return !m_matchVisitedPseudoClass;
    23662399                break;
    23672400            case CSSSelector::PseudoVisited:
    2368                 if (pseudoState == PseudoUnknown || pseudoState == PseudoAnyLink)
    2369                     pseudoState = checkPseudoState(e);
    2370                 if (pseudoState == PseudoVisited)
    2371                     return true;
     2401                if (e && e->isLink())
     2402                    return m_matchVisitedPseudoClass;
    23722403                break;
    23732404            case CSSSelector::PseudoDrag: {
     
    29552986void CSSStyleSelector::applyPropertyToStyle(int id, CSSValue *value, RenderStyle* style)
    29562987{
    2957     initElementAndPseudoState(0);
     2988    initElement(0);
    29582989    initForStyleResolve(0, style);
    29592990    m_style = style;
     
    60486079        if (ident == CSSValueWebkitText)
    60496080            col = m_element->document()->textColor();
    6050         else if (ident == CSSValueWebkitLink) {
    6051             const Color& linkColor = m_element->document()->linkColor();
    6052             const Color& visitedColor = m_element->document()->visitedLinkColor();
    6053             if (linkColor == visitedColor)
    6054                 col = linkColor;
    6055             else {
    6056                 if (pseudoState == PseudoUnknown || pseudoState == PseudoAnyLink)
    6057                     pseudoState = m_checker.checkPseudoState(m_element);
    6058                 col = (pseudoState == PseudoLink) ? linkColor : visitedColor;
    6059             }
    6060         } else if (ident == CSSValueWebkitActivelink)
     6081        else if (ident == CSSValueWebkitLink)
     6082            col = m_element->isLink() && m_checker.m_matchVisitedPseudoClass ? m_element->document()->visitedLinkColor() : m_element->document()->linkColor();
     6083        else if (ident == CSSValueWebkitActivelink)
    60616084            col = m_element->document()->activeLinkColor();
    60626085        else if (ident == CSSValueWebkitFocusRingColor)
  • trunk/WebCore/css/CSSStyleSelector.h

    r56608 r57292  
    8686        ~CSSStyleSelector();
    8787
    88         void initElementAndPseudoState(Element*);
     88        void initElement(Element*);
    8989        void initForStyleResolve(Element*, RenderStyle* parentStyle = 0, PseudoId = NOPSEUDO);
    90         PassRefPtr<RenderStyle> styleForElement(Element*, RenderStyle* parentStyle = 0, bool allowSharing = true, bool resolveForRootDefault = false);
     90        PassRefPtr<RenderStyle> styleForElement(Element*, RenderStyle* parentStyle = 0, bool allowSharing = true, bool resolveForRootDefault = false, bool matchVisitedLinks = false);
    9191        void keyframeStylesForAnimation(Element*, const RenderStyle*, KeyframeList& list);
    9292
    93         PassRefPtr<RenderStyle> pseudoStyleForElement(PseudoId, Element*, RenderStyle* parentStyle = 0);
     93        PassRefPtr<RenderStyle> pseudoStyleForElement(PseudoId, Element*, RenderStyle* parentStyle = 0, bool matchVisitedLinks = false);
    9494
    9595        static PassRefPtr<RenderStyle> styleForDocument(Document*);
     
    197197
    198198            bool checkSelector(CSSSelector*, Element*) const;
    199             SelectorMatch checkSelector(CSSSelector*, Element*, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isAncestor, bool isSubSelector, RenderStyle* = 0, RenderStyle* elementParentStyle = 0) const;
    200             bool checkOneSelector(CSSSelector*, Element*, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isAncestor, bool isSubSelector, RenderStyle*, RenderStyle* elementParentStyle) const;
    201             PseudoState checkPseudoState(Element*, bool checkVisited = true) const;
     199            SelectorMatch checkSelector(CSSSelector*, Element*, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle* = 0, RenderStyle* elementParentStyle = 0) const;
     200            bool checkOneSelector(CSSSelector*, Element*, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isSubSelector, RenderStyle*, RenderStyle* elementParentStyle) const;
    202201            bool checkScrollbarPseudoClass(CSSSelector*, PseudoId& dynamicPseudo) const;
    203202
     203            EInsideLink determineLinkState(Element* element) const;
    204204            void allVisitedStateChanged();
    205205            void visitedStateChanged(LinkHash visitedHash);
     
    210210            PseudoId m_pseudoStyle;
    211211            bool m_documentIsHTML;
     212            mutable bool m_matchVisitedPseudoClass;
    212213            mutable HashSet<LinkHash, LinkHashHash> m_linksCheckedForVisitedState;
    213214        };
     
    280281        bool m_fontDirty;
    281282        bool m_matchAuthorAndUserStyles;
    282 
     283       
    283284        RefPtr<CSSFontSelector> m_fontSelector;
    284285        HashSet<AtomicStringImpl*> m_selectorAttrs;
  • trunk/WebCore/dom/Element.cpp

    r57148 r57292  
    869869        RefPtr<RenderStyle> newPseudoStyle;
    870870        PseudoId pseudoId = pseudoStyleCache[i]->styleType();
    871         if (pseudoId == FIRST_LINE || pseudoId == FIRST_LINE_INHERITED)
     871        if (pseudoId == VISITED_LINK) {
     872            newPseudoStyle =  newStyle->getCachedPseudoStyle(VISITED_LINK); // This pseudo-style was aggressively computed already when we first called styleForElement on the new style.
     873            if (!newPseudoStyle || *newPseudoStyle != *pseudoStyleCache[i])
     874                return true;
     875        } else if (pseudoId == FIRST_LINE || pseudoId == FIRST_LINE_INHERITED)
    872876            newPseudoStyle = renderer()->uncachedFirstLineStyle(newStyle);
    873877        else
    874878            newPseudoStyle = renderer()->getUncachedPseudoStyle(pseudoId, newStyle, newStyle);
    875 
     879        if (!newPseudoStyle)
     880            return true;
    876881        if (*newPseudoStyle != *pseudoStyleCache[i]) {
    877882            if (pseudoId < FIRST_INTERNAL_PSEUDOID)
  • trunk/WebCore/inspector/InspectorDOMAgent.cpp

    r56846 r57292  
    3535
    3636#include "AtomicString.h"
     37#include "CSSComputedStyleDeclaration.h"
    3738#include "CSSMutableStyleDeclaration.h"
    3839#include "CSSRule.h"
    3940#include "CSSRuleList.h"
    40 #include "CSSStyleDeclaration.h"
    4141#include "CSSStyleRule.h"
    4242#include "CSSStyleSelector.h"
     
    776776
    777777    Element* element = static_cast<Element*>(node);
    778     RefPtr<CSSStyleDeclaration> computedStyle = defaultView->getComputedStyle(element, "");
     778    RefPtr<CSSComputedStyleDeclaration> computedStyleInfo = computedStyle(node, true); // Support the viewing of :visited information in computed style.
    779779
    780780    ScriptObject result = m_frontend->newScriptObject();
    781781    if (element->style())
    782782        result.set("inlineStyle", buildObjectForStyle(element->style(), true));
    783     result.set("computedStyle", buildObjectForStyle(computedStyle.get(), false));
     783    result.set("computedStyle", buildObjectForStyle(computedStyleInfo.get(), false));
    784784
    785785    CSSStyleSelector* selector = element->ownerDocument()->styleSelector();
  • trunk/WebCore/platform/LinkHash.cpp

    r53809 r57292  
    155155void visitedURL(const KURL& base, const AtomicString& attributeURL, Vector<UChar, 512>& buffer)
    156156{
     157    if (attributeURL.isNull())
     158        return;
     159
    157160    const UChar* characters = attributeURL.characters();
    158161    unsigned length = attributeURL.length();
    159     if (!length)
    160         return;
    161162
    162163    // This is a poor man's completeURL. Faster with less memory allocation.
     
    187188    }
    188189
    189     switch (characters[0]) {
    190         case '/':
    191             buffer.append(base.string().characters(), base.pathStart());
    192             break;
    193         case '#':
    194             buffer.append(base.string().characters(), base.pathEnd());
    195             break;
    196         default:
    197             buffer.append(base.string().characters(), base.pathAfterLastSlash());
    198             break;
     190    if (!length)
     191        buffer.append(base.string().characters(), base.string().length());
     192    else {
     193        switch (characters[0]) {
     194            case '/':
     195                buffer.append(base.string().characters(), base.pathStart());
     196                break;
     197            case '#':
     198                buffer.append(base.string().characters(), base.pathEnd());
     199                break;
     200            default:
     201                buffer.append(base.string().characters(), base.pathAfterLastSlash());
     202                break;
     203        }
    199204    }
    200205    buffer.append(characters, length);
  • trunk/WebCore/rendering/InlineFlowBox.cpp

    r57215 r57292  
    2222
    2323#include "CachedImage.h"
     24#include "CSSPropertyNames.h"
    2425#include "Document.h"
    2526#include "EllipsisBox.h"
     
    765766            paintBoxShadow(context, styleToUse, Normal, tx, ty, w, h);
    766767
    767         Color c = styleToUse->backgroundColor();
     768        Color c = styleToUse->visitedDependentColor(CSSPropertyBackgroundColor);
    768769        paintFillLayers(paintInfo, c, styleToUse->backgroundLayers(), tx, ty, w, h);
    769770
     
    962963
    963964        Color underline, overline, linethrough;
    964         underline = overline = linethrough = styleToUse->color();
     965        underline = overline = linethrough = styleToUse->visitedDependentColor(CSSPropertyColor);
    965966        if (!parent())
    966967            renderer()->getTextDecorationColors(deco, underline, overline, linethrough);
  • trunk/WebCore/rendering/InlineTextBox.cpp

    r57215 r57292  
    412412        textStrokeColor = Color::black;
    413413    } else {
    414         textFillColor = styleToUse->textFillColor();
    415         if (!textFillColor.isValid())
    416             textFillColor = styleToUse->color();
    417 
     414        textFillColor = styleToUse->visitedDependentColor(CSSPropertyWebkitTextFillColor);
     415       
    418416        // Make the text fill color legible against a white background
    419417        if (styleToUse->forceBackgroundsToWhite())
    420418            textFillColor = correctedTextColor(textFillColor, Color::white);
    421419
    422         textStrokeColor = styleToUse->textStrokeColor();
    423         if (!textStrokeColor.isValid())
    424             textStrokeColor = styleToUse->color();
    425 
     420        textStrokeColor = styleToUse->visitedDependentColor(CSSPropertyWebkitTextStrokeColor);
     421       
    426422        // Make the text stroke color legible against a white background
    427423        if (styleToUse->forceBackgroundsToWhite())
     
    518514    // Paint decorations
    519515    if (d != TDNONE && paintInfo.phase != PaintPhaseSelection && styleToUse->htmlHacks()) {
    520         context->setStrokeColor(styleToUse->color(), styleToUse->colorSpace());
     516        context->setStrokeColor(styleToUse->visitedDependentColor(CSSPropertyColor), styleToUse->colorSpace());
    521517        paintDecoration(context, tx, ty, d, textShadow);
    522518    }
     
    578574        return;
    579575
    580     Color textColor = style->color();
     576    Color textColor = style->visitedDependentColor(CSSPropertyColor);
    581577    Color c = renderer()->selectionBackgroundColor();
    582578    if (!c.isValid() || c.alpha() == 0)
  • trunk/WebCore/rendering/RenderBlock.cpp

    r56297 r57292  
    15471547void RenderBlock::paintColumnRules(PaintInfo& paintInfo, int tx, int ty)
    15481548{
    1549     const Color& ruleColor = style()->columnRuleColor();
     1549    const Color& ruleColor = style()->visitedDependentColor(CSSPropertyWebkitColumnRuleColor);
    15501550    bool ruleTransparent = style()->columnRuleIsTransparent();
    15511551    EBorderStyle ruleStyle = style()->columnRuleStyle();
     
    15821582            int ruleBottom = ruleTop + contentHeight();
    15831583            drawLineForBoxSide(paintInfo.context, ruleStart, ruleTop, ruleEnd, ruleBottom,
    1584                                style()->direction() == LTR ? BSLeft : BSRight, ruleColor, style()->color(), ruleStyle, 0, 0);
     1584                               style()->direction() == LTR ? BSLeft : BSRight, ruleColor, ruleStyle, 0, 0);
    15851585        }
    15861586       
     
    17611761    // 5. paint outline.
    17621762    if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style()->visibility() == VISIBLE)
    1763         paintOutline(paintInfo.context, tx, ty, width(), height(), style());
     1763        paintOutline(paintInfo.context, tx, ty, width(), height());
    17641764
    17651765    // 6. paint continuation outlines.
  • trunk/WebCore/rendering/RenderBoxModelObject.cpp

    r57287 r57292  
    921921
    922922void RenderBoxModelObject::paintBorder(GraphicsContext* graphicsContext, int tx, int ty, int w, int h,
    923                                const RenderStyle* style, bool begin, bool end)
     923                                       const RenderStyle* style, bool begin, bool end)
    924924{
    925925    if (paintNinePieceImage(graphicsContext, tx, ty, w, h, style, style->borderImage()))
    926926        return;
    927927
    928     const Color& topColor = style->borderTopColor();
    929     const Color& bottomColor = style->borderBottomColor();
    930     const Color& leftColor = style->borderLeftColor();
    931     const Color& rightColor = style->borderRightColor();
     928    const Color& topColor = style->visitedDependentColor(CSSPropertyBorderTopColor);
     929    const Color& bottomColor = style->visitedDependentColor(CSSPropertyBorderBottomColor);
     930    const Color& leftColor = style->visitedDependentColor(CSSPropertyBorderLeftColor);
     931    const Color& rightColor = style->visitedDependentColor(CSSPropertyBorderRightColor);
    932932
    933933    bool topTransparent = style->borderTopIsTransparent();
     
    994994        }
    995995
    996         drawLineForBoxSide(graphicsContext, x, ty, x2, ty + style->borderTopWidth(), BSTop, topColor, style->color(), topStyle,
     996        drawLineForBoxSide(graphicsContext, x, ty, x2, ty + style->borderTopWidth(), BSTop, topColor, topStyle,
    997997                   ignore_left ? 0 : style->borderLeftWidth(), ignore_right ? 0 : style->borderRightWidth());
    998998
     
    10221022                // Draw upper left arc
    10231023                drawArcForBoxSide(graphicsContext, leftX, leftY, thickness, topLeft, firstAngleStart, firstAngleSpan,
    1024                               BSTop, topColor, style->color(), topStyle, true);
     1024                              BSTop, topColor, topStyle, true);
    10251025                if (applyLeftInnerClip)
    10261026                    graphicsContext->restore();
     
    10481048                // Draw upper right arc
    10491049                drawArcForBoxSide(graphicsContext, rightX, leftY, thickness, topRight, secondAngleStart, secondAngleSpan,
    1050                               BSTop, topColor, style->color(), topStyle, false);
     1050                              BSTop, topColor, topStyle, false);
    10511051                if (applyRightInnerClip)
    10521052                    graphicsContext->restore();
     
    10711071        }
    10721072
    1073         drawLineForBoxSide(graphicsContext, x, ty + h - style->borderBottomWidth(), x2, ty + h, BSBottom, bottomColor, style->color(), bottomStyle,
     1073        drawLineForBoxSide(graphicsContext, x, ty + h - style->borderBottomWidth(), x2, ty + h, BSBottom, bottomColor, bottomStyle,
    10741074                   ignore_left ? 0 : style->borderLeftWidth(), ignore_right ? 0 : style->borderRightWidth());
    10751075
     
    10991099                // Draw lower left arc
    11001100                drawArcForBoxSide(graphicsContext, leftX, leftY, thickness, bottomLeft, firstAngleStart, firstAngleSpan,
    1101                               BSBottom, bottomColor, style->color(), bottomStyle, true);
     1101                              BSBottom, bottomColor, bottomStyle, true);
    11021102                if (applyLeftInnerClip)
    11031103                    graphicsContext->restore();
     
    11211121                // Draw lower right arc
    11221122                drawArcForBoxSide(graphicsContext, rightX, rightY, thickness, bottomRight, secondAngleStart, secondAngleSpan,
    1123                               BSBottom, bottomColor, style->color(), bottomStyle, false);
     1123                              BSBottom, bottomColor, bottomStyle, false);
    11241124                if (applyRightInnerClip)
    11251125                    graphicsContext->restore();
     
    11441144        }
    11451145
    1146         drawLineForBoxSide(graphicsContext, tx, y, tx + style->borderLeftWidth(), y2, BSLeft, leftColor, style->color(), leftStyle,
     1146        drawLineForBoxSide(graphicsContext, tx, y, tx + style->borderLeftWidth(), y2, BSLeft, leftColor, leftStyle,
    11471147                   ignore_top ? 0 : style->borderTopWidth(), ignore_bottom ? 0 : style->borderBottomWidth());
    11481148
     
    11671167                // Draw top left arc
    11681168                drawArcForBoxSide(graphicsContext, topX, topY, thickness, topLeft, firstAngleStart, firstAngleSpan,
    1169                               BSLeft, leftColor, style->color(), leftStyle, true);
     1169                              BSLeft, leftColor, leftStyle, true);
    11701170                if (applyTopInnerClip)
    11711171                    graphicsContext->restore();
     
    11881188                // Draw bottom left arc
    11891189                drawArcForBoxSide(graphicsContext, topX, bottomY, thickness, bottomLeft, secondAngleStart, secondAngleSpan,
    1190                               BSLeft, leftColor, style->color(), leftStyle, false);
     1190                              BSLeft, leftColor, leftStyle, false);
    11911191                if (applyBottomInnerClip)
    11921192                    graphicsContext->restore();
     
    12131213        }
    12141214
    1215         drawLineForBoxSide(graphicsContext, tx + w - style->borderRightWidth(), y, tx + w, y2, BSRight, rightColor, style->color(), rightStyle,
     1215        drawLineForBoxSide(graphicsContext, tx + w - style->borderRightWidth(), y, tx + w, y2, BSRight, rightColor, rightStyle,
    12161216                   ignore_top ? 0 : style->borderTopWidth(), ignore_bottom ? 0 : style->borderBottomWidth());
    12171217
     
    12361236                // Draw top right arc
    12371237                drawArcForBoxSide(graphicsContext, topX, topY, thickness, topRight, firstAngleStart, firstAngleSpan,
    1238                               BSRight, rightColor, style->color(), rightStyle, true);
     1238                              BSRight, rightColor, rightStyle, true);
    12391239                if (applyTopInnerClip)
    12401240                    graphicsContext->restore();
     
    12581258                // Draw bottom right arc
    12591259                drawArcForBoxSide(graphicsContext, bottomX, bottomY, thickness, bottomRight, secondAngleStart, secondAngleSpan,
    1260                               BSRight, rightColor, style->color(), rightStyle, false);
     1260                              BSRight, rightColor, rightStyle, false);
    12611261                if (applyBottomInnerClip)
    12621262                    graphicsContext->restore();
  • trunk/WebCore/rendering/RenderFieldset.cpp

    r54311 r57292  
    2525#include "RenderFieldset.h"
    2626
     27#include "CSSPropertyNames.h"
    2728#include "HTMLNames.h"
    2829#include "GraphicsContext.h"
     
    182183                                            const RenderStyle* style, int lx, int lw, int lb)
    183184{
    184     const Color& tc = style->borderTopColor();
    185     const Color& bc = style->borderBottomColor();
     185    const Color& tc = style->visitedDependentColor(CSSPropertyBorderTopColor);
     186    const Color& bc = style->visitedDependentColor(CSSPropertyBorderBottomColor);
    186187
    187188    EBorderStyle ts = style->borderTopStyle();
     
    200201    if (render_t) {
    201202        if (lx >= borderLeftWidth)
    202             drawLineForBoxSide(graphicsContext, tx, ty, tx + min(lx, w), ty + style->borderTopWidth(), BSTop, tc, style->color(), ts,
     203            drawLineForBoxSide(graphicsContext, tx, ty, tx + min(lx, w), ty + style->borderTopWidth(), BSTop, tc, ts,
    203204                       (render_l && (ls == DOTTED || ls == DASHED || ls == DOUBLE) ? borderLeftWidth : 0),
    204205                       (lx >= w && render_r && (rs == DOTTED || rs == DASHED || rs == DOUBLE) ? borderRightWidth : 0));
    205206        if (lx + lw <=  w - borderRightWidth)
    206             drawLineForBoxSide(graphicsContext, tx + max(0, lx + lw), ty, tx + w, ty + style->borderTopWidth(), BSTop, tc, style->color(), ts,
     207            drawLineForBoxSide(graphicsContext, tx + max(0, lx + lw), ty, tx + w, ty + style->borderTopWidth(), BSTop, tc, ts,
    207208                       (lx + lw <= 0 && render_l && (ls == DOTTED || ls == DASHED || ls == DOUBLE) ? borderLeftWidth : 0),
    208209                       (render_r && (rs == DOTTED || rs == DASHED || rs == DOUBLE) ? borderRightWidth : 0));
     
    210211
    211212    if (render_b)
    212         drawLineForBoxSide(graphicsContext, tx, ty + h - style->borderBottomWidth(), tx + w, ty + h, BSBottom, bc, style->color(), bs,
     213        drawLineForBoxSide(graphicsContext, tx, ty + h - style->borderBottomWidth(), tx + w, ty + h, BSBottom, bc, bs,
    213214                   (render_l && (ls == DOTTED || ls == DASHED || ls == DOUBLE) ? style->borderLeftWidth() : 0),
    214215                   (render_r && (rs == DOTTED || rs == DASHED || rs == DOUBLE) ? style->borderRightWidth() : 0));
    215216
    216217    if (render_l) {
    217         const Color& lc = style->borderLeftColor();
     218        const Color& lc = style->visitedDependentColor(CSSPropertyBorderLeftColor);
    218219        int startY = ty;
    219220
     
    234235        }
    235236
    236         drawLineForBoxSide(graphicsContext, tx, startY, tx + borderLeftWidth, ty + h, BSLeft, lc, style->color(), ls,
    237                    ignore_top ? 0 : style->borderTopWidth(), ignore_bottom ? 0 : style->borderBottomWidth());
     237        drawLineForBoxSide(graphicsContext, tx, startY, tx + borderLeftWidth, ty + h, BSLeft, lc, ls,
     238                           ignore_top ? 0 : style->borderTopWidth(), ignore_bottom ? 0 : style->borderBottomWidth());
    238239    }
    239240
     
    258259        }
    259260
    260         drawLineForBoxSide(graphicsContext, tx + w - borderRightWidth, startY, tx + w, ty + h, BSRight, rc, style->color(), rs,
     261        drawLineForBoxSide(graphicsContext, tx + w - borderRightWidth, startY, tx + w, ty + h, BSRight, rc, rs,
    261262                   ignore_top ? 0 : style->borderTopWidth(), ignore_bottom ? 0 : style->borderBottomWidth());
    262263    }
  • trunk/WebCore/rendering/RenderImage.cpp

    r53857 r57292  
    471471        Vector<Path> focusRingPaths;
    472472        focusRingPaths.append(areaElement->getPath(this));
    473         paintInfo.context->drawFocusRing(focusRingPaths, style->outlineWidth(), style->outlineOffset(), style->outlineColor());
     473        paintInfo.context->drawFocusRing(focusRingPaths, style->outlineWidth(), style->outlineOffset(), style->visitedDependentColor(CSSPropertyOutlineColor));
    474474        break;
    475475    }
  • trunk/WebCore/rendering/RenderInline.cpp

    r55928 r57292  
    966966        return;
    967967   
    968     if (style()->outlineStyleIsAuto() || hasOutlineAnnotation()) {
    969         int ow = style()->outlineWidth();
    970         Color oc = style()->outlineColor();
    971         if (!oc.isValid())
    972             oc = style()->color();
     968    RenderStyle* styleToUse = style();
     969    if (styleToUse->outlineStyleIsAuto() || hasOutlineAnnotation()) {
     970        int ow = styleToUse->outlineWidth();
     971        Color oc = styleToUse->visitedDependentColor(CSSPropertyOutlineColor);
    973972
    974973        Vector<IntRect> focusRingRects;
    975974        addFocusRingRects(focusRingRects, tx, ty);
    976         if (style()->outlineStyleIsAuto())
    977             graphicsContext->drawFocusRing(focusRingRects, ow, style()->outlineOffset(), oc);
     975        if (styleToUse->outlineStyleIsAuto())
     976            graphicsContext->drawFocusRing(focusRingRects, ow, styleToUse->outlineOffset(), oc);
    978977        else
    979978            addPDFURLRect(graphicsContext, unionRect(focusRingRects));
    980979    }
    981980
    982     if (style()->outlineStyleIsAuto() || style()->outlineStyle() == BNONE)
     981    if (styleToUse->outlineStyleIsAuto() || styleToUse->outlineStyle() == BNONE)
    983982        return;
    984983
     
    10011000                                       const IntRect& lastline, const IntRect& thisline, const IntRect& nextline)
    10021001{
    1003     int ow = style()->outlineWidth();
    1004     EBorderStyle os = style()->outlineStyle();
    1005     Color oc = style()->outlineColor();
    1006     if (!oc.isValid())
    1007         oc = style()->color();
     1002    RenderStyle* styleToUse = style();
     1003    int ow = styleToUse->outlineWidth();
     1004    EBorderStyle os = styleToUse->outlineStyle();
     1005    Color oc = styleToUse->visitedDependentColor(CSSPropertyOutlineColor);
    10081006
    10091007    int offset = style()->outlineOffset();
     
    10211019               b + (nextline.isEmpty() || thisline.x() <= nextline.x() || (nextline.right() - 1) <= thisline.x() ? ow : 0),
    10221020               BSLeft,
    1023                oc, style()->color(), os,
     1021               oc, os,
    10241022               (lastline.isEmpty() || thisline.x() < lastline.x() || (lastline.right() - 1) <= thisline.x() ? ow : -ow),
    10251023               (nextline.isEmpty() || thisline.x() <= nextline.x() || (nextline.right() - 1) <= thisline.x() ? ow : -ow));
     
    10321030               b + (nextline.isEmpty() || nextline.right() <= thisline.right() || (thisline.right() - 1) <= nextline.x() ? ow : 0),
    10331031               BSRight,
    1034                oc, style()->color(), os,
     1032               oc, os,
    10351033               (lastline.isEmpty() || lastline.right() < thisline.right() || (thisline.right() - 1) <= lastline.x() ? ow : -ow),
    10361034               (nextline.isEmpty() || nextline.right() <= thisline.right() || (thisline.right() - 1) <= nextline.x() ? ow : -ow));
     
    10421040                   min(r+ow, (lastline.isEmpty() ? 1000000 : tx + lastline.x())),
    10431041                   t ,
    1044                    BSTop, oc, style()->color(), os,
     1042                   BSTop, oc, os,
    10451043                   ow,
    10461044                   (!lastline.isEmpty() && tx + lastline.x() + 1 < r + ow) ? -ow : ow);
     
    10521050                   r + ow,
    10531051                   t ,
    1054                    BSTop, oc, style()->color(), os,
     1052                   BSTop, oc, os,
    10551053                   (!lastline.isEmpty() && l - ow < tx + lastline.right()) ? -ow : ow,
    10561054                   ow);
     
    10631061                   min(r + ow, !nextline.isEmpty() ? tx + nextline.x() + 1 : 1000000),
    10641062                   b + ow,
    1065                    BSBottom, oc, style()->color(), os,
     1063                   BSBottom, oc, os,
    10661064                   ow,
    10671065                   (!nextline.isEmpty() && tx + nextline.x() + 1 < r + ow) ? -ow : ow);
     
    10731071                   r + ow,
    10741072                   b + ow,
    1075                    BSBottom, oc, style()->color(), os,
     1073                   BSBottom, oc, os,
    10761074                   (!nextline.isEmpty() && l - ow < tx + nextline.right()) ? -ow : ow,
    10771075                   ow);
  • trunk/WebCore/rendering/RenderObject.cpp

    r57165 r57292  
    699699
    700700void RenderObject::drawLineForBoxSide(GraphicsContext* graphicsContext, int x1, int y1, int x2, int y2,
    701                                       BoxSide s, Color c, const Color& textcolor, EBorderStyle style,
     701                                      BoxSide s, Color c, EBorderStyle style,
    702702                                      int adjbw1, int adjbw2)
    703703{
     
    706706    if (style == DOUBLE && width < 3)
    707707        style = SOLID;
    708 
    709     if (!c.isValid()) {
    710         if (style == INSET || style == OUTSET || style == RIDGE || style == GROOVE)
    711             c.setRGB(238, 238, 238);
    712         else
    713             c = textcolor;
    714     }
    715708
    716709    switch (style) {
     
    765758                        drawLineForBoxSide(graphicsContext, x1 + max((-adjbw1 * 2 + 1) / 3, 0),
    766759                                   y1, x2 - max((-adjbw2 * 2 + 1) / 3, 0), y1 + third,
    767                                    s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
     760                                   s, c, SOLID, adjbw1bigthird, adjbw2bigthird);
    768761                        drawLineForBoxSide(graphicsContext, x1 + max((adjbw1 * 2 + 1) / 3, 0),
    769762                                   y2 - third, x2 - max((adjbw2 * 2 + 1) / 3, 0), y2,
    770                                    s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
     763                                   s, c, SOLID, adjbw1bigthird, adjbw2bigthird);
    771764                        break;
    772765                    case BSLeft:
    773766                        drawLineForBoxSide(graphicsContext, x1, y1 + max((-adjbw1 * 2 + 1) / 3, 0),
    774767                                   x1 + third, y2 - max((-adjbw2 * 2 + 1) / 3, 0),
    775                                    s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
     768                                   s, c, SOLID, adjbw1bigthird, adjbw2bigthird);
    776769                        drawLineForBoxSide(graphicsContext, x2 - third, y1 + max((adjbw1 * 2 + 1) / 3, 0),
    777770                                   x2, y2 - max((adjbw2 * 2 + 1) / 3, 0),
    778                                    s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
     771                                   s, c, SOLID, adjbw1bigthird, adjbw2bigthird);
    779772                        break;
    780773                    case BSBottom:
    781774                        drawLineForBoxSide(graphicsContext, x1 + max((adjbw1 * 2 + 1) / 3, 0),
    782775                                   y1, x2 - max((adjbw2 * 2 + 1) / 3, 0), y1 + third,
    783                                    s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
     776                                   s, c, SOLID, adjbw1bigthird, adjbw2bigthird);
    784777                        drawLineForBoxSide(graphicsContext, x1 + max((-adjbw1 * 2 + 1) / 3, 0),
    785778                                   y2 - third, x2 - max((-adjbw2 * 2 + 1) / 3, 0), y2,
    786                                    s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
     779                                   s, c, SOLID, adjbw1bigthird, adjbw2bigthird);
    787780                        break;
    788781                    case BSRight:
    789782                        drawLineForBoxSide(graphicsContext, x1, y1 + max((adjbw1 * 2 + 1) / 3, 0),
    790783                                   x1 + third, y2 - max((adjbw2 * 2 + 1) / 3, 0),
    791                                    s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
     784                                   s, c, SOLID, adjbw1bigthird, adjbw2bigthird);
    792785                        drawLineForBoxSide(graphicsContext, x2 - third, y1 + max((-adjbw1 * 2 + 1) / 3, 0),
    793786                                   x2, y2 - max((-adjbw2 * 2 + 1) / 3, 0),
    794                                    s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
     787                                   s, c, SOLID, adjbw1bigthird, adjbw2bigthird);
    795788                        break;
    796789                    default:
     
    819812                case BSTop:
    820813                    drawLineForBoxSide(graphicsContext, x1 + max(-adjbw1, 0) / 2, y1, x2 - max(-adjbw2, 0) / 2, (y1 + y2 + 1) / 2,
    821                                s, c, textcolor, s1, adjbw1bighalf, adjbw2bighalf);
     814                               s, c, s1, adjbw1bighalf, adjbw2bighalf);
    822815                    drawLineForBoxSide(graphicsContext, x1 + max(adjbw1 + 1, 0) / 2, (y1 + y2 + 1) / 2, x2 - max(adjbw2 + 1, 0) / 2, y2,
    823                                s, c, textcolor, s2, adjbw1 / 2, adjbw2 / 2);
     816                               s, c, s2, adjbw1 / 2, adjbw2 / 2);
    824817                    break;
    825818                case BSLeft:
    826819                    drawLineForBoxSide(graphicsContext, x1, y1 + max(-adjbw1, 0) / 2, (x1 + x2 + 1) / 2, y2 - max(-adjbw2, 0) / 2,
    827                                s, c, textcolor, s1, adjbw1bighalf, adjbw2bighalf);
     820                               s, c, s1, adjbw1bighalf, adjbw2bighalf);
    828821                    drawLineForBoxSide(graphicsContext, (x1 + x2 + 1) / 2, y1 + max(adjbw1 + 1, 0) / 2, x2, y2 - max(adjbw2 + 1, 0) / 2,
    829                                s, c, textcolor, s2, adjbw1 / 2, adjbw2 / 2);
     822                               s, c, s2, adjbw1 / 2, adjbw2 / 2);
    830823                    break;
    831824                case BSBottom:
    832825                    drawLineForBoxSide(graphicsContext, x1 + max(adjbw1, 0) / 2, y1, x2 - max(adjbw2, 0) / 2, (y1 + y2 + 1) / 2,
    833                                s, c, textcolor, s2, adjbw1bighalf, adjbw2bighalf);
     826                               s, c, s2, adjbw1bighalf, adjbw2bighalf);
    834827                    drawLineForBoxSide(graphicsContext, x1 + max(-adjbw1 + 1, 0) / 2, (y1 + y2 + 1) / 2, x2 - max(-adjbw2 + 1, 0) / 2, y2,
    835                                s, c, textcolor, s1, adjbw1/2, adjbw2/2);
     828                               s, c, s1, adjbw1 / 2, adjbw2 / 2);
    836829                    break;
    837830                case BSRight:
    838831                    drawLineForBoxSide(graphicsContext, x1, y1 + max(adjbw1, 0) / 2, (x1 + x2 + 1) / 2, y2 - max(adjbw2, 0) / 2,
    839                                s, c, textcolor, s2, adjbw1bighalf, adjbw2bighalf);
     832                               s, c, s2, adjbw1bighalf, adjbw2bighalf);
    840833                    drawLineForBoxSide(graphicsContext, (x1 + x2 + 1) / 2, y1 + max(-adjbw1 + 1, 0) / 2, x2, y2 - max(-adjbw2 + 1, 0) / 2,
    841                                s, c, textcolor, s1, adjbw1/2, adjbw2/2);
     834                               s, c, s1, adjbw1 / 2, adjbw2 / 2);
    842835                    break;
    843836            }
     
    895888
    896889void RenderObject::drawArcForBoxSide(GraphicsContext* graphicsContext, int x, int y, float thickness, IntSize radius,
    897                                      int angleStart, int angleSpan, BoxSide s, Color c, const Color& textColor,
     890                                     int angleStart, int angleSpan, BoxSide s, Color c,
    898891                                     EBorderStyle style, bool firstCorner)
    899892{
    900893    if ((style == DOUBLE && thickness / 2 < 3) || ((style == RIDGE || style == GROOVE) && thickness / 2 < 2))
    901894        style = SOLID;
    902 
    903     if (!c.isValid()) {
    904         if (style == INSET || style == OUTSET || style == RIDGE || style == GROOVE)
    905             c.setRGB(238, 238, 238);
    906         else
    907             c = textColor;
    908     }
    909895
    910896    switch (style) {
     
    995981}
    996982
    997 void RenderObject::paintOutline(GraphicsContext* graphicsContext, int tx, int ty, int w, int h, const RenderStyle* style)
     983void RenderObject::paintOutline(GraphicsContext* graphicsContext, int tx, int ty, int w, int h)
    998984{
    999985    if (!hasOutline())
    1000986        return;
    1001987
    1002     int ow = style->outlineWidth();
    1003     EBorderStyle os = style->outlineStyle();
    1004 
    1005     Color oc = style->outlineColor();
    1006     if (!oc.isValid())
    1007         oc = style->color();
    1008 
    1009     int offset = style->outlineOffset();
    1010 
    1011     if (style->outlineStyleIsAuto() || hasOutlineAnnotation()) {
    1012         if (!theme()->supportsFocusRing(style)) {
     988    RenderStyle* styleToUse = style();
     989    int ow = styleToUse->outlineWidth();
     990    EBorderStyle os = styleToUse->outlineStyle();
     991
     992    Color oc = styleToUse->visitedDependentColor(CSSPropertyOutlineColor);
     993
     994    int offset = styleToUse->outlineOffset();
     995
     996    if (styleToUse->outlineStyleIsAuto() || hasOutlineAnnotation()) {
     997        if (!theme()->supportsFocusRing(styleToUse)) {
    1013998            // Only paint the focus ring by hand if the theme isn't able to draw the focus ring.
    1014999            Vector<IntRect> focusRingRects;
    10151000            addFocusRingRects(focusRingRects, tx, ty);
    1016             if (style->outlineStyleIsAuto())
     1001            if (styleToUse->outlineStyleIsAuto())
    10171002                graphicsContext->drawFocusRing(focusRingRects, ow, offset, oc);
    10181003            else
     
    10211006    }
    10221007
    1023     if (style->outlineStyleIsAuto() || style->outlineStyle() == BNONE)
     1008    if (styleToUse->outlineStyleIsAuto() || styleToUse->outlineStyle() == BNONE)
    10241009        return;
    10251010
     
    10321017        return;
    10331018
    1034     drawLineForBoxSide(graphicsContext, tx - ow, ty - ow, tx, ty + h + ow,
    1035                BSLeft, Color(oc), style->color(), os, ow, ow);
    1036 
    1037     drawLineForBoxSide(graphicsContext, tx - ow, ty - ow, tx + w + ow, ty,
    1038                BSTop, Color(oc), style->color(), os, ow, ow);
    1039 
    1040     drawLineForBoxSide(graphicsContext, tx + w, ty - ow, tx + w + ow, ty + h + ow,
    1041                BSRight, Color(oc), style->color(), os, ow, ow);
    1042 
    1043     drawLineForBoxSide(graphicsContext, tx - ow, ty + h, tx + w + ow, ty + h + ow,
    1044                BSBottom, Color(oc), style->color(), os, ow, ow);
     1019    drawLineForBoxSide(graphicsContext, tx - ow, ty - ow, tx, ty + h + ow, BSLeft, oc, os, ow, ow);
     1020    drawLineForBoxSide(graphicsContext, tx - ow, ty - ow, tx + w + ow, ty, BSTop, oc, os, ow, ow);
     1021    drawLineForBoxSide(graphicsContext, tx + w, ty - ow, tx + w + ow, ty + h + ow, BSRight, oc, os, ow, ow);
     1022    drawLineForBoxSide(graphicsContext, tx - ow, ty + h, tx + w + ow, ty + h + ow, BSBottom, oc, os, ow, ow);
    10451023}
    10461024
     
    22102188}
    22112189
    2212 static Color decorationColor(RenderStyle* style)
     2190static Color decorationColor(RenderObject* renderer)
    22132191{
    22142192    Color result;
    2215     if (style->textStrokeWidth() > 0) {
     2193    if (renderer->style()->textStrokeWidth() > 0) {
    22162194        // Prefer stroke color if possible but not if it's fully transparent.
    2217         result = style->textStrokeColor();
    2218         if (!result.isValid())
    2219             result = style->color();
     2195        result = renderer->style()->visitedDependentColor(CSSPropertyWebkitTextStrokeColor);
    22202196        if (result.alpha())
    22212197            return result;
    22222198    }
    22232199   
    2224     result = style->textFillColor();
    2225     if (!result.isValid())
    2226         result = style->color();
     2200    result = renderer->style()->visitedDependentColor(CSSPropertyWebkitTextFillColor);
    22272201    return result;
    22282202}
     
    22372211            if (currDecs & UNDERLINE) {
    22382212                decorations &= ~UNDERLINE;
    2239                 underline = decorationColor(curr->style());
     2213                underline = decorationColor(curr);
    22402214            }
    22412215            if (currDecs & OVERLINE) {
    22422216                decorations &= ~OVERLINE;
    2243                 overline = decorationColor(curr->style());
     2217                overline = decorationColor(curr);
    22442218            }
    22452219            if (currDecs & LINE_THROUGH) {
    22462220                decorations &= ~LINE_THROUGH;
    2247                 linethrough = decorationColor(curr->style());
     2221                linethrough = decorationColor(curr);
    22482222            }
    22492223        }
     
    22572231    if (decorations && curr) {
    22582232        if (decorations & UNDERLINE)
    2259             underline = decorationColor(curr->style());
     2233            underline = decorationColor(curr);
    22602234        if (decorations & OVERLINE)
    2261             overline = decorationColor(curr->style());
     2235            overline = decorationColor(curr);
    22622236        if (decorations & LINE_THROUGH)
    2263             linethrough = decorationColor(curr->style());
     2237            linethrough = decorationColor(curr);
    22642238    }
    22652239}
  • trunk/WebCore/rendering/RenderObject.h

    r57287 r57292  
    409409
    410410    void drawLineForBoxSide(GraphicsContext*, int x1, int y1, int x2, int y2, BoxSide,
    411                             Color, const Color& textcolor, EBorderStyle, int adjbw1, int adjbw2);
     411                            Color, EBorderStyle, int adjbw1, int adjbw2);
    412412    void drawArcForBoxSide(GraphicsContext*, int x, int y, float thickness, IntSize radius, int angleStart,
    413                            int angleSpan, BoxSide, Color, const Color& textcolor, EBorderStyle, bool firstCorner);
     413                           int angleSpan, BoxSide, Color, EBorderStyle, bool firstCorner);
    414414
    415415public:
     
    782782    virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
    783783
    784     void paintOutline(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*);
     784    void paintOutline(GraphicsContext*, int tx, int ty, int w, int h);
    785785    void addPDFURLRect(GraphicsContext*, const IntRect&);
    786786
  • trunk/WebCore/rendering/RenderPath.cpp

    r56693 r57292  
    246246        if (drawsOutline)
    247247            paintOutline(childPaintInfo.context, static_cast<int>(boundingBox.x()), static_cast<int>(boundingBox.y()),
    248                 static_cast<int>(boundingBox.width()), static_cast<int>(boundingBox.height()), style());
     248                static_cast<int>(boundingBox.width()), static_cast<int>(boundingBox.height()));
    249249       
    250250        childPaintInfo.context->restore();
  • trunk/WebCore/rendering/RenderReplaced.cpp

    r50760 r57292  
    110110
    111111    if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth())
    112         paintOutline(paintInfo.context, tx, ty, width(), height(), style());
     112        paintOutline(paintInfo.context, tx, ty, width(), height());
    113113   
    114114    if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection)
  • trunk/WebCore/rendering/RenderSVGContainer.cpp

    r53300 r57292  
    121121    IntRect paintRectInParent = enclosingIntRect(localToParentTransform().mapRect(repaintRectInLocalCoordinates()));
    122122    if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth() && style()->visibility() == VISIBLE)
    123         paintOutline(paintInfo.context, paintRectInParent.x(), paintRectInParent.y(), paintRectInParent.width(), paintRectInParent.height(), style());
     123        paintOutline(paintInfo.context, paintRectInParent.x(), paintRectInParent.y(), paintRectInParent.width(), paintRectInParent.height());
    124124}
    125125
  • trunk/WebCore/rendering/RenderSVGImage.cpp

    r56693 r57292  
    9696
    9797    if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth())
    98         paintOutline(paintInfo.context, 0, 0, width(), height(), style());
     98        paintOutline(paintInfo.context, 0, 0, width(), height());
    9999
    100100    paintInfo.context->restore();
  • trunk/WebCore/rendering/RenderSVGRoot.cpp

    r54991 r57292  
    183183
    184184    if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth() && style()->visibility() == VISIBLE)
    185         paintOutline(paintInfo.context, borderBoxOriginInContainer.x(), borderBoxOriginInContainer.y(), width(), height(), style());
     185        paintOutline(paintInfo.context, borderBoxOriginInContainer.x(), borderBoxOriginInContainer.y(), width(), height());
    186186}
    187187
  • trunk/WebCore/rendering/RenderTableCell.cpp

    r57287 r57292  
    339339    // For border left, we need to check, in order of precedence:
    340340    // (1) Our left border.
    341     CollapsedBorderValue result(&style()->borderLeft(), BCELL);
     341    int left = CSSPropertyBorderLeftColor;
     342    int right = CSSPropertyBorderRightColor;
     343    CollapsedBorderValue result(&style()->borderLeft(), style()->visitedDependentColor(left), BCELL);
    342344   
    343345    // (2) The right border of the cell to the left.
    344346    RenderTableCell* prevCell = rtl ? tableElt->cellAfter(this) : tableElt->cellBefore(this);
    345347    if (prevCell) {
    346         result = rtl ? compareBorders(result, CollapsedBorderValue(&prevCell->style()->borderRight(), BCELL)) : compareBorders(CollapsedBorderValue(&prevCell->style()->borderRight(), BCELL), result);
     348        CollapsedBorderValue prevCellBorder = CollapsedBorderValue(&prevCell->style()->borderRight(), prevCell->style()->visitedDependentColor(right), BCELL);
     349        result = rtl ? compareBorders(result, prevCellBorder) : compareBorders(prevCellBorder, result);
    347350        if (!result.exists())
    348351            return result;
    349352    } else if (leftmostColumn) {
    350353        // (3) Our row's left border.
    351         result = compareBorders(result, CollapsedBorderValue(&parent()->style()->borderLeft(), BROW));
     354        result = compareBorders(result, CollapsedBorderValue(&parent()->style()->borderLeft(), parent()->style()->visitedDependentColor(left), BROW));
    352355        if (!result.exists())
    353356            return result;
    354357       
    355358        // (4) Our row group's left border.
    356         result = compareBorders(result, CollapsedBorderValue(&section()->style()->borderLeft(), BROWGROUP));
     359        result = compareBorders(result, CollapsedBorderValue(&section()->style()->borderLeft(), section()->style()->visitedDependentColor(left), BROWGROUP));
    357360        if (!result.exists())
    358361            return result;
     
    364367    RenderTableCol* colElt = tableElt->colElement(col() + (rtl ? colSpan() - 1 : 0), &startColEdge, &endColEdge);
    365368    if (colElt && (!rtl ? startColEdge : endColEdge)) {
    366         result = compareBorders(result, CollapsedBorderValue(&colElt->style()->borderLeft(), BCOL));
     369        result = compareBorders(result, CollapsedBorderValue(&colElt->style()->borderLeft(), colElt->style()->visitedDependentColor(left), BCOL));
    367370        if (!result.exists())
    368371            return result;
    369372        if (colElt->parent()->isTableCol() && (!rtl ? !colElt->previousSibling() : !colElt->nextSibling())) {
    370             result = compareBorders(result, CollapsedBorderValue(&colElt->parent()->style()->borderLeft(), BCOLGROUP));
     373            result = compareBorders(result, CollapsedBorderValue(&colElt->parent()->style()->borderLeft(), colElt->parent()->style()->visitedDependentColor(left), BCOLGROUP));
    371374            if (!result.exists())
    372375                return result;
     
    378381        colElt = tableElt->colElement(col() + (rtl ? colSpan() : -1), &startColEdge, &endColEdge);
    379382        if (colElt && (!rtl ? endColEdge : startColEdge)) {
    380             result = rtl ? compareBorders(result, CollapsedBorderValue(&colElt->style()->borderRight(), BCOL)) : compareBorders(CollapsedBorderValue(&colElt->style()->borderRight(), BCOL), result);
     383            CollapsedBorderValue rightBorder = CollapsedBorderValue(&colElt->style()->borderRight(), colElt->style()->visitedDependentColor(right), BCOL);
     384            result = rtl ? compareBorders(result, rightBorder) : compareBorders(rightBorder, result);
    381385            if (!result.exists())
    382386                return result;
     
    384388    } else {
    385389        // (7) The table's left border.
    386         result = compareBorders(result, CollapsedBorderValue(&tableElt->style()->borderLeft(), BTABLE));
     390        result = compareBorders(result, CollapsedBorderValue(&tableElt->style()->borderLeft(), tableElt->style()->visitedDependentColor(left), BTABLE));
    387391        if (!result.exists())
    388392            return result;
     
    405409    // For border right, we need to check, in order of precedence:
    406410    // (1) Our right border.
    407     CollapsedBorderValue result = CollapsedBorderValue(&style()->borderRight(), BCELL);
     411    int left = CSSPropertyBorderLeftColor;
     412    int right = CSSPropertyBorderRightColor;
     413    CollapsedBorderValue result = CollapsedBorderValue(&style()->borderRight(), style()->visitedDependentColor(right), BCELL);
    408414   
    409415    // (2) The left border of the cell to the right.
     
    411417        RenderTableCell* nextCell = rtl ? tableElt->cellBefore(this) : tableElt->cellAfter(this);
    412418        if (nextCell && nextCell->style()) {
    413             result = rtl ? compareBorders(CollapsedBorderValue(&nextCell->style()->borderLeft(), BCELL), result) : compareBorders(result, CollapsedBorderValue(&nextCell->style()->borderLeft(), BCELL));
     419            CollapsedBorderValue leftBorder = CollapsedBorderValue(&nextCell->style()->borderLeft(), nextCell->style()->visitedDependentColor(left), BCELL);
     420            result = rtl ? compareBorders(leftBorder, result) : compareBorders(result, leftBorder);
    414421            if (!result.exists())
    415422                return result;
     
    417424    } else {
    418425        // (3) Our row's right border.
    419         result = compareBorders(result, CollapsedBorderValue(&parent()->style()->borderRight(), BROW));
     426        result = compareBorders(result, CollapsedBorderValue(&parent()->style()->borderRight(), parent()->style()->visitedDependentColor(right), BROW));
    420427        if (!result.exists())
    421428            return result;
    422429       
    423430        // (4) Our row group's right border.
    424         result = compareBorders(result, CollapsedBorderValue(&section()->style()->borderRight(), BROWGROUP));
     431        result = compareBorders(result, CollapsedBorderValue(&section()->style()->borderRight(), section()->style()->visitedDependentColor(right), BROWGROUP));
    425432        if (!result.exists())
    426433            return result;
     
    432439    RenderTableCol* colElt = tableElt->colElement(col() + (rtl ? 0 : colSpan() - 1), &startColEdge, &endColEdge);
    433440    if (colElt && (!rtl ? endColEdge : startColEdge)) {
    434         result = compareBorders(result, CollapsedBorderValue(&colElt->style()->borderRight(), BCOL));
     441        result = compareBorders(result, CollapsedBorderValue(&colElt->style()->borderRight(), colElt->style()->visitedDependentColor(right), BCOL));
    435442        if (!result.exists())
    436443            return result;
    437444        if (colElt->parent()->isTableCol() && (!rtl ? !colElt->nextSibling() : !colElt->previousSibling())) {
    438             result = compareBorders(result, CollapsedBorderValue(&colElt->parent()->style()->borderRight(), BCOLGROUP));
     445            result = compareBorders(result, CollapsedBorderValue(&colElt->parent()->style()->borderRight(), colElt->parent()->style()->visitedDependentColor(right), BCOLGROUP));
    439446            if (!result.exists())
    440447                return result;
     
    446453        colElt = tableElt->colElement(col() + (rtl ? -1 : colSpan()), &startColEdge, &endColEdge);
    447454        if (colElt && (!rtl ? startColEdge : endColEdge)) {
    448             result = rtl ? compareBorders(CollapsedBorderValue(&colElt->style()->borderLeft(), BCOL), result) : compareBorders(result, CollapsedBorderValue(&colElt->style()->borderLeft(), BCOL));
     455            CollapsedBorderValue leftBorder = CollapsedBorderValue(&colElt->style()->borderLeft(), colElt->style()->visitedDependentColor(left), BCOL);
     456            result = rtl ? compareBorders(leftBorder, result) : compareBorders(result, leftBorder);
    449457            if (!result.exists())
    450458                return result;
     
    452460    } else {
    453461        // (7) The table's right border.
    454         result = compareBorders(result, CollapsedBorderValue(&tableElt->style()->borderRight(), BTABLE));
     462        result = compareBorders(result, CollapsedBorderValue(&tableElt->style()->borderRight(), tableElt->style()->visitedDependentColor(right), BTABLE));
    455463        if (!result.exists())
    456464            return result;
     
    464472    // For border top, we need to check, in order of precedence:
    465473    // (1) Our top border.
    466     CollapsedBorderValue result = CollapsedBorderValue(&style()->borderTop(), BCELL);
     474    int top = CSSPropertyBorderTopColor;
     475    int bottom = CSSPropertyBorderBottomColor;
     476    CollapsedBorderValue result = CollapsedBorderValue(&style()->borderTop(), style()->visitedDependentColor(top), BCELL);
    467477   
    468478    RenderTableCell* prevCell = table()->cellAbove(this);
    469479    if (prevCell) {
    470480        // (2) A previous cell's bottom border.
    471         result = compareBorders(CollapsedBorderValue(&prevCell->style()->borderBottom(), BCELL), result);
     481        result = compareBorders(CollapsedBorderValue(&prevCell->style()->borderBottom(), prevCell->style()->visitedDependentColor(bottom), BCELL), result);
    472482        if (!result.exists())
    473483            return result;
     
    475485   
    476486    // (3) Our row's top border.
    477     result = compareBorders(result, CollapsedBorderValue(&parent()->style()->borderTop(), BROW));
     487    result = compareBorders(result, CollapsedBorderValue(&parent()->style()->borderTop(), parent()->style()->visitedDependentColor(top), BROW));
    478488    if (!result.exists())
    479489        return result;
     
    488498   
    489499        if (prevRow) {
    490             result = compareBorders(CollapsedBorderValue(&prevRow->style()->borderBottom(), BROW), result);
     500            result = compareBorders(CollapsedBorderValue(&prevRow->style()->borderBottom(), prevRow->style()->visitedDependentColor(bottom), BROW), result);
    491501            if (!result.exists())
    492502                return result;
     
    498508    if (!row()) {
    499509        // (5) Our row group's top border.
    500         result = compareBorders(result, CollapsedBorderValue(&currSection->style()->borderTop(), BROWGROUP));
     510        result = compareBorders(result, CollapsedBorderValue(&currSection->style()->borderTop(), currSection->style()->visitedDependentColor(top), BROWGROUP));
    501511        if (!result.exists())
    502512            return result;
     
    505515        currSection = table()->sectionAbove(currSection);
    506516        if (currSection) {
    507             result = compareBorders(CollapsedBorderValue(&currSection->style()->borderBottom(), BROWGROUP), result);
     517            result = compareBorders(CollapsedBorderValue(&currSection->style()->borderBottom(), currSection->style()->visitedDependentColor(bottom), BROWGROUP), result);
    508518            if (!result.exists())
    509519                return result;
     
    515525        RenderTableCol* colElt = table()->colElement(col());
    516526        if (colElt) {
    517             result = compareBorders(result, CollapsedBorderValue(&colElt->style()->borderTop(), BCOL));
     527            result = compareBorders(result, CollapsedBorderValue(&colElt->style()->borderTop(), colElt->style()->visitedDependentColor(top), BCOL));
    518528            if (!result.exists())
    519529                return result;
    520530            if (colElt->parent()->isTableCol()) {
    521                 result = compareBorders(result, CollapsedBorderValue(&colElt->parent()->style()->borderTop(), BCOLGROUP));
     531                result = compareBorders(result, CollapsedBorderValue(&colElt->parent()->style()->borderTop(), colElt->parent()->style()->visitedDependentColor(top), BCOLGROUP));
    522532                if (!result.exists())
    523533                    return result;
     
    526536       
    527537        // (9) The table's top border.
    528         result = compareBorders(result, CollapsedBorderValue(&table()->style()->borderTop(), BTABLE));
     538        RenderTable* enclosingTable = table();
     539        result = compareBorders(result, CollapsedBorderValue(&enclosingTable->style()->borderTop(), enclosingTable->style()->visitedDependentColor(top), BTABLE));
    529540        if (!result.exists())
    530541            return result;
     
    538549    // For border top, we need to check, in order of precedence:
    539550    // (1) Our bottom border.
    540     CollapsedBorderValue result = CollapsedBorderValue(&style()->borderBottom(), BCELL);
     551    int top = CSSPropertyBorderTopColor;
     552    int bottom = CSSPropertyBorderBottomColor;
     553    CollapsedBorderValue result = CollapsedBorderValue(&style()->borderBottom(), style()->visitedDependentColor(bottom), BCELL);
    541554   
    542555    RenderTableCell* nextCell = table()->cellBelow(this);
    543556    if (nextCell) {
    544557        // (2) A following cell's top border.
    545         result = compareBorders(result, CollapsedBorderValue(&nextCell->style()->borderTop(), BCELL));
     558        result = compareBorders(result, CollapsedBorderValue(&nextCell->style()->borderTop(), nextCell->style()->visitedDependentColor(top), BCELL));
    546559        if (!result.exists())
    547560            return result;
     
    549562   
    550563    // (3) Our row's bottom border. (FIXME: Deal with rowspan!)
    551     result = compareBorders(result, CollapsedBorderValue(&parent()->style()->borderBottom(), BROW));
     564    result = compareBorders(result, CollapsedBorderValue(&parent()->style()->borderBottom(), parent()->style()->visitedDependentColor(bottom), BROW));
    552565    if (!result.exists())
    553566        return result;
     
    555568    // (4) The next row's top border.
    556569    if (nextCell) {
    557         result = compareBorders(result, CollapsedBorderValue(&nextCell->parent()->style()->borderTop(), BROW));
     570        result = compareBorders(result, CollapsedBorderValue(&nextCell->parent()->style()->borderTop(), nextCell->parent()->style()->visitedDependentColor(top), BROW));
    558571        if (!result.exists())
    559572            return result;
     
    564577    if (row() + rowSpan() >= currSection->numRows()) {
    565578        // (5) Our row group's bottom border.
    566         result = compareBorders(result, CollapsedBorderValue(&currSection->style()->borderBottom(), BROWGROUP));
     579        result = compareBorders(result, CollapsedBorderValue(&currSection->style()->borderBottom(), currSection->style()->visitedDependentColor(bottom), BROWGROUP));
    567580        if (!result.exists())
    568581            return result;
     
    571584        currSection = table()->sectionBelow(currSection);
    572585        if (currSection) {
    573             result = compareBorders(result, CollapsedBorderValue(&currSection->style()->borderTop(), BROWGROUP));
     586            result = compareBorders(result, CollapsedBorderValue(&currSection->style()->borderTop(), currSection->style()->visitedDependentColor(top), BROWGROUP));
    574587            if (!result.exists())
    575588                return result;
     
    581594        RenderTableCol* colElt = table()->colElement(col());
    582595        if (colElt) {
    583             result = compareBorders(result, CollapsedBorderValue(&colElt->style()->borderBottom(), BCOL));
     596            result = compareBorders(result, CollapsedBorderValue(&colElt->style()->borderBottom(), colElt->style()->visitedDependentColor(bottom), BCOL));
    584597            if (!result.exists()) return result;
    585598            if (colElt->parent()->isTableCol()) {
    586                 result = compareBorders(result, CollapsedBorderValue(&colElt->parent()->style()->borderBottom(), BCOLGROUP));
     599                result = compareBorders(result, CollapsedBorderValue(&colElt->parent()->style()->borderBottom(), colElt->parent()->style()->visitedDependentColor(bottom), BCOLGROUP));
    587600                if (!result.exists())
    588601                    return result;
     
    591604       
    592605        // (9) The table's bottom border.
    593         result = compareBorders(result, CollapsedBorderValue(&table()->style()->borderBottom(), BTABLE));
     606        RenderTable* enclosingTable = table();
     607        result = compareBorders(result, CollapsedBorderValue(&enclosingTable->style()->borderBottom(), enclosingTable->style()->visitedDependentColor(bottom), BTABLE));
    594608        if (!result.exists())
    595609            return result;
     
    809823        if (border->borderValue == *table()->currentBorderStyle())
    810824            drawLineForBoxSide(graphicsContext, border->x1, border->y1, border->x2, border->y2, border->side,
    811                                border->borderValue.color(), style()->color(), border->style, 0, 0);
     825                               border->borderValue.color(), border->style, 0, 0);
    812826    }
    813827}
  • trunk/WebCore/rendering/style/CollapsedBorderValue.h

    r36579 r57292  
    3737    }
    3838
    39     CollapsedBorderValue(const BorderValue* b, EBorderPrecedence p)
     39    CollapsedBorderValue(const BorderValue* b, Color c, EBorderPrecedence p)
    4040        : border(b)
     41        , borderColor(c)
    4142        , precedence(p)
    4243    {
     
    4647    EBorderStyle style() const { return border ? border->style() : BHIDDEN; }
    4748    bool exists() const { return border; }
    48     Color color() const { return border ? border->color : Color(); }
     49    Color color() const { return borderColor; }
    4950    bool isTransparent() const { return border ? border->isTransparent() : true; }
    5051   
     
    5556        if (!o.border)
    5657            return false;
    57         return *border == *o.border && precedence == o.precedence;
     58        return *border == *o.border && borderColor == o.borderColor && precedence == o.precedence;
    5859    }
    5960   
    6061    const BorderValue* border;
     62    Color borderColor;
    6163    EBorderPrecedence precedence;   
    6264};
  • trunk/WebCore/rendering/style/RenderStyle.cpp

    r54926 r57292  
    2323#include "RenderStyle.h"
    2424
     25#include "CSSPropertyNames.h"
    2526#include "CSSStyleSelector.h"
    2627#include "CachedImage.h"
     
    5960
    6061RenderStyle::RenderStyle()
    61     : m_pseudoState(PseudoUnknown)
    62     , m_affectedByAttributeSelectors(false)
     62    : m_affectedByAttributeSelectors(false)
    6363    , m_unique(false)
    6464    , m_affectedByEmpty(false)
     
    8787
    8888RenderStyle::RenderStyle(bool)
    89     : m_pseudoState(PseudoUnknown)
    90     , m_affectedByAttributeSelectors(false)
     89    : m_affectedByAttributeSelectors(false)
    9190    , m_unique(false)
    9291    , m_affectedByEmpty(false)
     
    122121RenderStyle::RenderStyle(const RenderStyle& o)
    123122    : RefCounted<RenderStyle>()
    124     , m_pseudoState(o.m_pseudoState)
    125123    , m_affectedByAttributeSelectors(false)
    126124    , m_unique(false)
     
    503501        inherited_flags._text_decorations != other->inherited_flags._text_decorations ||
    504502        inherited_flags._force_backgrounds_to_white != other->inherited_flags._force_backgrounds_to_white ||
     503        inherited_flags._insideLink != other->inherited_flags._insideLink ||
    505504        surround->border != other->surround->border ||
    506505        *background.get() != *other->background.get() ||
     
    968967}
    969968
     969static EBorderStyle borderStyleForColorProperty(const RenderStyle* style, int colorProperty)
     970{
     971    EBorderStyle borderStyle;
     972    switch (colorProperty) {
     973    case CSSPropertyBorderLeftColor:
     974        borderStyle = style->borderLeftStyle();
     975        break;
     976    case CSSPropertyBorderRightColor:
     977        borderStyle = style->borderRightStyle();
     978        break;
     979    case CSSPropertyBorderTopColor:
     980        borderStyle = style->borderTopStyle();
     981        break;
     982    case CSSPropertyBorderBottomColor:
     983        borderStyle = style->borderBottomStyle();
     984        break;
     985    default:
     986        borderStyle = BNONE;
     987        break;
     988    }
     989    return borderStyle;
     990}
     991
     992static Color colorIncludingFallback(const RenderStyle* style, int colorProperty, EBorderStyle borderStyle)
     993{
     994    Color result;
     995    switch (colorProperty) {
     996    case CSSPropertyBackgroundColor:
     997        return style->backgroundColor(); // Background color doesn't fall back.
     998    case CSSPropertyBorderLeftColor:
     999        result = style->borderLeftColor();
     1000        borderStyle = style->borderLeftStyle();
     1001        break;
     1002    case CSSPropertyBorderRightColor:
     1003        result = style->borderRightColor();
     1004        borderStyle = style->borderRightStyle();
     1005        break;
     1006    case CSSPropertyBorderTopColor:
     1007        result = style->borderTopColor();
     1008        borderStyle = style->borderTopStyle();
     1009        break;
     1010    case CSSPropertyBorderBottomColor:
     1011        result = style->borderBottomColor();
     1012        borderStyle = style->borderBottomStyle();
     1013        break;
     1014    case CSSPropertyColor:
     1015        result = style->color();
     1016        break;
     1017    case CSSPropertyOutlineColor:
     1018        result = style->outlineColor();
     1019        break;
     1020    case CSSPropertyWebkitColumnRuleColor:
     1021        result = style->columnRuleColor();
     1022        break;
     1023    case CSSPropertyWebkitTextFillColor:
     1024        result = style->textFillColor();
     1025        break;
     1026    case CSSPropertyWebkitTextStrokeColor:
     1027        result = style->textStrokeColor();
     1028        break;
     1029    default:
     1030        // FIXME: Add SVG fill and stroke.
     1031        ASSERT_NOT_REACHED();
     1032        break;
     1033    }
     1034
     1035    if (!result.isValid()) {
     1036        if ((colorProperty == CSSPropertyBorderLeftColor || colorProperty == CSSPropertyBorderRightColor
     1037            || colorProperty == CSSPropertyBorderTopColor || colorProperty == CSSPropertyBorderBottomColor)
     1038            && (borderStyle == INSET || borderStyle == OUTSET || borderStyle == RIDGE || borderStyle == GROOVE))
     1039            result.setRGB(238, 238, 238);
     1040        else
     1041            result = style->color();
     1042    }
     1043
     1044    return result;
     1045}
     1046
     1047Color RenderStyle::visitedDependentColor(int colorProperty) const
     1048{
     1049    EBorderStyle borderStyle = borderStyleForColorProperty(this, colorProperty);
     1050    Color unvisitedColor = colorIncludingFallback(this, colorProperty, borderStyle);
     1051    if (insideLink() != InsideVisitedLink)
     1052        return unvisitedColor;
     1053
     1054    RenderStyle* visitedStyle = getCachedPseudoStyle(VISITED_LINK);
     1055    if (!visitedStyle)
     1056        return unvisitedColor;
     1057    Color visitedColor = colorIncludingFallback(visitedStyle, colorProperty, borderStyle);
     1058
     1059    // Take the alpha from the unvisited color, but get the RGB values from the visited color.
     1060    return Color(visitedColor.red(), visitedColor.green(), visitedColor.blue(), unvisitedColor.alpha());
     1061}
     1062
    9701063} // namespace WebCore
  • trunk/WebCore/rendering/style/RenderStyle.h

    r54926 r57292  
    117117    // The following bitfield is 32-bits long, which optimizes padding with the
    118118    // int refCount in the base class. Beware when adding more bits.
    119     unsigned m_pseudoState : 3; // PseudoState
    120119    bool m_affectedByAttributeSelectors : 1;
    121120    bool m_unique : 1;
     
    134133    bool m_firstChildState : 1;
    135134    bool m_lastChildState : 1;
    136     unsigned m_childIndex : 18; // Plenty of bits to cache an index.
     135    unsigned m_childIndex : 21; // Plenty of bits to cache an index.
    137136
    138137    // non-inherited attributes
     
    177176                   (_htmlHacks == other._htmlHacks) &&
    178177                   (_force_backgrounds_to_white == other._force_backgrounds_to_white) &&
    179                    (_pointerEvents == other._pointerEvents);
     178                   (_pointerEvents == other._pointerEvents) &&
     179                   (_insideLink == other._insideLink);
    180180        }
    181181
     
    202202        bool _force_backgrounds_to_white : 1;
    203203        unsigned _pointerEvents : 4; // EPointerEvents
    204         // 41 bits
     204        EInsideLink _insideLink : 2; // Whether or not we are contained inside a link.
     205        // 43 bits
    205206    } inherited_flags;
    206207
     
    226227                && _affectedByDrag == other._affectedByDrag
    227228                && _pseudoBits == other._pseudoBits
    228                 && _unicodeBidi == other._unicodeBidi;
     229                && _unicodeBidi == other._unicodeBidi
     230                && _isLink == other._isLink;
    229231        }
    230232
     
    245247        unsigned _page_break_inside : 2; // EPageBreak
    246248
    247         unsigned _styleType : 5; // PseudoId
     249        unsigned _styleType : 6; // PseudoId
    248250        bool _affectedByHover : 1;
    249251        bool _affectedByActive : 1;
     
    251253        unsigned _pseudoBits : 7;
    252254        unsigned _unicodeBidi : 2; // EUnicodeBidi
     255        bool _isLink : 1;
    253256        // 50 bits
    254257    } noninherited_flags;
     
    276279        inherited_flags._force_backgrounds_to_white = false;
    277280        inherited_flags._pointerEvents = initialPointerEvents();
     281        inherited_flags._insideLink = NotInsideLink;
    278282
    279283        noninherited_flags._effectiveDisplay = noninherited_flags._originalDisplay = initialDisplay();
     
    294298        noninherited_flags._pseudoBits = 0;
    295299        noninherited_flags._unicodeBidi = initialUnicodeBidi();
     300        noninherited_flags._isLink = false;
    296301    }
    297302
     
    587592
    588593    CursorList* cursors() const { return inherited->cursorData.get(); }
     594
     595    EInsideLink insideLink() const { return static_cast<EInsideLink>(inherited_flags._insideLink); }
     596    bool isLink() const { return noninherited_flags._isLink; }
    589597
    590598    short widows() const { return inherited->widows; }
     
    912920    void setCursorList(PassRefPtr<CursorList>);
    913921    void clearCursorList();
     922
     923    void setInsideLink(EInsideLink insideLink) { inherited_flags._insideLink = insideLink; }
     924    void setIsLink(bool b) { noninherited_flags._isLink = b; }
    914925
    915926    bool forceBackgroundsToWhite() const { return inherited_flags._force_backgrounds_to_white; }
     
    10701081    }
    10711082
    1072     // To obtain at any time the pseudo state for a given link.
    1073     PseudoState pseudoState() const { return static_cast<PseudoState>(m_pseudoState); }
    1074     void setPseudoState(PseudoState s) { m_pseudoState = s; }
    1075 
    10761083    // To tell if this style matched attribute selectors. This makes it impossible to share.
    10771084    bool affectedByAttributeSelectors() const { return m_affectedByAttributeSelectors; }
     
    11021109    unsigned childIndex() const { return m_childIndex; }
    11031110    void setChildIndex(unsigned index) { m_childIndex = index; }
     1111
     1112    Color visitedDependentColor(int colorProperty) const;
    11041113
    11051114    // Initial values for all the properties
  • trunk/WebCore/rendering/style/RenderStyleConstants.h

    r56608 r57292  
    7575    MEDIA_CONTROLS_RETURN_TO_REALTIME_BUTTON, MEDIA_CONTROLS_TOGGLE_CLOSED_CAPTIONS_BUTTON,
    7676    MEDIA_CONTROLS_STATUS_DISPLAY, SCROLLBAR_THUMB, SCROLLBAR_BUTTON, SCROLLBAR_TRACK, SCROLLBAR_TRACK_PIECE, SCROLLBAR_CORNER, RESIZER,
    77     INPUT_LIST_BUTTON, INNER_SPIN_BUTTON, OUTER_SPIN_BUTTON,
     77    INPUT_LIST_BUTTON, INNER_SPIN_BUTTON, OUTER_SPIN_BUTTON, VISITED_LINK,
    7878
    7979    AFTER_LAST_INTERNAL_PSEUDOID,
     
    8989enum EBorderPrecedence { BOFF, BTABLE, BCOLGROUP, BCOL, BROWGROUP, BROW, BCELL };
    9090
    91 enum PseudoState { PseudoUnknown, PseudoNone, PseudoAnyLink, PseudoLink, PseudoVisited};
    92 
    9391enum EPosition {
    9492    StaticPosition, RelativePosition, AbsolutePosition, FixedPosition
     
    9896    FNONE = 0, FLEFT, FRIGHT
    9997};
    100 
    10198
    10299enum EMarginCollapse { MCOLLAPSE, MSEPARATE, MDISCARD };
     
    390387};
    391388
     389enum EInsideLink {
     390    NotInsideLink, InsideUnvisitedLink, InsideVisitedLink
     391};
     392   
    392393enum EPointerEvents {
    393394    PE_NONE, PE_AUTO, PE_STROKE, PE_FILL, PE_PAINTED, PE_VISIBLE,
  • trunk/WebCore/svg/graphics/SVGPaintServer.cpp

    r55930 r57292  
    8080
    8181    SVGPaint* fill = style->svgStyle()->fillPaint();
    82 
     82       
    8383    SVGPaintServer* fillPaintServer = 0;
    8484    SVGPaint::SVGPaintType paintType = fill->paintType();
     
    9999        fillPaintServer = sharedSolidPaintServer();
    100100        SVGPaintServerSolid* fillPaintServerSolid = static_cast<SVGPaintServerSolid*>(fillPaintServer);
     101       
     102        Color fillColor;
    101103        if (paintType == SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR)
    102             fillPaintServerSolid->setColor(style->color());
     104            fillColor = style->color();
    103105        else
    104             fillPaintServerSolid->setColor(fill->color());
     106            fillColor = fill->color();
     107
     108        if (style->insideLink() == InsideVisitedLink) {
     109            RenderStyle* visitedStyle = style->getCachedPseudoStyle(VISITED_LINK);
     110            SVGPaint* visitedFill = visitedStyle->svgStyle()->fillPaint();
     111            Color visitedFillColor;
     112            if (visitedFill->paintType() != SVGPaint::SVG_PAINTTYPE_URI) {
     113                if (visitedFill->paintType() == SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR)
     114                    visitedFillColor = visitedStyle->color();
     115                else
     116                    visitedFillColor = visitedFill->color();
     117                if (visitedFillColor.isValid())
     118                    fillColor = Color(visitedFillColor.red(), visitedFillColor.green(), visitedFillColor.blue(), fillColor.alpha());
     119            }
     120        }
     121
     122        fillPaintServerSolid->setColor(fillColor);
     123       
    105124        // FIXME: Ideally invalid colors would never get set on the RenderStyle and this could turn into an ASSERT
    106125        if (!fillPaintServerSolid->color().isValid())
     
    142161        strokePaintServer = sharedSolidPaintServer();
    143162        SVGPaintServerSolid* strokePaintServerSolid = static_cast<SVGPaintServerSolid*>(strokePaintServer);
     163       
     164        Color strokeColor;
    144165        if (paintType == SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR)
    145             strokePaintServerSolid->setColor(style->color());
     166            strokeColor = style->color();
    146167        else
    147             strokePaintServerSolid->setColor(stroke->color());
     168            strokeColor = stroke->color();
     169
     170        if (style->insideLink() == InsideVisitedLink) {
     171            RenderStyle* visitedStyle = style->getCachedPseudoStyle(VISITED_LINK);
     172            SVGPaint* visitedStroke = visitedStyle->svgStyle()->strokePaint();
     173            Color visitedStrokeColor;
     174            if (visitedStroke->paintType() != SVGPaint::SVG_PAINTTYPE_URI) {
     175                if (visitedStroke->paintType() == SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR)
     176                    visitedStrokeColor = visitedStyle->color();
     177                else
     178                    visitedStrokeColor = visitedStroke->color();
     179                if (visitedStrokeColor.isValid())
     180                    strokeColor = Color(visitedStrokeColor.red(), visitedStrokeColor.green(), visitedStrokeColor.blue(), strokeColor.alpha());
     181            }
     182        }
     183
     184        strokePaintServerSolid->setColor(strokeColor);
     185
    148186        // FIXME: Ideally invalid colors would never get set on the RenderStyle and this could turn into an ASSERT
    149187        if (!strokePaintServerSolid->color().isValid())
  • trunk/WebKit/mac/ChangeLog

    r57246 r57292  
     12010-04-07  David Hyatt  <hyatt@apple.com>
     2
     3        Reviewed by Oliver Hunt.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=24300, don't expose history info via CSS
     6
     7        Add SPI so that layout tests can access computed style including :visited information.
     8
     9        * WebView/WebRenderNode.mm:
     10        (copyRenderNode):
     11        * WebView/WebView.mm:
     12        (-[WebView _computedStyleIncludingVisitedInfo:forElement:]):
     13        * WebView/WebViewInternal.h:
     14        * WebView/WebViewPrivate.h:
     15
    1162010-04-07  Dan Bernstein  <mitz@apple.com>
    217
  • trunk/WebKit/mac/WebView/WebRenderNode.mm

    r46908 r57292  
    119119        width = box.width();
    120120        height = box.height();
     121    } else if (node->isRenderInline()) {
     122        RenderBoxModelObject* inlineFlow = toRenderBoxModelObject(node);
     123        IntRect boundingBox = inlineFlow->borderBoundingBox();
     124        x = boundingBox.x();
     125        y = boundingBox.y();
     126        width = boundingBox.width();
     127        height = boundingBox.height();
    121128    }
    122    
     129
    123130    WebRenderNode *result = [[WebRenderNode alloc] _initWithName:name
    124131                                                        position:absPos rect:NSMakeRect(x, y, width, height)
  • trunk/WebKit/mac/WebView/WebView.mm

    r56718 r57292  
    102102#import <CoreFoundation/CFSet.h>
    103103#import <Foundation/NSURLConnection.h>
     104#import <JavaScriptCore/APICast.h>
     105#import <JavaScriptCore/JSValueRef.h>
    104106#import <WebCore/ApplicationCacheStorage.h>
    105107#import <WebCore/BackForwardList.h>
    106108#import <WebCore/Cache.h>
    107109#import <WebCore/ColorMac.h>
     110#import <WebCore/CSSComputedStyleDeclaration.h>
    108111#import <WebCore/Cursor.h>
    109112#import <WebCore/Database.h>
     
    125128#import <WebCore/HistoryItem.h>
    126129#import <WebCore/IconDatabase.h>
     130#import <WebCore/JSCSSStyleDeclaration.h>
     131#import <WebCore/JSElement.h>
    127132#import <WebCore/Logging.h>
    128133#import <WebCore/MIMETypeRegistry.h>
     
    57005705@end
    57015706
     5707@implementation WebView (WebViewPrivateStyleInfo)
     5708
     5709- (JSValueRef)_computedStyleIncludingVisitedInfo:(JSContextRef)context forElement:(JSValueRef)value
     5710{
     5711    JSLock lock(SilenceAssertionsOnly);
     5712    ExecState* exec = toJS(context);
     5713    if (!value)
     5714        return JSValueMakeUndefined(context);
     5715    JSValue jsValue = toJS(exec, value);
     5716    if (!jsValue.inherits(&JSElement::s_info))
     5717        return JSValueMakeUndefined(context);
     5718    JSElement* jsElement = static_cast<JSElement*>(asObject(jsValue));
     5719    Element* element = jsElement->impl();
     5720    RefPtr<CSSComputedStyleDeclaration> style = computedStyle(element, true);
     5721    return toRef(exec, toJS(exec, jsElement->globalObject(), style.get()));
     5722}
     5723
     5724@end
     5725
    57025726#ifdef BUILDING_ON_LEOPARD
    57035727
  • trunk/WebKit/mac/WebView/WebViewInternal.h

    r54908 r57292  
    175175#endif
    176176
     177- (JSValueRef)_computedStyleIncludingVisitedInfo:(JSContextRef)context forElement:(JSValueRef)value;
     178
    177179@end
  • trunk/WebKit/mac/WebView/WebViewPrivate.h

    r55408 r57292  
    600600@end
    601601
     602@interface WebView (WebViewPrivateStyleInfo)
     603- (JSValueRef)_computedStyleIncludingVisitedInfo:(JSContextRef)context forElement:(JSValueRef)value;
     604@end
     605
    602606@interface NSObject (WebFrameLoadDelegatePrivate)
    603607- (void)webView:(WebView *)sender didFirstLayoutInFrame:(WebFrame *)frame;
  • trunk/WebKitTools/ChangeLog

    r57290 r57292  
     12010-04-07  David Hyatt  <hyatt@apple.com>
     2
     3        Reviewed by Oliver Hunt.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=24300, don't expose history info via CSS.  Add a new method for
     6        obtaining computed style with :visited info included.  This allows layout tests to actually tell that
     7        :visited is in effect.
     8
     9        * DumpRenderTree/LayoutTestController.cpp:
     10        (computedStyleIncludingVisitedInfoCallback):
     11        (LayoutTestController::staticFunctions):
     12        * DumpRenderTree/LayoutTestController.h:
     13        * DumpRenderTree/mac/LayoutTestControllerMac.mm:
     14        (LayoutTestController::computedStyleIncludingVisitedInfo):
     15
    1162010-04-07  Dirk Pranke  <dpranke@chromium.org>
    217
  • trunk/WebKitTools/DumpRenderTree/LayoutTestController.cpp

    r57278 r57292  
    466466}
    467467
     468static JSValueRef computedStyleIncludingVisitedInfoCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
     469{
     470    if (argumentCount != 1)
     471        return JSValueMakeUndefined(context);
     472   
     473    // Has mac implementation
     474    LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
     475    return controller->computedStyleIncludingVisitedInfo(context, arguments[0]);
     476}
     477
    468478static JSValueRef layerTreeAsTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    469479{
     
    14441454        { "clearPersistentUserStyleSheet", clearPersistentUserStyleSheetCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    14451455        { "closeWebInspector", closeWebInspectorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
     1456        { "computedStyleIncludingVisitedInfo", computedStyleIncludingVisitedInfoCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    14461457        { "decodeHostName", decodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    14471458        { "disableImageLoading", disableImageLoadingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
  • trunk/WebKitTools/DumpRenderTree/LayoutTestController.h

    r57278 r57292  
    5858    bool isCommandEnabled(JSStringRef name);
    5959    void keepWebHistory();
     60    JSValueRef computedStyleIncludingVisitedInfo(JSContextRef, JSValueRef);
    6061    void notifyDone();
    6162    int numberOfPages(float pageWidthInPixels, float pageHeightInPixels);
  • trunk/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp

    r57278 r57292  
    144144}
    145145
     146JSValueRef LayoutTestController::computedStyleIncludingVisitedInfo(JSContextRef context, JSValueRef value)
     147{
     148    // FIXME: Implement this.
     149    return 0;
     150}
     151
    146152JSRetainPtr<JSStringRef> LayoutTestController::layerTreeAsText() const
    147153{
  • trunk/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm

    r57278 r57292  
    182182}
    183183
     184JSValueRef LayoutTestController::computedStyleIncludingVisitedInfo(JSContextRef context, JSValueRef value)
     185{   
     186    return [[mainFrame webView] _computedStyleIncludingVisitedInfo:context forElement:value];
     187}
     188
    184189JSRetainPtr<JSStringRef> LayoutTestController::layerTreeAsText() const
    185190{
  • trunk/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp

    r57277 r57292  
    168168}
    169169
     170JSValueRef LayoutTestController::computedStyleIncludingVisitedInfo(JSContextRef context, JSValueRef value)
     171{
     172    // FIXME: Implement this.
     173    return 0;
     174}
     175
    170176void LayoutTestController::notifyDone()
    171177{
  • trunk/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp

    r57278 r57292  
    174174}
    175175
     176JSValueRef LayoutTestController::computedStyleIncludingVisitedInfo(JSContextRef context, JSValueRef value)
     177{
     178    // FIXME: Implement this.
     179    return 0;
     180}
     181
    176182JSRetainPtr<JSStringRef> LayoutTestController::layerTreeAsText() const
    177183{
Note: See TracChangeset for help on using the changeset viewer.