author | Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> |
Tue, 06 Jul 2010 15:10:48 +0300 | |
changeset 30 | 5dc02b23752f |
parent 0 | 1918ee327afb |
permissions | -rw-r--r-- |
0 | 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 |
||
30
5dc02b23752f
Revision: 201025
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
29 |
#include "Chrome.h" |
0 | 30 |
#include "ChromeClient.h" |
31 |
#include "Document.h" |
|
32 |
#include "Frame.h" |
|
33 |
#include "Page.h" |
|
34 |
#include "Settings.h" |
|
35 |
||
36 |
#if ENABLE(DOM_STORAGE) |
|
37 |
#include "StorageNamespace.h" |
|
38 |
#endif |
|
39 |
||
40 |
#if PLATFORM(CHROMIUM) |
|
41 |
#include "ChromiumBridge.h" |
|
42 |
#endif |
|
43 |
||
44 |
namespace WebCore { |
|
45 |
||
46 |
static unsigned getUniqueIdentifier() |
|
47 |
{ |
|
48 |
static unsigned currentIdentifier = 0; |
|
49 |
return ++currentIdentifier; |
|
50 |
} |
|
51 |
||
52 |
// -------- |
|
53 |
||
30
5dc02b23752f
Revision: 201025
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
54 |
static bool shouldTrackVisitedLinks = false; |
0 | 55 |
|
56 |
PageGroup::PageGroup(const String& name) |
|
57 |
: m_name(name) |
|
58 |
, m_visitedLinksPopulated(false) |
|
59 |
, m_identifier(getUniqueIdentifier()) |
|
60 |
{ |
|
61 |
} |
|
62 |
||
63 |
PageGroup::PageGroup(Page* page) |
|
64 |
: m_visitedLinksPopulated(false) |
|
65 |
, m_identifier(getUniqueIdentifier()) |
|
66 |
{ |
|
67 |
ASSERT(page); |
|
68 |
addPage(page); |
|
69 |
} |
|
70 |
||
71 |
PageGroup::~PageGroup() |
|
72 |
{ |
|
73 |
removeAllUserContent(); |
|
74 |
} |
|
75 |
||
76 |
typedef HashMap<String, PageGroup*> PageGroupMap; |
|
77 |
static PageGroupMap* pageGroups = 0; |
|
78 |
||
79 |
PageGroup* PageGroup::pageGroup(const String& groupName) |
|
80 |
{ |
|
81 |
ASSERT(!groupName.isEmpty()); |
|
82 |
||
83 |
if (!pageGroups) |
|
84 |
pageGroups = new PageGroupMap; |
|
85 |
||
86 |
pair<PageGroupMap::iterator, bool> result = pageGroups->add(groupName, 0); |
|
87 |
||
88 |
if (result.second) { |
|
89 |
ASSERT(!result.first->second); |
|
90 |
result.first->second = new PageGroup(groupName); |
|
91 |
} |
|
92 |
||
93 |
ASSERT(result.first->second); |
|
94 |
return result.first->second; |
|
95 |
} |
|
96 |
||
97 |
void PageGroup::closeLocalStorage() |
|
98 |
{ |
|
99 |
#if ENABLE(DOM_STORAGE) |
|
100 |
if (!pageGroups) |
|
101 |
return; |
|
102 |
||
103 |
PageGroupMap::iterator end = pageGroups->end(); |
|
104 |
||
105 |
for (PageGroupMap::iterator it = pageGroups->begin(); it != end; ++it) { |
|
106 |
if (it->second->hasLocalStorage()) |
|
107 |
it->second->localStorage()->close(); |
|
108 |
} |
|
109 |
#endif |
|
110 |
} |
|
111 |
||
112 |
void PageGroup::addPage(Page* page) |
|
113 |
{ |
|
114 |
ASSERT(page); |
|
115 |
ASSERT(!m_pages.contains(page)); |
|
116 |
m_pages.add(page); |
|
117 |
} |
|
118 |
||
119 |
void PageGroup::removePage(Page* page) |
|
120 |
{ |
|
121 |
ASSERT(page); |
|
122 |
ASSERT(m_pages.contains(page)); |
|
123 |
m_pages.remove(page); |
|
124 |
} |
|
125 |
||
126 |
bool PageGroup::isLinkVisited(LinkHash visitedLinkHash) |
|
127 |
{ |
|
128 |
#if PLATFORM(CHROMIUM) |
|
129 |
// Use Chromium's built-in visited link database. |
|
130 |
return ChromiumBridge::isLinkVisited(visitedLinkHash); |
|
131 |
#else |
|
132 |
if (!m_visitedLinksPopulated) { |
|
133 |
m_visitedLinksPopulated = true; |
|
134 |
ASSERT(!m_pages.isEmpty()); |
|
135 |
(*m_pages.begin())->chrome()->client()->populateVisitedLinks(); |
|
136 |
} |
|
137 |
return m_visitedLinkHashes.contains(visitedLinkHash); |
|
138 |
#endif |
|
139 |
} |
|
140 |
||
141 |
inline void PageGroup::addVisitedLink(LinkHash hash) |
|
142 |
{ |
|
143 |
ASSERT(shouldTrackVisitedLinks); |
|
144 |
#if !PLATFORM(CHROMIUM) |
|
145 |
if (!m_visitedLinkHashes.add(hash).second) |
|
146 |
return; |
|
147 |
#endif |
|
148 |
Page::visitedStateChanged(this, hash); |
|
149 |
} |
|
150 |
||
151 |
void PageGroup::addVisitedLink(const KURL& url) |
|
152 |
{ |
|
153 |
if (!shouldTrackVisitedLinks) |
|
154 |
return; |
|
155 |
ASSERT(!url.isEmpty()); |
|
156 |
addVisitedLink(visitedLinkHash(url.string().characters(), url.string().length())); |
|
157 |
} |
|
158 |
||
159 |
void PageGroup::addVisitedLink(const UChar* characters, size_t length) |
|
160 |
{ |
|
161 |
if (!shouldTrackVisitedLinks) |
|
162 |
return; |
|
163 |
addVisitedLink(visitedLinkHash(characters, length)); |
|
164 |
} |
|
165 |
||
166 |
void PageGroup::removeVisitedLinks() |
|
167 |
{ |
|
168 |
m_visitedLinksPopulated = false; |
|
169 |
if (m_visitedLinkHashes.isEmpty()) |
|
170 |
return; |
|
171 |
m_visitedLinkHashes.clear(); |
|
172 |
Page::allVisitedStateChanged(this); |
|
173 |
} |
|
174 |
||
175 |
void PageGroup::removeAllVisitedLinks() |
|
176 |
{ |
|
177 |
Page::removeAllVisitedLinks(); |
|
178 |
} |
|
179 |
||
180 |
void PageGroup::setShouldTrackVisitedLinks(bool shouldTrack) |
|
181 |
{ |
|
182 |
if (shouldTrackVisitedLinks == shouldTrack) |
|
183 |
return; |
|
184 |
shouldTrackVisitedLinks = shouldTrack; |
|
185 |
if (!shouldTrackVisitedLinks) |
|
186 |
removeAllVisitedLinks(); |
|
187 |
} |
|
188 |
||
189 |
#if ENABLE(DOM_STORAGE) |
|
190 |
StorageNamespace* PageGroup::localStorage() |
|
191 |
{ |
|
192 |
if (!m_localStorage) { |
|
193 |
// Need a page in this page group to query the settings for the local storage database path. |
|
194 |
Page* page = *m_pages.begin(); |
|
195 |
const String& path = page->settings()->localStorageDatabasePath(); |
|
196 |
unsigned quota = page->settings()->localStorageQuota(); |
|
197 |
m_localStorage = StorageNamespace::localStorageNamespace(path, quota); |
|
198 |
} |
|
199 |
||
200 |
return m_localStorage.get(); |
|
201 |
} |
|
202 |
#endif |
|
203 |
||
30
5dc02b23752f
Revision: 201025
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
204 |
void PageGroup::addUserScriptToWorld(DOMWrapperWorld* world, const String& source, const KURL& url, PassOwnPtr<Vector<String> > whitelist, |
0 | 205 |
PassOwnPtr<Vector<String> > blacklist, UserScriptInjectionTime injectionTime) |
206 |
{ |
|
30
5dc02b23752f
Revision: 201025
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
207 |
ASSERT_ARG(world, world); |
5dc02b23752f
Revision: 201025
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
208 |
|
5dc02b23752f
Revision: 201025
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
209 |
OwnPtr<UserScript> userScript(new UserScript(source, url, whitelist, blacklist, injectionTime)); |
0 | 210 |
if (!m_userScripts) |
211 |
m_userScripts.set(new UserScriptMap); |
|
30
5dc02b23752f
Revision: 201025
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
212 |
UserScriptVector*& scriptsInWorld = m_userScripts->add(world, 0).first->second; |
0 | 213 |
if (!scriptsInWorld) |
214 |
scriptsInWorld = new UserScriptVector; |
|
215 |
scriptsInWorld->append(userScript.release()); |
|
216 |
} |
|
217 |
||
30
5dc02b23752f
Revision: 201025
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
218 |
void PageGroup::addUserStyleSheetToWorld(DOMWrapperWorld* world, const String& source, const KURL& url, PassOwnPtr<Vector<String> > whitelist, |
0 | 219 |
PassOwnPtr<Vector<String> > blacklist) |
220 |
{ |
|
30
5dc02b23752f
Revision: 201025
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
221 |
ASSERT_ARG(world, world); |
5dc02b23752f
Revision: 201025
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
222 |
|
5dc02b23752f
Revision: 201025
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
223 |
OwnPtr<UserStyleSheet> userStyleSheet(new UserStyleSheet(source, url, whitelist, blacklist)); |
0 | 224 |
if (!m_userStyleSheets) |
225 |
m_userStyleSheets.set(new UserStyleSheetMap); |
|
30
5dc02b23752f
Revision: 201025
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
226 |
UserStyleSheetVector*& styleSheetsInWorld = m_userStyleSheets->add(world, 0).first->second; |
0 | 227 |
if (!styleSheetsInWorld) |
228 |
styleSheetsInWorld = new UserStyleSheetVector; |
|
229 |
styleSheetsInWorld->append(userStyleSheet.release()); |
|
230 |
||
231 |
// Clear our cached sheets and have them just reparse. |
|
232 |
HashSet<Page*>::const_iterator end = m_pages.end(); |
|
233 |
for (HashSet<Page*>::const_iterator it = m_pages.begin(); it != end; ++it) { |
|
234 |
for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext()) |
|
235 |
frame->document()->clearPageGroupUserSheets(); |
|
236 |
} |
|
237 |
} |
|
238 |
||
30
5dc02b23752f
Revision: 201025
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
239 |
void PageGroup::removeUserScriptFromWorld(DOMWrapperWorld* world, const KURL& url) |
0 | 240 |
{ |
30
5dc02b23752f
Revision: 201025
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
241 |
ASSERT_ARG(world, world); |
5dc02b23752f
Revision: 201025
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
242 |
|
0 | 243 |
if (!m_userScripts) |
244 |
return; |
|
245 |
||
30
5dc02b23752f
Revision: 201025
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
246 |
UserScriptMap::iterator it = m_userScripts->find(world); |
0 | 247 |
if (it == m_userScripts->end()) |
248 |
return; |
|
249 |
||
250 |
UserScriptVector* scripts = it->second; |
|
251 |
for (int i = scripts->size() - 1; i >= 0; --i) { |
|
252 |
if (scripts->at(i)->url() == url) |
|
253 |
scripts->remove(i); |
|
254 |
} |
|
255 |
||
256 |
if (!scripts->isEmpty()) |
|
257 |
return; |
|
258 |
||
259 |
delete it->second; |
|
260 |
m_userScripts->remove(it); |
|
261 |
} |
|
262 |
||
30
5dc02b23752f
Revision: 201025
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
263 |
void PageGroup::removeUserStyleSheetFromWorld(DOMWrapperWorld* world, const KURL& url) |
0 | 264 |
{ |
30
5dc02b23752f
Revision: 201025
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
265 |
ASSERT_ARG(world, world); |
5dc02b23752f
Revision: 201025
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
266 |
|
0 | 267 |
if (!m_userStyleSheets) |
268 |
return; |
|
269 |
||
30
5dc02b23752f
Revision: 201025
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
270 |
UserStyleSheetMap::iterator it = m_userStyleSheets->find(world); |
0 | 271 |
bool sheetsChanged = false; |
272 |
if (it == m_userStyleSheets->end()) |
|
273 |
return; |
|
274 |
||
275 |
UserStyleSheetVector* stylesheets = it->second; |
|
276 |
for (int i = stylesheets->size() - 1; i >= 0; --i) { |
|
277 |
if (stylesheets->at(i)->url() == url) { |
|
278 |
stylesheets->remove(i); |
|
279 |
sheetsChanged = true; |
|
280 |
} |
|
281 |
} |
|
282 |
||
283 |
if (!sheetsChanged) |
|
284 |
return; |
|
285 |
||
286 |
if (!stylesheets->isEmpty()) { |
|
287 |
delete it->second; |
|
288 |
m_userStyleSheets->remove(it); |
|
289 |
} |
|
290 |
||
291 |
// Clear our cached sheets and have them just reparse. |
|
292 |
HashSet<Page*>::const_iterator end = m_pages.end(); |
|
293 |
for (HashSet<Page*>::const_iterator it = m_pages.begin(); it != end; ++it) { |
|
294 |
for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext()) |
|
295 |
frame->document()->clearPageGroupUserSheets(); |
|
296 |
} |
|
297 |
} |
|
298 |
||
30
5dc02b23752f
Revision: 201025
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
299 |
void PageGroup::removeUserScriptsFromWorld(DOMWrapperWorld* world) |
0 | 300 |
{ |
30
5dc02b23752f
Revision: 201025
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
301 |
ASSERT_ARG(world, world); |
5dc02b23752f
Revision: 201025
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
302 |
|
0 | 303 |
if (!m_userScripts) |
304 |
return; |
|
305 |
||
30
5dc02b23752f
Revision: 201025
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
306 |
UserScriptMap::iterator it = m_userScripts->find(world); |
0 | 307 |
if (it == m_userScripts->end()) |
308 |
return; |
|
309 |
||
310 |
delete it->second; |
|
311 |
m_userScripts->remove(it); |
|
312 |
} |
|
313 |
||
30
5dc02b23752f
Revision: 201025
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
314 |
void PageGroup::removeUserStyleSheetsFromWorld(DOMWrapperWorld* world) |
0 | 315 |
{ |
30
5dc02b23752f
Revision: 201025
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
316 |
ASSERT_ARG(world, world); |
5dc02b23752f
Revision: 201025
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
317 |
|
0 | 318 |
if (!m_userStyleSheets) |
319 |
return; |
|
320 |
||
30
5dc02b23752f
Revision: 201025
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
321 |
UserStyleSheetMap::iterator it = m_userStyleSheets->find(world); |
0 | 322 |
if (it == m_userStyleSheets->end()) |
323 |
return; |
|
324 |
||
325 |
delete it->second; |
|
326 |
m_userStyleSheets->remove(it); |
|
327 |
||
328 |
// Clear our cached sheets and have them just reparse. |
|
329 |
HashSet<Page*>::const_iterator end = m_pages.end(); |
|
330 |
for (HashSet<Page*>::const_iterator it = m_pages.begin(); it != end; ++it) { |
|
331 |
for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext()) |
|
332 |
frame->document()->clearPageGroupUserSheets(); |
|
333 |
} |
|
334 |
} |
|
335 |
||
336 |
void PageGroup::removeAllUserContent() |
|
337 |
{ |
|
338 |
if (m_userScripts) { |
|
339 |
deleteAllValues(*m_userScripts); |
|
340 |
m_userScripts.clear(); |
|
341 |
} |
|
342 |
||
343 |
||
344 |
if (m_userStyleSheets) { |
|
345 |
deleteAllValues(*m_userStyleSheets); |
|
346 |
m_userStyleSheets.clear(); |
|
347 |
} |
|
348 |
} |
|
349 |
||
350 |
} // namespace WebCore |