Changeset 138515 in webkit


Ignore:
Timestamp:
Dec 27, 2012, 2:57:00 PM (13 years ago)
Author:
Dimitri Glazkov
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.

Location:
trunk/Source/WebCore
Files:
2 added
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/CMakeLists.txt

    r138512 r138515  
    12471247    dom/UserTypingGestureIndicator.cpp
    12481248    dom/ViewportArguments.cpp
     1249    dom/VisitedLinkState.cpp
    12491250    dom/WebCoreMemoryInstrumentation.cpp
    12501251    dom/WebKitAnimationEvent.cpp
  • trunk/Source/WebCore/ChangeLog

    r138513 r138515  
     12012-12-27  Dimitri Glazkov  <dglazkov@chromium.org>
     2
     3        Move visited link-checking (and caching) code out of SelectorChecker.
     4        https://bugs.webkit.org/show_bug.cgi?id=105752
     5
     6        SelectorChecker knew too much about visited links and how links are stored in DOM. This change
     7        moves the code to more relevant locations and moves the visited links cache all the way up to Document,
     8        introducing VisitedLinkState class to manage the state of visited links.
     9        Relanding without a null-ptr ref.
     10
     11        Reviewed by Antti Koivisto.
     12
     13        No change in behavior, covered by existing tests.
     14
     15        * CMakeLists.txt: Added VisitedLinkState to build system.
     16        * GNUmakefile.list.am: Ditto.
     17        * Target.pri: Ditto.
     18        * WebCore.gypi: Ditto.
     19        * WebCore.xcodeproj/project.pbxproj: Ditto.
     20        * css/SelectorChecker.cpp: Moved visited-link state code out to VisitedLinkState class.
     21        * css/SelectorChecker.h: Ditto.
     22        * css/StyleResolver.cpp:
     23        (WebCore::StyleResolver::initElement): Changed callsite to use VisitedLinkState.
     24        * css/StyleResolver.h: Removed plumb-throughs that are now unnecessary.
     25        * dom/DOMAllInOne.cpp: Added VisitedLinkState to build system.
     26        * dom/Document.cpp: Added VisitedLinkState initalizer.
     27        * dom/Document.h: Added VisitedLinkState member.
     28        * dom/VisitedLinkState.cpp: Added.
     29        * dom/VisitedLinkState.h: Added.
     30        * history/CachedPage.cpp:
     31        (WebCore::CachedPage::restore): Changed callsite to use VisitedLinkState.
     32        * page/Page.cpp:
     33        (WebCore::Page::allVisitedStateChanged): Ditto.
     34        (WebCore::Page::visitedStateChanged): Ditto.
     35
    1362012-12-27  Kondapally Kalyan  <kalyan.kondapally@intel.com>
    237
  • trunk/Source/WebCore/GNUmakefile.list.am

    r138512 r138515  
    29902990        Source/WebCore/dom/ViewportArguments.cpp \
    29912991        Source/WebCore/dom/ViewportArguments.h \
     2992        Source/WebCore/dom/VisitedLinkState.cpp \
     2993        Source/WebCore/dom/VisitedLinkState.h \
    29922994        Source/WebCore/dom/WebCoreMemoryInstrumentation.cpp \
    29932995        Source/WebCore/dom/WebCoreMemoryInstrumentation.h \
  • trunk/Source/WebCore/Target.pri

    r138512 r138515  
    472472    dom/UserTypingGestureIndicator.cpp \
    473473    dom/ViewportArguments.cpp \
     474    dom/VisitedLinkState.cpp \
    474475    dom/WebCoreMemoryInstrumentation.cpp \
    475476    dom/WebKitAnimationEvent.cpp \
  • trunk/Source/WebCore/WebCore.gypi

    r138512 r138515  
    29452945            'dom/UserTypingGestureIndicator.cpp',
    29462946            'dom/ViewportArguments.cpp',
     2947            'dom/VisitedLinkState.cpp',
     2948            'dom/VisitedLinkState.h',
    29472949            'dom/WebCoreMemoryInstrumentation.cpp',
    29482950            'dom/WebCoreMemoryInstrumentation.h',
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r138512 r138515  
    10931093                418F88040FF957AE0080F045 /* JSAbstractWorker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 418F88020FF957AE0080F045 /* JSAbstractWorker.cpp */; };
    10941094                418F88050FF957AF0080F045 /* JSAbstractWorker.h in Headers */ = {isa = PBXBuildFile; fileRef = 418F88030FF957AE0080F045 /* JSAbstractWorker.h */; };
     1095                419BC2DE1685329900D64D6D /* VisitedLinkState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 419BC2DC1685329900D64D6D /* VisitedLinkState.cpp */; };
     1096                419BC2DF1685329900D64D6D /* VisitedLinkState.h in Headers */ = {isa = PBXBuildFile; fileRef = 419BC2DD1685329900D64D6D /* VisitedLinkState.h */; };
    10951097                41A3D58E101C152D00316D07 /* DedicatedWorkerThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41A3D58C101C152D00316D07 /* DedicatedWorkerThread.cpp */; };
    10961098                41A3D58F101C152D00316D07 /* DedicatedWorkerThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 41A3D58D101C152D00316D07 /* DedicatedWorkerThread.h */; };
     
    83278329                418F88020FF957AE0080F045 /* JSAbstractWorker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSAbstractWorker.cpp; sourceTree = "<group>"; };
    83288330                418F88030FF957AE0080F045 /* JSAbstractWorker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSAbstractWorker.h; sourceTree = "<group>"; };
     8331                419BC2DC1685329900D64D6D /* VisitedLinkState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VisitedLinkState.cpp; sourceTree = "<group>"; };
     8332                419BC2DD1685329900D64D6D /* VisitedLinkState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VisitedLinkState.h; sourceTree = "<group>"; };
    83298333                41A3D58C101C152D00316D07 /* DedicatedWorkerThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DedicatedWorkerThread.cpp; path = workers/DedicatedWorkerThread.cpp; sourceTree = "<group>"; };
    83308334                41A3D58D101C152D00316D07 /* DedicatedWorkerThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DedicatedWorkerThread.h; path = workers/DedicatedWorkerThread.h; sourceTree = "<group>"; };
     
    2228622290                                CEF418CC1179678C009D112C /* ViewportArguments.cpp */,
    2228722291                                CEF418CD1179678C009D112C /* ViewportArguments.h */,
     22292                                419BC2DC1685329900D64D6D /* VisitedLinkState.cpp */,
     22293                                419BC2DD1685329900D64D6D /* VisitedLinkState.h */,
    2228822294                                F3BFC9D215C177EC004244E5 /* WebCoreMemoryInstrumentation.cpp */,
    2228922295                                4F377FF415FA356A00E5D60D /* WebCoreMemoryInstrumentation.h */,
     
    2599325999                                E13EF3441684ECF40034C83F /* NetworkStorageSession.h in Headers */,
    2599426000                                415071581685067300C3C7B3 /* SelectorFilter.h in Headers */,
     26001                                419BC2DF1685329900D64D6D /* VisitedLinkState.h in Headers */,
    2599526002                        );
    2599626003                        runOnlyForDeploymentPostprocessing = 0;
     
    2911329120                                E13EF34916850C470034C83F /* NetworkStorageSessionCFNet.cpp in Sources */,
    2911429121                                415071571685067300C3C7B3 /* SelectorFilter.cpp in Sources */,
     29122                                419BC2DE1685329900D64D6D /* VisitedLinkState.cpp in Sources */,
    2911529123                        );
    2911629124                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/Source/WebCore/css/SelectorChecker.cpp

    r138512 r138515  
    3636#include "Frame.h"
    3737#include "FrameSelection.h"
    38 #include "HTMLAnchorElement.h"
    3938#include "HTMLFrameElementBase.h"
    4039#include "HTMLInputElement.h"
     
    4544#include "InspectorInstrumentation.h"
    4645#include "NodeRenderStyle.h"
    47 #include "NodeTraversal.h"
    4846#include "Page.h"
    49 #include "PageGroup.h"
    5047#include "RenderObject.h"
    5148#include "RenderScrollbar.h"
     
    5754#include "StyledElement.h"
    5855#include "Text.h"
    59 #include "XLinkNames.h"
    60 
    61 #if USE(PLATFORM_STRATEGIES)
    62 #include "PlatformStrategies.h"
    63 #include "VisitedLinkStrategy.h"
    64 #endif
    6556
    6657namespace WebCore {
     
    7667    , m_mode(ResolvingStyle)
    7768{
    78 }
    79 
    80 static inline const AtomicString* linkAttribute(Element* element)
    81 {
    82     if (!element->isLink())
    83         return 0;
    84     if (element->isHTMLElement())
    85         return &element->fastGetAttribute(hrefAttr);
    86     if (element->isSVGElement())
    87         return &element->getAttribute(XLinkNames::hrefAttr);
    88     return 0;
    89 }
    90 
    91 EInsideLink SelectorChecker::determineLinkStateSlowCase(Element* element) const
    92 {
    93     ASSERT(element->isLink());
    94 
    95     const AtomicString* attribute = linkAttribute(element);
    96     if (!attribute || attribute->isNull())
    97         return NotInsideLink;
    98 
    99     // An empty href refers to the document itself which is always visited. It is useful to check this explicitly so
    100     // that visited links can be tested in platform independent manner, without explicit support in the test harness.
    101     if (attribute->isEmpty())
    102         return InsideVisitedLink;
    103    
    104     LinkHash hash;
    105     if (element->hasTagName(aTag))
    106         hash = static_cast<HTMLAnchorElement*>(element)->visitedLinkHash();
    107     else
    108         hash = visitedLinkHash(m_document->baseURL(), *attribute);
    109 
    110     if (!hash)
    111         return InsideUnvisitedLink;
    112 
    113     Frame* frame = m_document->frame();
    114     if (!frame)
    115         return InsideUnvisitedLink;
    116 
    117     Page* page = frame->page();
    118     if (!page)
    119         return InsideUnvisitedLink;
    120 
    121     m_linksCheckedForVisitedState.add(hash);
    122 
    123 #if USE(PLATFORM_STRATEGIES)
    124     return platformStrategies()->visitedLinkStrategy()->isLinkVisited(page, hash, m_document->baseURL(), *attribute) ? InsideVisitedLink : InsideUnvisitedLink;
    125 #else
    126     return page->group().isLinkVisited(hash) ? InsideVisitedLink : InsideUnvisitedLink;
    127 #endif
    12869}
    12970
     
    11021043}
    11031044
    1104 void SelectorChecker::allVisitedStateChanged()
    1105 {
    1106     if (m_linksCheckedForVisitedState.isEmpty())
    1107         return;
    1108     for (Element* element = ElementTraversal::firstWithin(m_document); element; element = ElementTraversal::next(element)) {
    1109         if (element->isLink())
    1110             element->setNeedsStyleRecalc();
    1111     }
    1112 }
    1113 
    1114 void SelectorChecker::visitedStateChanged(LinkHash visitedHash)
    1115 {
    1116     if (!m_linksCheckedForVisitedState.contains(visitedHash))
    1117         return;
    1118     for (Element* element = ElementTraversal::firstWithin(m_document); element; element = ElementTraversal::next(element)) {
    1119         LinkHash hash = 0;
    1120         if (element->hasTagName(aTag))
    1121             hash = static_cast<HTMLAnchorElement*>(element)->visitedLinkHash();
    1122         else if (const AtomicString* attr = linkAttribute(element))
    1123             hash = visitedLinkHash(m_document->baseURL(), *attr);
    1124         if (hash == visitedHash)
    1125             element->setNeedsStyleRecalc();
    1126     }
    1127 }
    1128 
    11291045bool SelectorChecker::commonPseudoClassSelectorMatches(const Element* element, const CSSSelector* selector, VisitedMatchType visitedMatchType) const
    11301046{
  • trunk/Source/WebCore/css/SelectorChecker.h

    r138512 r138515  
    3232#include "CSSSelector.h"
    3333#include "InspectorInstrumentation.h"
    34 #include "LinkHash.h"
    35 #include "RenderStyleConstants.h"
    3634#include "SpaceSplitString.h"
    3735#include "StyledElement.h"
     
    8987    bool fastCheckSelector(const CSSSelector*, const Element*) const;
    9088
    91     EInsideLink determineLinkState(Element*) const;
    92     void allVisitedStateChanged();
    93     void visitedStateChanged(LinkHash visitedHash);
    94 
    9589    Document* document() const { return m_document; }
    9690    bool strictParsing() const { return m_strictParsing; }
     
    116110    bool commonPseudoClassSelectorMatches(const Element*, const CSSSelector*, VisitedMatchType) const;
    117111
    118     EInsideLink determineLinkStateSlowCase(Element*) const;
    119 
    120112    Document* m_document;
    121113    bool m_strictParsing;
    122114    bool m_documentIsHTML;
    123115    Mode m_mode;
    124     mutable HashSet<LinkHash, LinkHashHash> m_linksCheckedForVisitedState;
    125116};
    126 
    127 inline EInsideLink SelectorChecker::determineLinkState(Element* element) const
    128 {
    129     if (!element || !element->isLink())
    130         return NotInsideLink;
    131     return determineLinkStateSlowCase(element);
    132 }
    133117
    134118inline bool SelectorChecker::isCommonPseudoClassSelector(const CSSSelector* selector)
  • trunk/Source/WebCore/css/StyleResolver.cpp

    r138512 r138515  
    8989#include "NodeRenderingContext.h"
    9090#include "Page.h"
    91 #include "PageGroup.h"
    9291#include "Pair.h"
    9392#include "PerspectiveTransformOperation.h"
     
    125124#include "UserAgentStyleSheets.h"
    126125#include "ViewportStyleResolver.h"
     126#include "VisitedLinkState.h"
    127127#include "WebCoreMemoryInstrumentation.h"
    128128#include "WebKitCSSKeyframeRule.h"
     
    965965        m_element = e;
    966966        m_styledElement = m_element && m_element->isStyledElement() ? static_cast<StyledElement*>(m_element) : 0;
    967         m_elementLinkState = m_checker.determineLinkState(m_element);
     967        m_elementLinkState = m_checker.document()->visitedLinkState()->determineLinkState(m_element);
    968968        if (e && e == e->document()->documentElement()) {
    969969            e->document()->setDirectionSetOnDocumentElement(false);
  • trunk/Source/WebCore/css/StyleResolver.h

    r138512 r138515  
    264264    bool affectedByViewportChange() const;
    265265
    266     void allVisitedStateChanged() { m_checker.allVisitedStateChanged(); }
    267     void visitedStateChanged(LinkHash visitedHash) { m_checker.visitedStateChanged(visitedHash); }
    268 
    269266    void addKeyframeStyle(PassRefPtr<StyleRuleKeyframes>);
    270267
  • trunk/Source/WebCore/dom/DOMAllInOne.cpp

    r138512 r138515  
    150150#include "UserTypingGestureIndicator.cpp"
    151151#include "ViewportArguments.cpp"
     152#include "VisitedLinkState.cpp"
    152153#include "WebKitAnimationEvent.cpp"
    153154#include "WebKitNamedFlow.cpp"
  • trunk/Source/WebCore/dom/Document.cpp

    r138512 r138515  
    162162#include "UserActionElementSet.h"
    163163#include "UserContentURLPattern.h"
     164#include "VisitedLinkState.h"
    164165#include "WebCoreMemoryInstrumentation.h"
    165166#include "WebKitNamedFlow.h"
     
    450451#endif
    451452    , m_styleSheetCollection(DocumentStyleSheetCollection::create(this))
     453    , m_visitedLinkState(VisitedLinkState::create(this))
    452454    , m_readyState(Complete)
    453455    , m_styleRecalcTimer(this, &Document::styleRecalcTimerFired)
  • trunk/Source/WebCore/dom/Document.h

    r138512 r138515  
    141141class TextResourceDecoder;
    142142class TreeWalker;
     143class VisitedLinkState;
    143144class WebKitNamedFlow;
    144145class XMLHttpRequest;
     
    673674    void resetVisitedLinkColor();
    674675    void resetActiveLinkColor();
    675    
     676    VisitedLinkState* visitedLinkState() const { return m_visitedLinkState.get(); }
     677
    676678    MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const LayoutPoint&, const PlatformMouseEvent&);
    677679
     
    13661368    Color m_visitedLinkColor;
    13671369    Color m_activeLinkColor;
     1370    OwnPtr<VisitedLinkState> m_visitedLinkState;
    13681371
    13691372    bool m_loadingSheet;
  • trunk/Source/WebCore/history/CachedPage.cpp

    r138512 r138515  
    3434#include "Node.h"
    3535#include "Page.h"
    36 #include "StyleResolver.h"
     36#include "VisitedLinkState.h"
    3737#include <wtf/CurrentTime.h>
    3838#include <wtf/RefCountedLeakCounter.h>
     
    8888
    8989    if (m_needStyleRecalcForVisitedLinks) {
    90         for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
    91             if (StyleResolver* styleResolver = frame->document()->styleResolver())
    92                 styleResolver->allVisitedStateChanged();
    93         }
     90        for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext())
     91            frame->document()->visitedLinkState()->invalidateStyleForAllLinks();
    9492    }
    9593
  • trunk/Source/WebCore/page/Page.cpp

    r138512 r138515  
    7070#include "StorageArea.h"
    7171#include "StorageNamespace.h"
    72 #include "StyleResolver.h"
    7372#include "TextResourceDecoder.h"
     73#include "VisitedLinkState.h"
    7474#include "VoidCallback.h"
    7575#include "WebCoreMemoryInstrumentation.h"
     
    941941        if (page->m_group != group)
    942942            continue;
    943         for (Frame* frame = page->m_mainFrame.get(); frame; frame = frame->tree()->traverseNext()) {
    944             if (StyleResolver* styleResolver = frame->document()->styleResolver())
    945                 styleResolver->allVisitedStateChanged();
    946         }
    947     }
    948 }
    949 
    950 void Page::visitedStateChanged(PageGroup* group, LinkHash visitedLinkHash)
     943        for (Frame* frame = page->m_mainFrame.get(); frame; frame = frame->tree()->traverseNext())
     944            frame->document()->visitedLinkState()->invalidateStyleForAllLinks();
     945    }
     946}
     947
     948void Page::visitedStateChanged(PageGroup* group, LinkHash linkHash)
    951949{
    952950    ASSERT(group);
     
    959957        if (page->m_group != group)
    960958            continue;
    961         for (Frame* frame = page->m_mainFrame.get(); frame; frame = frame->tree()->traverseNext()) {
    962             if (StyleResolver* styleResolver = frame->document()->styleResolver())
    963                 styleResolver->visitedStateChanged(visitedLinkHash);
    964         }
     959        for (Frame* frame = page->m_mainFrame.get(); frame; frame = frame->tree()->traverseNext())
     960            frame->document()->visitedLinkState()->invalidateStyleForLink(linkHash);
    965961    }
    966962}
Note: See TracChangeset for help on using the changeset viewer.