Title: [138515] trunk/Source/WebCore
Revision
138515
Author
dglaz...@chromium.org
Date
2012-12-27 14:57:00 -0800 (Thu, 27 Dec 2012)

Log Message

Move visited link-checking (and caching) code out of SelectorChecker.
https://bugs.webkit.org/show_bug.cgi?id=105752

SelectorChecker knew too much about visited links and how links are stored in DOM. This change
moves the code to more relevant locations and moves the visited links cache all the way up to Document,
introducing VisitedLinkState class to manage the state of visited links.
Relanding without a null-ptr ref.

Reviewed by Antti Koivisto.

No change in behavior, covered by existing tests.

* CMakeLists.txt: Added VisitedLinkState to build system.
* GNUmakefile.list.am: Ditto.
* Target.pri: Ditto.
* WebCore.gypi: Ditto.
* WebCore.xcodeproj/project.pbxproj: Ditto.
* css/SelectorChecker.cpp: Moved visited-link state code out to VisitedLinkState class.
* css/SelectorChecker.h: Ditto.
* css/StyleResolver.cpp:
(WebCore::StyleResolver::initElement): Changed callsite to use VisitedLinkState.
* css/StyleResolver.h: Removed plumb-throughs that are now unnecessary.
* dom/DOMAllInOne.cpp: Added VisitedLinkState to build system.
* dom/Document.cpp: Added VisitedLinkState initalizer.
* dom/Document.h: Added VisitedLinkState member.
* dom/VisitedLinkState.cpp: Added.
* dom/VisitedLinkState.h: Added.
* history/CachedPage.cpp:
(WebCore::CachedPage::restore): Changed callsite to use VisitedLinkState.
* page/Page.cpp:
(WebCore::Page::allVisitedStateChanged): Ditto.
(WebCore::Page::visitedStateChanged): Ditto.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/CMakeLists.txt (138514 => 138515)


--- trunk/Source/WebCore/CMakeLists.txt	2012-12-27 22:06:41 UTC (rev 138514)
+++ trunk/Source/WebCore/CMakeLists.txt	2012-12-27 22:57:00 UTC (rev 138515)
@@ -1246,6 +1246,7 @@
     dom/UserGestureIndicator.cpp
     dom/UserTypingGestureIndicator.cpp
     dom/ViewportArguments.cpp
+    dom/VisitedLinkState.cpp
     dom/WebCoreMemoryInstrumentation.cpp
     dom/WebKitAnimationEvent.cpp
     dom/WebKitNamedFlow.cpp

Modified: trunk/Source/WebCore/ChangeLog (138514 => 138515)


--- trunk/Source/WebCore/ChangeLog	2012-12-27 22:06:41 UTC (rev 138514)
+++ trunk/Source/WebCore/ChangeLog	2012-12-27 22:57:00 UTC (rev 138515)
@@ -1,3 +1,38 @@
+2012-12-27  Dimitri Glazkov  <dglaz...@chromium.org>
+
+        Move visited link-checking (and caching) code out of SelectorChecker.
+        https://bugs.webkit.org/show_bug.cgi?id=105752
+
+        SelectorChecker knew too much about visited links and how links are stored in DOM. This change
+        moves the code to more relevant locations and moves the visited links cache all the way up to Document,
+        introducing VisitedLinkState class to manage the state of visited links.
+        Relanding without a null-ptr ref.
+
+        Reviewed by Antti Koivisto.
+
+        No change in behavior, covered by existing tests.
+
+        * CMakeLists.txt: Added VisitedLinkState to build system.
+        * GNUmakefile.list.am: Ditto.
+        * Target.pri: Ditto.
+        * WebCore.gypi: Ditto.
+        * WebCore.xcodeproj/project.pbxproj: Ditto.
+        * css/SelectorChecker.cpp: Moved visited-link state code out to VisitedLinkState class.
+        * css/SelectorChecker.h: Ditto.
+        * css/StyleResolver.cpp:
+        (WebCore::StyleResolver::initElement): Changed callsite to use VisitedLinkState.
+        * css/StyleResolver.h: Removed plumb-throughs that are now unnecessary.
+        * dom/DOMAllInOne.cpp: Added VisitedLinkState to build system.
+        * dom/Document.cpp: Added VisitedLinkState initalizer.
+        * dom/Document.h: Added VisitedLinkState member.
+        * dom/VisitedLinkState.cpp: Added.
+        * dom/VisitedLinkState.h: Added.
+        * history/CachedPage.cpp:
+        (WebCore::CachedPage::restore): Changed callsite to use VisitedLinkState.
+        * page/Page.cpp:
+        (WebCore::Page::allVisitedStateChanged): Ditto.
+        (WebCore::Page::visitedStateChanged): Ditto.
+
 2012-12-27  Kondapally Kalyan  <kalyan.kondapa...@intel.com>
 
         [EFL][WebGL] Implement EGL support with GLX.

Modified: trunk/Source/WebCore/GNUmakefile.list.am (138514 => 138515)


--- trunk/Source/WebCore/GNUmakefile.list.am	2012-12-27 22:06:41 UTC (rev 138514)
+++ trunk/Source/WebCore/GNUmakefile.list.am	2012-12-27 22:57:00 UTC (rev 138515)
@@ -2989,6 +2989,8 @@
 	Source/WebCore/dom/UserTypingGestureIndicator.h \
 	Source/WebCore/dom/ViewportArguments.cpp \
 	Source/WebCore/dom/ViewportArguments.h \
+	Source/WebCore/dom/VisitedLinkState.cpp \
+	Source/WebCore/dom/VisitedLinkState.h \
 	Source/WebCore/dom/WebCoreMemoryInstrumentation.cpp \
 	Source/WebCore/dom/WebCoreMemoryInstrumentation.h \
 	Source/WebCore/dom/WebKitAnimationEvent.cpp \

Modified: trunk/Source/WebCore/Target.pri (138514 => 138515)


--- trunk/Source/WebCore/Target.pri	2012-12-27 22:06:41 UTC (rev 138514)
+++ trunk/Source/WebCore/Target.pri	2012-12-27 22:57:00 UTC (rev 138515)
@@ -471,6 +471,7 @@
     dom/UserGestureIndicator.cpp \
     dom/UserTypingGestureIndicator.cpp \
     dom/ViewportArguments.cpp \
+    dom/VisitedLinkState.cpp \
     dom/WebCoreMemoryInstrumentation.cpp \
     dom/WebKitAnimationEvent.cpp \
     dom/WebKitTransitionEvent.cpp \

Modified: trunk/Source/WebCore/WebCore.gypi (138514 => 138515)


--- trunk/Source/WebCore/WebCore.gypi	2012-12-27 22:06:41 UTC (rev 138514)
+++ trunk/Source/WebCore/WebCore.gypi	2012-12-27 22:57:00 UTC (rev 138515)
@@ -2944,6 +2944,8 @@
             'dom/UserGestureIndicator.cpp',
             'dom/UserTypingGestureIndicator.cpp',
             'dom/ViewportArguments.cpp',
+            'dom/VisitedLinkState.cpp',
+            'dom/VisitedLinkState.h',
             'dom/WebCoreMemoryInstrumentation.cpp',
             'dom/WebCoreMemoryInstrumentation.h',
             'dom/WebKitAnimationEvent.cpp',

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (138514 => 138515)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2012-12-27 22:06:41 UTC (rev 138514)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2012-12-27 22:57:00 UTC (rev 138515)
@@ -1092,6 +1092,8 @@
 		418A06D1133C04D500CD379C /* EventDispatcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 418A06CF133C04D500CD379C /* EventDispatcher.cpp */; };
 		418F88040FF957AE0080F045 /* JSAbstractWorker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 418F88020FF957AE0080F045 /* JSAbstractWorker.cpp */; };
 		418F88050FF957AF0080F045 /* JSAbstractWorker.h in Headers */ = {isa = PBXBuildFile; fileRef = 418F88030FF957AE0080F045 /* JSAbstractWorker.h */; };
+		419BC2DE1685329900D64D6D /* VisitedLinkState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 419BC2DC1685329900D64D6D /* VisitedLinkState.cpp */; };
+		419BC2DF1685329900D64D6D /* VisitedLinkState.h in Headers */ = {isa = PBXBuildFile; fileRef = 419BC2DD1685329900D64D6D /* VisitedLinkState.h */; };
 		41A3D58E101C152D00316D07 /* DedicatedWorkerThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41A3D58C101C152D00316D07 /* DedicatedWorkerThread.cpp */; };
 		41A3D58F101C152D00316D07 /* DedicatedWorkerThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 41A3D58D101C152D00316D07 /* DedicatedWorkerThread.h */; };
 		41BF700B0FE86F49005E8DEC /* MessagePortChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41BF70090FE86F49005E8DEC /* MessagePortChannel.cpp */; };
@@ -8326,6 +8328,8 @@
 		418A06CF133C04D500CD379C /* EventDispatcher.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventDispatcher.cpp; sourceTree = "<group>"; };
 		418F88020FF957AE0080F045 /* JSAbstractWorker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSAbstractWorker.cpp; sourceTree = "<group>"; };
 		418F88030FF957AE0080F045 /* JSAbstractWorker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSAbstractWorker.h; sourceTree = "<group>"; };
+		419BC2DC1685329900D64D6D /* VisitedLinkState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VisitedLinkState.cpp; sourceTree = "<group>"; };
+		419BC2DD1685329900D64D6D /* VisitedLinkState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VisitedLinkState.h; sourceTree = "<group>"; };
 		41A3D58C101C152D00316D07 /* DedicatedWorkerThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DedicatedWorkerThread.cpp; path = workers/DedicatedWorkerThread.cpp; sourceTree = "<group>"; };
 		41A3D58D101C152D00316D07 /* DedicatedWorkerThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DedicatedWorkerThread.h; path = workers/DedicatedWorkerThread.h; sourceTree = "<group>"; };
 		41BF70090FE86F49005E8DEC /* MessagePortChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MessagePortChannel.cpp; sourceTree = "<group>"; };
@@ -22285,6 +22289,8 @@
 				BCDF317A11F8D683003C5BF8 /* UserTypingGestureIndicator.h */,
 				CEF418CC1179678C009D112C /* ViewportArguments.cpp */,
 				CEF418CD1179678C009D112C /* ViewportArguments.h */,
+				419BC2DC1685329900D64D6D /* VisitedLinkState.cpp */,
+				419BC2DD1685329900D64D6D /* VisitedLinkState.h */,
 				F3BFC9D215C177EC004244E5 /* WebCoreMemoryInstrumentation.cpp */,
 				4F377FF415FA356A00E5D60D /* WebCoreMemoryInstrumentation.h */,
 				31C0FF1B0E4CEB6E007D6FE5 /* WebKitAnimationEvent.cpp */,
@@ -25992,6 +25998,7 @@
 				0FB8890F167D30160010CDA5 /* ScrollingStateStickyNode.h in Headers */,
 				E13EF3441684ECF40034C83F /* NetworkStorageSession.h in Headers */,
 				415071581685067300C3C7B3 /* SelectorFilter.h in Headers */,
+				419BC2DF1685329900D64D6D /* VisitedLinkState.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -29112,6 +29119,7 @@
 				209B456B16796A7E00E54E4E /* JSCryptoCustom.cpp in Sources */,
 				E13EF34916850C470034C83F /* NetworkStorageSessionCFNet.cpp in Sources */,
 				415071571685067300C3C7B3 /* SelectorFilter.cpp in Sources */,
+				419BC2DE1685329900D64D6D /* VisitedLinkState.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

Modified: trunk/Source/WebCore/css/SelectorChecker.cpp (138514 => 138515)


--- trunk/Source/WebCore/css/SelectorChecker.cpp	2012-12-27 22:06:41 UTC (rev 138514)
+++ trunk/Source/WebCore/css/SelectorChecker.cpp	2012-12-27 22:57:00 UTC (rev 138515)
@@ -35,7 +35,6 @@
 #include "FocusController.h"
 #include "Frame.h"
 #include "FrameSelection.h"
-#include "HTMLAnchorElement.h"
 #include "HTMLFrameElementBase.h"
 #include "HTMLInputElement.h"
 #include "HTMLNames.h"
@@ -44,9 +43,7 @@
 #include "HTMLStyleElement.h"
 #include "InspectorInstrumentation.h"
 #include "NodeRenderStyle.h"
-#include "NodeTraversal.h"
 #include "Page.h"
-#include "PageGroup.h"
 #include "RenderObject.h"
 #include "RenderScrollbar.h"
 #include "RenderStyle.h"
@@ -56,13 +53,7 @@
 #include "SiblingTraversalStrategies.h"
 #include "StyledElement.h"
 #include "Text.h"
-#include "XLinkNames.h"
 
-#if USE(PLATFORM_STRATEGIES)
-#include "PlatformStrategies.h"
-#include "VisitedLinkStrategy.h"
-#endif
-
 namespace WebCore {
 
 using namespace HTMLNames;
@@ -77,56 +68,6 @@
 {
 }
 
-static inline const AtomicString* linkAttribute(Element* element)
-{
-    if (!element->isLink())
-        return 0;
-    if (element->isHTMLElement())
-        return &element->fastGetAttribute(hrefAttr);
-    if (element->isSVGElement())
-        return &element->getAttribute(XLinkNames::hrefAttr);
-    return 0;
-}
-
-EInsideLink SelectorChecker::determineLinkStateSlowCase(Element* element) const
-{
-    ASSERT(element->isLink());
-
-    const AtomicString* attribute = linkAttribute(element);
-    if (!attribute || attribute->isNull())
-        return NotInsideLink;
-
-    // An empty href refers to the document itself which is always visited. It is useful to check this explicitly so
-    // that visited links can be tested in platform independent manner, without explicit support in the test harness.
-    if (attribute->isEmpty())
-        return InsideVisitedLink;
-    
-    LinkHash hash;
-    if (element->hasTagName(aTag)) 
-        hash = static_cast<HTMLAnchorElement*>(element)->visitedLinkHash();
-    else
-        hash = visitedLinkHash(m_document->baseURL(), *attribute);
-
-    if (!hash)
-        return InsideUnvisitedLink;
-
-    Frame* frame = m_document->frame();
-    if (!frame)
-        return InsideUnvisitedLink;
-
-    Page* page = frame->page();
-    if (!page)
-        return InsideUnvisitedLink;
-
-    m_linksCheckedForVisitedState.add(hash);
-
-#if USE(PLATFORM_STRATEGIES)
-    return platformStrategies()->visitedLinkStrategy()->isLinkVisited(page, hash, m_document->baseURL(), *attribute) ? InsideVisitedLink : InsideUnvisitedLink;
-#else
-    return page->group().isLinkVisited(hash) ? InsideVisitedLink : InsideUnvisitedLink;
-#endif
-}
-
 bool SelectorChecker::checkSelector(CSSSelector* sel, Element* element, bool isFastCheckableSelector) const
 {
     if (isFastCheckableSelector && !element->isSVGElement()) {
@@ -1101,31 +1042,6 @@
     }
 }
 
-void SelectorChecker::allVisitedStateChanged()
-{
-    if (m_linksCheckedForVisitedState.isEmpty())
-        return;
-    for (Element* element = ElementTraversal::firstWithin(m_document); element; element = ElementTraversal::next(element)) {
-        if (element->isLink())
-            element->setNeedsStyleRecalc();
-    }
-}
-
-void SelectorChecker::visitedStateChanged(LinkHash visitedHash)
-{
-    if (!m_linksCheckedForVisitedState.contains(visitedHash))
-        return;
-    for (Element* element = ElementTraversal::firstWithin(m_document); element; element = ElementTraversal::next(element)) {
-        LinkHash hash = 0;
-        if (element->hasTagName(aTag))
-            hash = static_cast<HTMLAnchorElement*>(element)->visitedLinkHash();
-        else if (const AtomicString* attr = linkAttribute(element))
-            hash = visitedLinkHash(m_document->baseURL(), *attr);
-        if (hash == visitedHash)
-            element->setNeedsStyleRecalc();
-    }
-}
-
 bool SelectorChecker::commonPseudoClassSelectorMatches(const Element* element, const CSSSelector* selector, VisitedMatchType visitedMatchType) const
 {
     ASSERT(isCommonPseudoClassSelector(selector));

Modified: trunk/Source/WebCore/css/SelectorChecker.h (138514 => 138515)


--- trunk/Source/WebCore/css/SelectorChecker.h	2012-12-27 22:06:41 UTC (rev 138514)
+++ trunk/Source/WebCore/css/SelectorChecker.h	2012-12-27 22:57:00 UTC (rev 138515)
@@ -31,8 +31,6 @@
 #include "Attribute.h"
 #include "CSSSelector.h"
 #include "InspectorInstrumentation.h"
-#include "LinkHash.h"
-#include "RenderStyleConstants.h"
 #include "SpaceSplitString.h"
 #include "StyledElement.h"
 #include <wtf/HashSet.h>
@@ -88,10 +86,6 @@
     static bool isFastCheckableSelector(const CSSSelector*);
     bool fastCheckSelector(const CSSSelector*, const Element*) const;
 
-    EInsideLink determineLinkState(Element*) const;
-    void allVisitedStateChanged();
-    void visitedStateChanged(LinkHash visitedHash);
-
     Document* document() const { return m_document; }
     bool strictParsing() const { return m_strictParsing; }
 
@@ -115,22 +109,12 @@
     bool fastCheckRightmostSelector(const CSSSelector*, const Element*, VisitedMatchType) const;
     bool commonPseudoClassSelectorMatches(const Element*, const CSSSelector*, VisitedMatchType) const;
 
-    EInsideLink determineLinkStateSlowCase(Element*) const;
-
     Document* m_document;
     bool m_strictParsing;
     bool m_documentIsHTML;
     Mode m_mode;
-    mutable HashSet<LinkHash, LinkHashHash> m_linksCheckedForVisitedState;
 };
 
-inline EInsideLink SelectorChecker::determineLinkState(Element* element) const
-{
-    if (!element || !element->isLink())
-        return NotInsideLink;
-    return determineLinkStateSlowCase(element);
-}
-
 inline bool SelectorChecker::isCommonPseudoClassSelector(const CSSSelector* selector)
 {
     if (selector->m_match != CSSSelector::PseudoClass)

Modified: trunk/Source/WebCore/css/StyleResolver.cpp (138514 => 138515)


--- trunk/Source/WebCore/css/StyleResolver.cpp	2012-12-27 22:06:41 UTC (rev 138514)
+++ trunk/Source/WebCore/css/StyleResolver.cpp	2012-12-27 22:57:00 UTC (rev 138515)
@@ -88,7 +88,6 @@
 #include "NodeRenderStyle.h"
 #include "NodeRenderingContext.h"
 #include "Page.h"
-#include "PageGroup.h"
 #include "Pair.h"
 #include "PerspectiveTransformOperation.h"
 #include "QuotesData.h"
@@ -124,6 +123,7 @@
 #include "TranslateTransformOperation.h"
 #include "UserAgentStyleSheets.h"
 #include "ViewportStyleResolver.h"
+#include "VisitedLinkState.h"
 #include "WebCoreMemoryInstrumentation.h"
 #include "WebKitCSSKeyframeRule.h"
 #include "WebKitCSSKeyframesRule.h"
@@ -964,7 +964,7 @@
     if (m_element != e) {
         m_element = e;
         m_styledElement = m_element && m_element->isStyledElement() ? static_cast<StyledElement*>(m_element) : 0;
-        m_elementLinkState = m_checker.determineLinkState(m_element);
+        m_elementLinkState = m_checker.document()->visitedLinkState()->determineLinkState(m_element);
         if (e && e == e->document()->documentElement()) {
             e->document()->setDirectionSetOnDocumentElement(false);
             e->document()->setWritingModeSetOnDocumentElement(false);

Modified: trunk/Source/WebCore/css/StyleResolver.h (138514 => 138515)


--- trunk/Source/WebCore/css/StyleResolver.h	2012-12-27 22:06:41 UTC (rev 138514)
+++ trunk/Source/WebCore/css/StyleResolver.h	2012-12-27 22:57:00 UTC (rev 138515)
@@ -263,9 +263,6 @@
     bool hasViewportDependentMediaQueries() const { return !m_viewportDependentMediaQueryResults.isEmpty(); }
     bool affectedByViewportChange() const;
 
-    void allVisitedStateChanged() { m_checker.allVisitedStateChanged(); }
-    void visitedStateChanged(LinkHash visitedHash) { m_checker.visitedStateChanged(visitedHash); }
-
     void addKeyframeStyle(PassRefPtr<StyleRuleKeyframes>);
 
     bool checkRegionStyle(Element* regionElement);

Modified: trunk/Source/WebCore/dom/DOMAllInOne.cpp (138514 => 138515)


--- trunk/Source/WebCore/dom/DOMAllInOne.cpp	2012-12-27 22:06:41 UTC (rev 138514)
+++ trunk/Source/WebCore/dom/DOMAllInOne.cpp	2012-12-27 22:57:00 UTC (rev 138515)
@@ -149,6 +149,7 @@
 #include "UserGestureIndicator.cpp"
 #include "UserTypingGestureIndicator.cpp"
 #include "ViewportArguments.cpp"
+#include "VisitedLinkState.cpp"
 #include "WebKitAnimationEvent.cpp"
 #include "WebKitNamedFlow.cpp"
 #include "WebKitTransitionEvent.cpp"

Modified: trunk/Source/WebCore/dom/Document.cpp (138514 => 138515)


--- trunk/Source/WebCore/dom/Document.cpp	2012-12-27 22:06:41 UTC (rev 138514)
+++ trunk/Source/WebCore/dom/Document.cpp	2012-12-27 22:57:00 UTC (rev 138515)
@@ -161,6 +161,7 @@
 #include "TreeWalker.h"
 #include "UserActionElementSet.h"
 #include "UserContentURLPattern.h"
+#include "VisitedLinkState.h"
 #include "WebCoreMemoryInstrumentation.h"
 #include "WebKitNamedFlow.h"
 #include "XMLDocumentParser.h"
@@ -449,6 +450,7 @@
     , m_mutationObserverTypes(0)
 #endif
     , m_styleSheetCollection(DocumentStyleSheetCollection::create(this))
+    , m_visitedLinkState(VisitedLinkState::create(this))
     , m_readyState(Complete)
     , m_styleRecalcTimer(this, &Document::styleRecalcTimerFired)
     , m_pendingStyleRecalcShouldForce(false)

Modified: trunk/Source/WebCore/dom/Document.h (138514 => 138515)


--- trunk/Source/WebCore/dom/Document.h	2012-12-27 22:06:41 UTC (rev 138514)
+++ trunk/Source/WebCore/dom/Document.h	2012-12-27 22:57:00 UTC (rev 138515)
@@ -140,6 +140,7 @@
 class Text;
 class TextResourceDecoder;
 class TreeWalker;
+class VisitedLinkState;
 class WebKitNamedFlow;
 class XMLHttpRequest;
 class XPathEvaluator;
@@ -672,7 +673,8 @@
     void resetLinkColor();
     void resetVisitedLinkColor();
     void resetActiveLinkColor();
-    
+    VisitedLinkState* visitedLinkState() const { return m_visitedLinkState.get(); }
+
     MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const LayoutPoint&, const PlatformMouseEvent&);
 
     /* Newly proposed CSS3 mechanism for selecting alternate
@@ -1365,6 +1367,7 @@
     Color m_linkColor;
     Color m_visitedLinkColor;
     Color m_activeLinkColor;
+    OwnPtr<VisitedLinkState> m_visitedLinkState;
 
     bool m_loadingSheet;
     bool m_visuallyOrdered;

Added: trunk/Source/WebCore/dom/VisitedLinkState.cpp (0 => 138515)


--- trunk/Source/WebCore/dom/VisitedLinkState.cpp	                        (rev 0)
+++ trunk/Source/WebCore/dom/VisitedLinkState.cpp	2012-12-27 22:57:00 UTC (rev 138515)
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (kn...@kde.org)
+ *           (C) 2004-2005 Allan Sandfeld Jensen (k...@carewolf.com)
+ * Copyright (C) 2006, 2007 Nicholas Shanks (web...@nickshanks.com)
+ * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Alexey Proskuryakov <a...@webkit.org>
+ * Copyright (C) 2007, 2008 Eric Seidel <e...@webkit.org>
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (C) Research In Motion Limited 2011. All rights reserved.
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "VisitedLinkState.h"
+
+#include "Frame.h"
+#include "HTMLAnchorElement.h"
+#include "HTMLNames.h"
+#include "NodeTraversal.h"
+#include "Page.h"
+#include "PageGroup.h"
+
+#if USE(PLATFORM_STRATEGIES)
+#include "PlatformStrategies.h"
+#include "VisitedLinkStrategy.h"
+#endif
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline static const AtomicString* linkAttribute(Element* element)
+{
+    if (!element->isLink())
+        return 0;
+    if (element->isHTMLElement())
+        return &element->fastGetAttribute(HTMLNames::hrefAttr);
+    if (element->isSVGElement())
+        return &element->getAttribute(XLinkNames::hrefAttr);
+    return 0;
+}
+
+PassOwnPtr<VisitedLinkState> VisitedLinkState::create(Document* document)
+{
+    return adoptPtr(new VisitedLinkState(document));
+}
+
+VisitedLinkState::VisitedLinkState(Document* document)
+    :m_document(document)
+{ }
+
+void VisitedLinkState::invalidateStyleForAllLinks()
+{
+    if (m_linksCheckedForVisitedState.isEmpty())
+        return;
+    for (Element* element = ElementTraversal::firstWithin(m_document); element; element = ElementTraversal::next(element)) {
+        if (element->isLink())
+            element->setNeedsStyleRecalc();
+    }
+}
+
+inline static LinkHash linkHashForElement(Document* document, Element* element)
+{
+    if (element->hasTagName(aTag))
+        return static_cast<HTMLAnchorElement*>(element)->visitedLinkHash();
+    if (const AtomicString* attr = linkAttribute(element))
+        return WebCore::visitedLinkHash(document->baseURL(), *attr);
+    return 0;
+}
+
+void VisitedLinkState::invalidateStyleForLink(LinkHash linkHash)
+{
+    if (!m_linksCheckedForVisitedState.contains(linkHash))
+        return;
+    for (Element* element = ElementTraversal::firstWithin(m_document); element; element = ElementTraversal::next(element)) {
+        if (linkHashForElement(m_document, element) == linkHash)
+            element->setNeedsStyleRecalc();
+    }
+}
+
+EInsideLink VisitedLinkState::determineLinkStateSlowCase(Element* element)
+{
+    ASSERT(element->isLink());
+
+    const AtomicString* attribute = linkAttribute(element);
+    if (!attribute || attribute->isNull())
+        return NotInsideLink;
+
+    // An empty href refers to the document itself which is always visited. It is useful to check this explicitly so
+    // that visited links can be tested in platform independent manner, without explicit support in the test harness.
+    if (attribute->isEmpty())
+        return InsideVisitedLink;
+
+    LinkHash hash;
+    if (element->hasTagName(aTag))
+        hash = static_cast<HTMLAnchorElement*>(element)->visitedLinkHash();
+    else
+        hash = WebCore::visitedLinkHash(element->document()->baseURL(), *attribute);
+
+    if (!hash)
+        return InsideUnvisitedLink;
+
+    Frame* frame = element->document()->frame();
+    if (!frame)
+        return InsideUnvisitedLink;
+
+    Page* page = frame->page();
+    if (!page)
+        return InsideUnvisitedLink;
+
+    m_linksCheckedForVisitedState.add(hash);
+
+#if USE(PLATFORM_STRATEGIES)
+    return platformStrategies()->visitedLinkStrategy()->isLinkVisited(page, hash, element->document()->baseURL(), *attribute) ? InsideVisitedLink : InsideUnvisitedLink;
+#else
+    return page->group().isLinkVisited(hash) ? InsideVisitedLink : InsideUnvisitedLink;
+#endif
+}
+
+
+}
Property changes on: trunk/Source/WebCore/dom/VisitedLinkState.cpp
___________________________________________________________________

Added: svn:eol-style

Added: trunk/Source/WebCore/dom/VisitedLinkState.h (0 => 138515)


--- trunk/Source/WebCore/dom/VisitedLinkState.h	                        (rev 0)
+++ trunk/Source/WebCore/dom/VisitedLinkState.h	2012-12-27 22:57:00 UTC (rev 138515)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (kn...@kde.org)
+ *           (C) 2004-2005 Allan Sandfeld Jensen (k...@carewolf.com)
+ * Copyright (C) 2006, 2007 Nicholas Shanks (web...@nickshanks.com)
+ * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Alexey Proskuryakov <a...@webkit.org>
+ * Copyright (C) 2007, 2008 Eric Seidel <e...@webkit.org>
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (C) Research In Motion Limited 2011. All rights reserved.
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef VisitedLinkState_h
+#define VisitedLinkState_h
+
+#include "Element.h"
+#include "LinkHash.h"
+#include "RenderStyleConstants.h"
+#include "XLinkNames.h"
+#include <wtf/HashSet.h>
+#include <wtf/OwnPtr.h>
+
+namespace WebCore {
+
+class Document;
+
+class VisitedLinkState {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    static PassOwnPtr<VisitedLinkState> create(Document*);
+
+    void invalidateStyleForAllLinks();
+    void invalidateStyleForLink(LinkHash);
+    EInsideLink determineLinkState(Element*);
+
+private:
+    VisitedLinkState(Document*);
+
+    EInsideLink determineLinkStateSlowCase(Element*);
+
+    Document* m_document;
+    HashSet<LinkHash, LinkHashHash> m_linksCheckedForVisitedState;
+};
+
+inline EInsideLink VisitedLinkState::determineLinkState(Element* element)
+{
+    if (!element || !element->isLink())
+        return NotInsideLink;
+    return determineLinkStateSlowCase(element);
+}
+
+}
+
+#endif
+
Property changes on: trunk/Source/WebCore/dom/VisitedLinkState.h
___________________________________________________________________

Added: svn:eol-style

Modified: trunk/Source/WebCore/history/CachedPage.cpp (138514 => 138515)


--- trunk/Source/WebCore/history/CachedPage.cpp	2012-12-27 22:06:41 UTC (rev 138514)
+++ trunk/Source/WebCore/history/CachedPage.cpp	2012-12-27 22:57:00 UTC (rev 138515)
@@ -33,7 +33,7 @@
 #include "FrameView.h"
 #include "Node.h"
 #include "Page.h"
-#include "StyleResolver.h"
+#include "VisitedLinkState.h"
 #include <wtf/CurrentTime.h>
 #include <wtf/RefCountedLeakCounter.h>
 #include <wtf/StdLibExtras.h>
@@ -87,10 +87,8 @@
     }
 
     if (m_needStyleRecalcForVisitedLinks) {
-        for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
-            if (StyleResolver* styleResolver = frame->document()->styleResolver())
-                styleResolver->allVisitedStateChanged();
-        }
+        for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext())
+            frame->document()->visitedLinkState()->invalidateStyleForAllLinks();
     }
 
     if (m_needsFullStyleRecalc)

Modified: trunk/Source/WebCore/page/Page.cpp (138514 => 138515)


--- trunk/Source/WebCore/page/Page.cpp	2012-12-27 22:06:41 UTC (rev 138514)
+++ trunk/Source/WebCore/page/Page.cpp	2012-12-27 22:57:00 UTC (rev 138515)
@@ -69,8 +69,8 @@
 #include "SharedBuffer.h"
 #include "StorageArea.h"
 #include "StorageNamespace.h"
-#include "StyleResolver.h"
 #include "TextResourceDecoder.h"
+#include "VisitedLinkState.h"
 #include "VoidCallback.h"
 #include "WebCoreMemoryInstrumentation.h"
 #include "Widget.h"
@@ -940,14 +940,12 @@
         Page* page = *it;
         if (page->m_group != group)
             continue;
-        for (Frame* frame = page->m_mainFrame.get(); frame; frame = frame->tree()->traverseNext()) {
-            if (StyleResolver* styleResolver = frame->document()->styleResolver())
-                styleResolver->allVisitedStateChanged();
-        }
+        for (Frame* frame = page->m_mainFrame.get(); frame; frame = frame->tree()->traverseNext())
+            frame->document()->visitedLinkState()->invalidateStyleForAllLinks();
     }
 }
 
-void Page::visitedStateChanged(PageGroup* group, LinkHash visitedLinkHash)
+void Page::visitedStateChanged(PageGroup* group, LinkHash linkHash)
 {
     ASSERT(group);
     if (!allPages)
@@ -958,10 +956,8 @@
         Page* page = *it;
         if (page->m_group != group)
             continue;
-        for (Frame* frame = page->m_mainFrame.get(); frame; frame = frame->tree()->traverseNext()) {
-            if (StyleResolver* styleResolver = frame->document()->styleResolver())
-                styleResolver->visitedStateChanged(visitedLinkHash);
-        }
+        for (Frame* frame = page->m_mainFrame.get(); frame; frame = frame->tree()->traverseNext())
+            frame->document()->visitedLinkState()->invalidateStyleForLink(linkHash);
     }
 }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to