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);
}
}