1926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)/*
2926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *           (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
4926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com)
5926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
6926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
7926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
8926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
9926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
10926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Copyright (C) Research In Motion Limited 2011. All rights reserved.
11926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Copyright (C) 2012 Google Inc. All rights reserved.
12926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *
13926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * This library is free software; you can redistribute it and/or
14926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * modify it under the terms of the GNU Library General Public
15926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * License as published by the Free Software Foundation; either
16926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * version 2 of the License, or (at your option) any later version.
17926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *
18926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * This library is distributed in the hope that it will be useful,
19926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
20926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Library General Public License for more details.
22926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *
23926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * You should have received a copy of the GNU Library General Public License
24926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
25926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
26926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Boston, MA 02110-1301, USA.
27926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) */
28926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
29926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#include "config.h"
3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/VisitedLinkState.h"
31926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
325d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/HTMLNames.h"
335d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/XLinkNames.h"
34e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/dom/ElementTraversal.h"
3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLAnchorElement.h"
365267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "public/platform/Platform.h"
37926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
38c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
39926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
401e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)static inline const AtomicString& linkAttribute(const Element& element)
41926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
421e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ASSERT(element.isLink());
431e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (element.isHTMLElement())
441e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        return element.fastGetAttribute(HTMLNames::hrefAttr);
451e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ASSERT(element.isSVGElement());
461e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    return element.getAttribute(XLinkNames::hrefAttr);
4793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
4893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
491e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)static inline LinkHash linkHashForElement(const Element& element, const AtomicString& attribute = AtomicString())
5093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
511e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ASSERT(attribute.isNull() || linkAttribute(element) == attribute);
52d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (isHTMLAnchorElement(element))
531e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        return toHTMLAnchorElement(element).visitedLinkHash();
541e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    return visitedLinkHash(element.document().baseURL(), attribute.isNull() ? linkAttribute(element) : attribute);
55926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
56926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
571e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)VisitedLinkState::VisitedLinkState(const Document& document)
58926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    : m_document(document)
59926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
60926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
61926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
62926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void VisitedLinkState::invalidateStyleForAllLinks()
63926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
64926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (m_linksCheckedForVisitedState.isEmpty())
65926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return;
669e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    for (Node* node = document().firstChild(); node; node = NodeTraversal::next(*node)) {
679e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        if (node->isLink())
689e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            node->setNeedsStyleRecalc(SubtreeStyleChange);
69926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
70926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
71926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
72926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void VisitedLinkState::invalidateStyleForLink(LinkHash linkHash)
73926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
74926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!m_linksCheckedForVisitedState.contains(linkHash))
75926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return;
769e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    for (Node* node = document().firstChild(); node; node = NodeTraversal::next(*node)) {
779e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        if (node->isLink() && linkHashForElement(toElement(*node)) == linkHash)
789e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            node->setNeedsStyleRecalc(SubtreeStyleChange);
79926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
80926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
81926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
821e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)EInsideLink VisitedLinkState::determineLinkStateSlowCase(const Element& element)
83926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
841e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ASSERT(element.isLink());
85c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ASSERT(document().isActive());
86c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ASSERT(document() == element.document());
87926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
8893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    const AtomicString& attribute = linkAttribute(element);
89926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
9093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (attribute.isNull())
9193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return NotInsideLink; // This can happen for <img usemap>
92926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
9393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // An empty attribute refers to the document itself which is always
9493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // visited. It is useful to check this explicitly so that visited
9593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // links can be tested in platform independent manner, without
9693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // explicit support in the test harness.
9793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (attribute.isEmpty())
9893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return InsideVisitedLink;
99926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1001e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (LinkHash hash = linkHashForElement(element, attribute)) {
1011e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        m_linksCheckedForVisitedState.add(hash);
102e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        if (Platform::current()->isLinkVisited(hash))
1031e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            return InsideVisitedLink;
1041e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
105926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1061e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    return InsideUnvisitedLink;
107926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
108926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
109c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void VisitedLinkState::trace(Visitor* visitor)
110c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
111c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    visitor->trace(m_document);
112c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
113c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
114e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)} // namespace blink
115