b3e1b06d8b3a20814e907f509d04c66f895f3bfb
[WebKit-https.git] / WebCore / page / PageGroup.cpp
1 /*
2  * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "PageGroup.h"
28
29 #include "ChromeClient.h"
30 #include "Document.h"
31 #include "Page.h"
32 #include "Settings.h"
33
34 #if ENABLE(DOM_STORAGE)
35 #include "LocalStorage.h"
36 #include "StorageArea.h"
37 #endif
38
39 namespace WebCore {
40
41 static unsigned getUniqueIdentifier()
42 {
43     static unsigned currentIdentifier = 0;
44     return ++currentIdentifier;
45 }
46
47 // --------
48
49 static bool shouldTrackVisitedLinks;
50
51 PageGroup::PageGroup(const String& name)
52     : m_name(name)
53     , m_visitedLinksPopulated(false)
54     , m_identifier(getUniqueIdentifier())
55 {
56 }
57
58 PageGroup::PageGroup(Page* page)
59     : m_visitedLinksPopulated(false)
60     , m_identifier(getUniqueIdentifier())
61 {
62     ASSERT(page);
63     m_pages.add(page);
64 }
65
66 typedef HashMap<String, PageGroup*> PageGroupMap;
67 static PageGroupMap* pageGroups = 0;
68
69 PageGroup* PageGroup::pageGroup(const String& groupName)
70 {
71     ASSERT(!groupName.isEmpty());
72     
73     if (!pageGroups)
74         pageGroups = new PageGroupMap;
75
76     pair<PageGroupMap::iterator, bool> result = pageGroups->add(groupName, 0);
77
78     if (result.second) {
79         ASSERT(!result.first->second);
80         result.first->second = new PageGroup(groupName);
81     }
82
83     ASSERT(result.first->second);
84     return result.first->second;
85 }
86
87 void PageGroup::addPage(Page* page)
88 {
89     ASSERT(page);
90     ASSERT(!m_pages.contains(page));
91     m_pages.add(page);
92 #if ENABLE(DOM_STORAGE)
93     if (!m_localStorage)
94         m_localStorage = LocalStorage::create(this, page->settings()->localStorageDatabasePath());
95 #endif
96 }
97
98 void PageGroup::removePage(Page* page)
99 {
100     ASSERT(page);
101     ASSERT(m_pages.contains(page));
102     m_pages.remove(page);
103 }
104
105 bool PageGroup::isLinkVisited(unsigned visitedLinkHash)
106 {
107     if (!m_visitedLinksPopulated) {
108         m_visitedLinksPopulated = true;
109         ASSERT(!m_pages.isEmpty());
110         (*m_pages.begin())->chrome()->client()->populateVisitedLinks();
111     }
112     return m_visitedLinkHashes.contains(visitedLinkHash);
113 }
114
115 inline void PageGroup::addVisitedLink(unsigned stringHash)
116 {
117     ASSERT(shouldTrackVisitedLinks);
118     unsigned visitedLinkHash = AlreadyHashed::avoidDeletedValue(stringHash);
119     if (!m_visitedLinkHashes.add(visitedLinkHash).second)
120         return;
121     Page::visitedStateChanged(this, visitedLinkHash);
122 }
123
124 void PageGroup::addVisitedLink(const KURL& url)
125 {
126     if (!shouldTrackVisitedLinks)
127         return;
128     ASSERT(!url.isEmpty());
129     addVisitedLink(url.string().impl()->hash());
130 }
131
132 void PageGroup::addVisitedLink(const UChar* characters, size_t length)
133 {
134     if (!shouldTrackVisitedLinks)
135         return;
136     addVisitedLink(StringImpl::computeHash(characters, length));
137 }
138
139 void PageGroup::removeVisitedLinks()
140 {
141     m_visitedLinksPopulated = false;
142     if (m_visitedLinkHashes.isEmpty())
143         return;
144     m_visitedLinkHashes.clear();
145     Page::allVisitedStateChanged(this);
146 }
147
148 void PageGroup::removeAllVisitedLinks()
149 {
150     Page::removeAllVisitedLinks();
151 }
152
153 void PageGroup::setShouldTrackVisitedLinks(bool shouldTrack)
154 {
155     if (shouldTrackVisitedLinks == shouldTrack)
156         return;
157     shouldTrackVisitedLinks = shouldTrack;
158     if (!shouldTrackVisitedLinks)
159         removeAllVisitedLinks();
160 }
161
162 #if ENABLE(DOM_STORAGE)
163 LocalStorage* PageGroup::localStorage()
164 {
165     return m_localStorage.get();
166 }
167 #endif
168
169 } // namespace WebCore