| 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 |