• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "StorageNamespace.h"
36 #endif
37 
38 #if PLATFORM(CHROMIUM)
39 #include "ChromiumBridge.h"
40 #endif
41 
42 namespace WebCore {
43 
getUniqueIdentifier()44 static unsigned getUniqueIdentifier()
45 {
46     static unsigned currentIdentifier = 0;
47     return ++currentIdentifier;
48 }
49 
50 // --------
51 
52 static bool shouldTrackVisitedLinks;
53 
PageGroup(const String & name)54 PageGroup::PageGroup(const String& name)
55     : m_name(name)
56     , m_visitedLinksPopulated(false)
57     , m_identifier(getUniqueIdentifier())
58 {
59 }
60 
PageGroup(Page * page)61 PageGroup::PageGroup(Page* page)
62     : m_visitedLinksPopulated(false)
63     , m_identifier(getUniqueIdentifier())
64 {
65     ASSERT(page);
66     addPage(page);
67 }
68 
69 typedef HashMap<String, PageGroup*> PageGroupMap;
70 static PageGroupMap* pageGroups = 0;
71 
pageGroup(const String & groupName)72 PageGroup* PageGroup::pageGroup(const String& groupName)
73 {
74     ASSERT(!groupName.isEmpty());
75 
76     if (!pageGroups)
77         pageGroups = new PageGroupMap;
78 
79     pair<PageGroupMap::iterator, bool> result = pageGroups->add(groupName, 0);
80 
81     if (result.second) {
82         ASSERT(!result.first->second);
83         result.first->second = new PageGroup(groupName);
84     }
85 
86     ASSERT(result.first->second);
87     return result.first->second;
88 }
89 
closeLocalStorage()90 void PageGroup::closeLocalStorage()
91 {
92 #if ENABLE(DOM_STORAGE)
93     if (!pageGroups)
94         return;
95 
96     PageGroupMap::iterator end = pageGroups->end();
97 
98     for (PageGroupMap::iterator it = pageGroups->begin(); it != end; ++it) {
99         if (it->second->hasLocalStorage())
100             it->second->localStorage()->close();
101     }
102 #endif
103 }
104 
addPage(Page * page)105 void PageGroup::addPage(Page* page)
106 {
107     ASSERT(page);
108     ASSERT(!m_pages.contains(page));
109     m_pages.add(page);
110 }
111 
removePage(Page * page)112 void PageGroup::removePage(Page* page)
113 {
114     ASSERT(page);
115     ASSERT(m_pages.contains(page));
116     m_pages.remove(page);
117 }
118 
isLinkVisited(LinkHash visitedLinkHash)119 bool PageGroup::isLinkVisited(LinkHash visitedLinkHash)
120 {
121 #if PLATFORM(CHROMIUM)
122     // Use Chromium's built-in visited link database.
123     return ChromiumBridge::isLinkVisited(visitedLinkHash);
124 #else
125     if (!m_visitedLinksPopulated) {
126         m_visitedLinksPopulated = true;
127         ASSERT(!m_pages.isEmpty());
128         (*m_pages.begin())->chrome()->client()->populateVisitedLinks();
129     }
130     return m_visitedLinkHashes.contains(visitedLinkHash);
131 #endif
132 }
133 
addVisitedLink(LinkHash hash)134 inline void PageGroup::addVisitedLink(LinkHash hash)
135 {
136     ASSERT(shouldTrackVisitedLinks);
137 #if !PLATFORM(CHROMIUM)
138     if (!m_visitedLinkHashes.add(hash).second)
139         return;
140 #endif
141     Page::visitedStateChanged(this, hash);
142 }
143 
addVisitedLink(const KURL & url)144 void PageGroup::addVisitedLink(const KURL& url)
145 {
146     if (!shouldTrackVisitedLinks)
147         return;
148     ASSERT(!url.isEmpty());
149     addVisitedLink(visitedLinkHash(url.string().characters(), url.string().length()));
150 }
151 
addVisitedLink(const UChar * characters,size_t length)152 void PageGroup::addVisitedLink(const UChar* characters, size_t length)
153 {
154     if (!shouldTrackVisitedLinks)
155         return;
156     addVisitedLink(visitedLinkHash(characters, length));
157 }
158 
removeVisitedLinks()159 void PageGroup::removeVisitedLinks()
160 {
161     m_visitedLinksPopulated = false;
162     if (m_visitedLinkHashes.isEmpty())
163         return;
164     m_visitedLinkHashes.clear();
165     Page::allVisitedStateChanged(this);
166 }
167 
removeAllVisitedLinks()168 void PageGroup::removeAllVisitedLinks()
169 {
170     Page::removeAllVisitedLinks();
171 }
172 
setShouldTrackVisitedLinks(bool shouldTrack)173 void PageGroup::setShouldTrackVisitedLinks(bool shouldTrack)
174 {
175     if (shouldTrackVisitedLinks == shouldTrack)
176         return;
177     shouldTrackVisitedLinks = shouldTrack;
178     if (!shouldTrackVisitedLinks)
179         removeAllVisitedLinks();
180 }
181 
182 #if ENABLE(DOM_STORAGE)
localStorage()183 StorageNamespace* PageGroup::localStorage()
184 {
185     if (!m_localStorage) {
186         // Need a page in this page group to query the settings for the local storage database path.
187         Page* page = *m_pages.begin();
188         ASSERT(page);
189         m_localStorage = StorageNamespace::localStorageNamespace(page->settings()->localStorageDatabasePath());
190     }
191 
192     return m_localStorage.get();
193 }
194 #endif
195 
196 } // namespace WebCore
197