OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2009 Google Inc. All Rights Reserved. | 2 * Copyright (C) 2009 Google Inc. All Rights Reserved. |
3 * (C) 2008 Apple Inc. | 3 * (C) 2008 Apple Inc. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 return String(); | 73 return String(); |
74 } | 74 } |
75 | 75 |
76 String StorageAreaProxy::getItem(const String& key, Frame* frame) const | 76 String StorageAreaProxy::getItem(const String& key, Frame* frame) const |
77 { | 77 { |
78 if (canAccessStorage(frame)) | 78 if (canAccessStorage(frame)) |
79 return m_storageArea->getItem(key); | 79 return m_storageArea->getItem(key); |
80 return String(); | 80 return String(); |
81 } | 81 } |
82 | 82 |
83 void StorageAreaProxy::setItem(const String& key, const String& value, Exception
Code& ec, Frame* frame) | 83 String StorageAreaProxy::setItem(const String& key, const String& value, Excepti
onCode& ec, Frame* frame) |
84 { | 84 { |
| 85 WebKit::WebStorageArea::Result result = WebKit::WebStorageArea::ResultOK; |
| 86 WebKit::WebString oldValue; |
85 if (!canAccessStorage(frame)) | 87 if (!canAccessStorage(frame)) |
86 ec = QUOTA_EXCEEDED_ERR; | 88 ec = QUOTA_EXCEEDED_ERR; |
87 else { | 89 else { |
88 WebKit::WebStorageArea::Result result = WebKit::WebStorageArea::ResultOK
; | 90 m_storageArea->setItem(key, value, frame->document()->url(), result, old
Value); |
89 m_storageArea->setItem(key, value, frame->document()->url(), result); | |
90 ec = (result == WebKit::WebStorageArea::ResultOK) ? 0 : QUOTA_EXCEEDED_E
RR; | 91 ec = (result == WebKit::WebStorageArea::ResultOK) ? 0 : QUOTA_EXCEEDED_E
RR; |
| 92 String oldValueString = oldValue; |
| 93 if (oldValueString != value && result == WebKit::WebStorageArea::ResultO
K) |
| 94 storageEvent(key, oldValue, value, m_storageType, frame->document()-
>securityOrigin(), frame); |
91 } | 95 } |
| 96 return oldValue; |
92 } | 97 } |
93 | 98 |
94 void StorageAreaProxy::removeItem(const String& key, Frame* frame) | 99 String StorageAreaProxy::removeItem(const String& key, Frame* frame) |
95 { | 100 { |
96 if (!canAccessStorage(frame)) | 101 if (!canAccessStorage(frame)) |
97 return; | 102 return String(); |
98 m_storageArea->removeItem(key, frame->document()->url()); | 103 WebKit::WebString oldValue; |
| 104 m_storageArea->removeItem(key, frame->document()->url(), oldValue); |
| 105 if (!oldValue.isNull()) |
| 106 storageEvent(key, oldValue, String(), m_storageType, frame->document()->
securityOrigin(), frame); |
| 107 return oldValue; |
99 } | 108 } |
100 | 109 |
101 void StorageAreaProxy::clear(Frame* frame) | 110 bool StorageAreaProxy::clear(Frame* frame) |
102 { | 111 { |
103 if (!canAccessStorage(frame)) | 112 if (!canAccessStorage(frame)) |
104 return; | 113 return false; |
105 m_storageArea->clear(frame->document()->url()); | 114 bool clearedSomething; |
| 115 m_storageArea->clear(frame->document()->url(), clearedSomething); |
| 116 if (clearedSomething) |
| 117 storageEvent(String(), String(), String(), m_storageType, frame->documen
t()->securityOrigin(), frame); |
| 118 return clearedSomething; |
106 } | 119 } |
107 | 120 |
108 bool StorageAreaProxy::contains(const String& key, Frame* frame) const | 121 bool StorageAreaProxy::contains(const String& key, Frame* frame) const |
109 { | 122 { |
110 return !getItem(key, frame).isNull(); | 123 return !getItem(key, frame).isNull(); |
111 } | 124 } |
112 | 125 |
| 126 // FIXME: remove this method and the calls to it from our setters after multi-si
de patch landing is done. |
| 127 // Copied from WebCore/storage/StorageEventDispatcher.cpp out of necessity. It'
s probably best to keep it current. |
| 128 void StorageAreaProxy::storageEvent(const String& key, const String& oldValue, c
onst String& newValue, StorageType storageType, SecurityOrigin* securityOrigin,
Frame* sourceFrame) |
| 129 { |
| 130 Page* page = sourceFrame->page(); |
| 131 if (!page) |
| 132 return; |
| 133 |
| 134 // We need to copy all relevant frames from every page to a vector since sen
ding the event to one frame might mutate the frame tree |
| 135 // of any given page in the group or mutate the page group itself. |
| 136 Vector<RefPtr<Frame> > frames; |
| 137 if (storageType == SessionStorage) { |
| 138 // Send events only to our page. |
| 139 for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->tra
verseNext()) { |
| 140 if (sourceFrame != frame && frame->document()->securityOrigin()->equ
al(securityOrigin)) |
| 141 frames.append(frame); |
| 142 } |
| 143 |
| 144 for (unsigned i = 0; i < frames.size(); ++i) { |
| 145 // FIXME: maybe only raise if the window has an onstorage listener |
| 146 // attached to avoid creating the Storage instance. |
| 147 ExceptionCode ec = 0; |
| 148 Storage* storage = frames[i]->domWindow()->sessionStorage(ec); |
| 149 if (!ec) |
| 150 frames[i]->document()->enqueueWindowEvent(StorageEvent::create(e
ventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->url(
), storage)); |
| 151 } |
| 152 } else { |
| 153 // Send events to every page. |
| 154 const HashSet<Page*>& pages = page->group().pages(); |
| 155 HashSet<Page*>::const_iterator end = pages.end(); |
| 156 for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it)
{ |
| 157 for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()
->traverseNext()) { |
| 158 if (sourceFrame != frame && frame->document()->securityOrigin()-
>equal(securityOrigin)) |
| 159 frames.append(frame); |
| 160 } |
| 161 } |
| 162 |
| 163 for (unsigned i = 0; i < frames.size(); ++i) { |
| 164 // FIXME: maybe only raise if the window has an onstorage listener |
| 165 // attached to avoid creating the Storage instance. |
| 166 ExceptionCode ec = 0; |
| 167 Storage* storage = frames[i]->domWindow()->localStorage(ec); |
| 168 if (!ec) |
| 169 frames[i]->document()->enqueueWindowEvent(StorageEvent::create(e
ventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->url(
), storage)); |
| 170 } |
| 171 } |
| 172 } |
| 173 |
113 bool StorageAreaProxy::canAccessStorage(Frame* frame) const | 174 bool StorageAreaProxy::canAccessStorage(Frame* frame) const |
114 { | 175 { |
115 if (!frame->page()) | 176 if (!frame->page()) |
116 return false; | 177 return false; |
117 WebKit::WebFrameImpl* webFrame = WebKit::WebFrameImpl::fromFrame(frame); | 178 WebKit::WebFrameImpl* webFrame = WebKit::WebFrameImpl::fromFrame(frame); |
118 WebKit::WebViewImpl* webView = webFrame->viewImpl(); | 179 WebKit::WebViewImpl* webView = webFrame->viewImpl(); |
119 return !webView->permissionClient() || webView->permissionClient()->allowSto
rage(webFrame, m_storageType == LocalStorage); | 180 return !webView->permissionClient() || webView->permissionClient()->allowSto
rage(webFrame, m_storageType == LocalStorage); |
120 } | 181 } |
121 | 182 |
122 void StorageAreaProxy::dispatchLocalStorageEvent(PageGroup* pageGroup, const Str
ing& key, const String& oldValue, const String& newValue, | 183 void StorageAreaProxy::dispatchLocalStorageEvent(const String& pageGroupName, co
nst String& key, const String& oldValue, const String& newValue, |
123 SecurityOrigin* securityOrigin,
const KURL& pageURL, WebKit::WebStorageArea* sourceAreaInstance, bool originate
dInProcess) | 184 SecurityOrigin* securityOrigin,
const KURL& pageURL, WebKit::WebStorageArea* sourceAreaInstance, bool originate
dInProcess) |
124 { | 185 { |
125 const HashSet<Page*>& pages = pageGroup->pages(); | 186 // FIXME: Multi-sided patch engineering alert ! |
| 187 // step 1: this method gets defined and implemented in webkit/webcore with t
he early return. |
| 188 // step 2: this method starts getting called by chromium still with the earl
y return. |
| 189 // step 3: This class's setters are modified to no longer raise SessionStora
ge |
| 190 // events for inprocess changes and this early return is removed. |
| 191 if (originatedInProcess) |
| 192 return; |
| 193 |
| 194 const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroupName)->pages(); |
126 for (HashSet<Page*>::const_iterator it = pages.begin(); it != pages.end(); +
+it) { | 195 for (HashSet<Page*>::const_iterator it = pages.begin(); it != pages.end(); +
+it) { |
127 for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->tr
averseNext()) { | 196 for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->tr
averseNext()) { |
128 if (frame->document()->securityOrigin()->equal(securityOrigin) && !i
sEventSource(frame->domWindow()->optionalLocalStorage(), sourceAreaInstance)) { | 197 if (frame->document()->securityOrigin()->equal(securityOrigin) && !i
sEventSource(frame->domWindow()->optionalLocalStorage(), sourceAreaInstance)) { |
129 // FIXME: maybe only raise if the window has an onstorage listen
er attached to avoid creating the Storage instance. | 198 // FIXME: maybe only raise if the window has an onstorage listen
er attached to avoid creating the Storage instance. |
130 ExceptionCode ec = 0; | 199 ExceptionCode ec = 0; |
131 Storage* storage = frame->domWindow()->localStorage(ec); | 200 Storage* storage = frame->domWindow()->localStorage(ec); |
132 if (!ec) | 201 if (!ec) |
133 frame->document()->enqueueWindowEvent(StorageEvent::create(e
ventNames().storageEvent, key, oldValue, newValue, pageURL, storage)); | 202 frame->document()->enqueueWindowEvent(StorageEvent::create(e
ventNames().storageEvent, key, oldValue, newValue, pageURL, storage)); |
134 } | 203 } |
135 } | 204 } |
136 } | 205 } |
137 } | 206 } |
138 | 207 |
139 static Page* findPageWithSessionStorageNamespace(PageGroup* pageGroup, const Web
Kit::WebStorageNamespace& sessionNamespace) | 208 static Page* findPageWithSessionStorageNamespace(const String& pageGroupName, co
nst WebKit::WebStorageNamespace& sessionNamespace) |
140 { | 209 { |
141 const HashSet<Page*>& pages = pageGroup->pages(); | 210 const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroupName)->pages(); |
142 for (HashSet<Page*>::const_iterator it = pages.begin(); it != pages.end(); +
+it) { | 211 for (HashSet<Page*>::const_iterator it = pages.begin(); it != pages.end(); +
+it) { |
143 const bool createIfNeeded = true; | 212 const bool createIfNeeded = true; |
144 StorageNamespaceProxy* proxy = static_cast<StorageNamespaceProxy*>((*it)
->sessionStorage(createIfNeeded)); | 213 StorageNamespaceProxy* proxy = static_cast<StorageNamespaceProxy*>((*it)
->sessionStorage(createIfNeeded)); |
145 if (proxy->isSameNamespace(sessionNamespace)) | 214 if (proxy->isSameNamespace(sessionNamespace)) |
146 return *it; | 215 return *it; |
147 } | 216 } |
148 return 0; | 217 return 0; |
149 } | 218 } |
150 | 219 |
151 void StorageAreaProxy::dispatchSessionStorageEvent(PageGroup* pageGroup, const S
tring& key, const String& oldValue, const String& newValue, | 220 void StorageAreaProxy::dispatchSessionStorageEvent(const String& pageGroupName,
const String& key, const String& oldValue, const String& newValue, |
152 SecurityOrigin* securityOrigi
n, const KURL& pageURL, const WebKit::WebStorageNamespace& sessionNamespace, | 221 SecurityOrigin* securityOrigi
n, const KURL& pageURL, const WebKit::WebStorageNamespace& sessionNamespace, |
153 WebKit::WebStorageArea* sourc
eAreaInstance, bool originatedInProcess) | 222 WebKit::WebStorageArea* sourc
eAreaInstance, bool originatedInProcess) |
154 { | 223 { |
155 Page* page = findPageWithSessionStorageNamespace(pageGroup, sessionNamespace
); | 224 // FIXME: Multi-sided patch engineering alert ! |
| 225 // step 1: this method gets defined and implemented in webkit/webcore with t
he early return. |
| 226 // step 2: this method starts getting called by chromium still with the earl
y return. |
| 227 // step 3: This class's setters are modified to no longer raise SessionStora
ge |
| 228 // events for inprocess changes and this early return is removed. |
| 229 if (originatedInProcess) |
| 230 return; |
| 231 |
| 232 Page* page = findPageWithSessionStorageNamespace(pageGroupName, sessionNames
pace); |
156 if (!page) | 233 if (!page) |
157 return; | 234 return; |
158 | 235 |
159 for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->travers
eNext()) { | 236 for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->travers
eNext()) { |
160 if (frame->document()->securityOrigin()->equal(securityOrigin) && !isEve
ntSource(frame->domWindow()->optionalSessionStorage(), sourceAreaInstance)) { | 237 if (frame->document()->securityOrigin()->equal(securityOrigin) && !isEve
ntSource(frame->domWindow()->optionalSessionStorage(), sourceAreaInstance)) { |
161 // FIXME: maybe only raise if the window has an onstorage listener a
ttached to avoid creating the Storage instance. | 238 // FIXME: maybe only raise if the window has an onstorage listener a
ttached to avoid creating the Storage instance. |
162 ExceptionCode ec = 0; | 239 ExceptionCode ec = 0; |
163 Storage* storage = frame->domWindow()->sessionStorage(ec); | 240 Storage* storage = frame->domWindow()->sessionStorage(ec); |
164 if (!ec) | 241 if (!ec) |
165 frame->document()->enqueueWindowEvent(StorageEvent::create(event
Names().storageEvent, key, oldValue, newValue, pageURL, storage)); | 242 frame->document()->enqueueWindowEvent(StorageEvent::create(event
Names().storageEvent, key, oldValue, newValue, pageURL, storage)); |
166 } | 243 } |
167 } | 244 } |
168 } | 245 } |
169 | 246 |
170 bool StorageAreaProxy::isEventSource(Storage* storage, WebKit::WebStorageArea* s
ourceAreaInstance) | 247 bool StorageAreaProxy::isEventSource(Storage* storage, WebKit::WebStorageArea* s
ourceAreaInstance) |
171 { | 248 { |
172 if (!storage) | 249 if (!storage) |
173 return false; | 250 return false; |
174 StorageAreaProxy* areaProxy = static_cast<StorageAreaProxy*>(storage->area()
); | 251 StorageAreaProxy* areaProxy = static_cast<StorageAreaProxy*>(storage->area()
); |
175 return areaProxy->m_storageArea == sourceAreaInstance; | 252 return areaProxy->m_storageArea == sourceAreaInstance; |
176 } | 253 } |
177 | 254 |
178 } // namespace WebCore | 255 } // namespace WebCore |
OLD | NEW |