summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjorlow@chromium.org <jorlow@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-01 19:51:45 +0000
committerjorlow@chromium.org <jorlow@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-01 19:51:45 +0000
commitb94c30ecc12799ad4f89897cb8333b5285f2918a (patch)
tree92fd0243537d0c1104ee39ff37b812029f39c12b
parent1d5ac66b45c8e625fb4ec382d4e38e5357fdb257 (diff)
downloadchromium_src-b94c30ecc12799ad4f89897cb8333b5285f2918a.zip
chromium_src-b94c30ecc12799ad4f89897cb8333b5285f2918a.tar.gz
chromium_src-b94c30ecc12799ad4f89897cb8333b5285f2918a.tar.bz2
Another stab at the Chromium side of storage events. The WebKit side can be found here: https://bugs.webkit.org/show_bug.cgi?id=29655
TEST=Manually inspected that storage events fired. Will turn on more layout tests in a subsequent patch. BUG=19972 Review URL: http://codereview.chromium.org/223013 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27756 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/in_process_webkit/browser_webkitclient_impl.cc13
-rw-r--r--chrome/browser/in_process_webkit/browser_webkitclient_impl.h3
-rw-r--r--chrome/browser/in_process_webkit/dom_storage_context.cc39
-rw-r--r--chrome/browser/in_process_webkit/dom_storage_context.h15
-rw-r--r--chrome/browser/in_process_webkit/dom_storage_dispatcher_host.cc64
-rw-r--r--chrome/browser/in_process_webkit/dom_storage_dispatcher_host.h40
-rw-r--r--chrome/browser/in_process_webkit/storage_namespace.cc8
-rw-r--r--chrome/browser/in_process_webkit/storage_namespace.h6
-rw-r--r--chrome/browser/in_process_webkit/webkit_context.cc27
-rw-r--r--chrome/browser/in_process_webkit/webkit_context.h8
-rw-r--r--chrome/common/render_messages_internal.h8
-rw-r--r--chrome/renderer/render_thread.cc16
-rw-r--r--chrome/renderer/render_thread.h12
-rw-r--r--chrome/renderer/renderer_webstoragenamespace_impl.cc12
-rw-r--r--webkit/api/public/WebKitClient.h8
-rw-r--r--webkit/api/public/WebStorageEventDispatcher.h54
-rw-r--r--webkit/api/src/StorageEventDispatcherChromium.cpp3
-rw-r--r--webkit/api/src/StorageEventDispatcherImpl.cpp82
-rw-r--r--webkit/api/src/StorageEventDispatcherImpl.h60
-rw-r--r--webkit/api/src/WebStorageEventDispatcherImpl.cpp64
-rw-r--r--webkit/api/src/WebStorageEventDispatcherImpl.h59
-rw-r--r--webkit/glue/webkitclient_impl.cc6
-rw-r--r--webkit/glue/webkitclient_impl.h3
-rw-r--r--webkit/glue/webview_impl.cc10
-rw-r--r--webkit/webkit.gyp5
25 files changed, 579 insertions, 46 deletions
diff --git a/chrome/browser/in_process_webkit/browser_webkitclient_impl.cc b/chrome/browser/in_process_webkit/browser_webkitclient_impl.cc
index 33fc0de..53ced24 100644
--- a/chrome/browser/in_process_webkit/browser_webkitclient_impl.cc
+++ b/chrome/browser/in_process_webkit/browser_webkitclient_impl.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/in_process_webkit/browser_webkitclient_impl.h"
#include "base/logging.h"
+#include "chrome/browser/in_process_webkit/dom_storage_dispatcher_host.h"
#include "webkit/api/public/WebData.h"
#include "webkit/api/public/WebString.h"
#include "webkit/api/public/WebURL.h"
@@ -105,3 +106,15 @@ BrowserWebKitClientImpl::createSessionStorageNamespace() {
NOTREACHED();
return 0;
}
+
+void BrowserWebKitClientImpl::dispatchStorageEvent(
+ const WebKit::WebString& key, const WebKit::WebString& old_value,
+ const WebKit::WebString& new_value, const WebKit::WebString& origin,
+ bool is_local_storage) {
+ // TODO(jorlow): Implement
+ if (!is_local_storage)
+ return;
+
+ DOMStorageDispatcherHost::DispatchStorageEvent(key, old_value, new_value,
+ origin, is_local_storage);
+}
diff --git a/chrome/browser/in_process_webkit/browser_webkitclient_impl.h b/chrome/browser/in_process_webkit/browser_webkitclient_impl.h
index 546100d..07824db 100644
--- a/chrome/browser/in_process_webkit/browser_webkitclient_impl.h
+++ b/chrome/browser/in_process_webkit/browser_webkitclient_impl.h
@@ -32,6 +32,9 @@ class BrowserWebKitClientImpl : public webkit_glue::WebKitClientImpl {
virtual WebKit::WebStorageNamespace* createLocalStorageNamespace(
const WebKit::WebString& path);
virtual WebKit::WebStorageNamespace* createSessionStorageNamespace();
+ virtual void dispatchStorageEvent(const WebKit::WebString& key,
+ const WebKit::WebString& oldValue, const WebKit::WebString& newValue,
+ const WebKit::WebString& origin, bool isLocalStorage);
};
#endif // CHROME_BROWSER_IN_PROCESS_WEBKIT_WEBKIT_CLIENT_IMPL_H_
diff --git a/chrome/browser/in_process_webkit/dom_storage_context.cc b/chrome/browser/in_process_webkit/dom_storage_context.cc
index b22d976..9f763e2 100644
--- a/chrome/browser/in_process_webkit/dom_storage_context.cc
+++ b/chrome/browser/in_process_webkit/dom_storage_context.cc
@@ -14,11 +14,18 @@ DOMStorageContext::DOMStorageContext(WebKitContext* webkit_context)
: last_storage_area_id_(kFirstStorageAreaId),
last_storage_namespace_id_(kFirstStorageNamespaceId),
webkit_context_(webkit_context) {
- DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
}
DOMStorageContext::~DOMStorageContext() {
+ // This should not go away until all DOM Storage Dispatcher hosts have gone
+ // away. And they remove themselves from this list.
+ DCHECK(dispatcher_host_set_.empty());
+
+ // If we don't have any work to do on the WebKit thread, bail.
+ if (storage_namespace_map_.empty())
+ return;
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
+
// The storage namespace destructor unregisters the storage namespace, so
// our iterator becomes invalid. Thus we just keep deleting the first item
// until there are none left.
@@ -27,6 +34,7 @@ DOMStorageContext::~DOMStorageContext() {
}
StorageNamespace* DOMStorageContext::LocalStorage() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
StorageNamespace* storage_namespace = GetStorageNamespace(
kLocalStorageNamespaceId);
if (storage_namespace)
@@ -40,22 +48,26 @@ StorageNamespace* DOMStorageContext::LocalStorage() {
}
StorageNamespace* DOMStorageContext::NewSessionStorage() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
return StorageNamespace::CreateSessionStorageNamespace(this);
}
void DOMStorageContext::RegisterStorageArea(StorageArea* storage_area) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
int64 id = storage_area->id();
DCHECK(!GetStorageArea(id));
storage_area_map_[id] = storage_area;
}
void DOMStorageContext::UnregisterStorageArea(StorageArea* storage_area) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
int64 id = storage_area->id();
DCHECK(GetStorageArea(id));
storage_area_map_.erase(id);
}
StorageArea* DOMStorageContext::GetStorageArea(int64 id) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
StorageAreaMap::iterator iter = storage_area_map_.find(id);
if (iter == storage_area_map_.end())
return NULL;
@@ -64,6 +76,7 @@ StorageArea* DOMStorageContext::GetStorageArea(int64 id) {
void DOMStorageContext::RegisterStorageNamespace(
StorageNamespace* storage_namespace) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
int64 id = storage_namespace->id();
DCHECK(!GetStorageNamespace(id));
storage_namespace_map_[id] = storage_namespace;
@@ -71,14 +84,38 @@ void DOMStorageContext::RegisterStorageNamespace(
void DOMStorageContext::UnregisterStorageNamespace(
StorageNamespace* storage_namespace) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
int64 id = storage_namespace->id();
DCHECK(GetStorageNamespace(id));
storage_namespace_map_.erase(id);
}
StorageNamespace* DOMStorageContext::GetStorageNamespace(int64 id) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
StorageNamespaceMap::iterator iter = storage_namespace_map_.find(id);
if (iter == storage_namespace_map_.end())
return NULL;
return iter->second;
}
+
+void DOMStorageContext::RegisterDispatcherHost(
+ DOMStorageDispatcherHost* dispatcher_host) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+ DCHECK(dispatcher_host_set_.find(dispatcher_host) ==
+ dispatcher_host_set_.end());
+ dispatcher_host_set_.insert(dispatcher_host);
+}
+
+void DOMStorageContext::UnregisterDispatcherHost(
+ DOMStorageDispatcherHost* dispatcher_host) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+ DCHECK(dispatcher_host_set_.find(dispatcher_host) !=
+ dispatcher_host_set_.end());
+ dispatcher_host_set_.erase(dispatcher_host);
+}
+
+const DOMStorageContext::DispatcherHostSet*
+DOMStorageContext::GetDispatcherHostSet() const {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+ return &dispatcher_host_set_;
+}
diff --git a/chrome/browser/in_process_webkit/dom_storage_context.h b/chrome/browser/in_process_webkit/dom_storage_context.h
index ba26ac2..5e85876 100644
--- a/chrome/browser/in_process_webkit/dom_storage_context.h
+++ b/chrome/browser/in_process_webkit/dom_storage_context.h
@@ -7,6 +7,7 @@
#include "base/file_path.h"
#include "base/hash_tables.h"
+#include "chrome/browser/in_process_webkit/dom_storage_dispatcher_host.h"
class StorageArea;
class StorageNamespace;
@@ -15,7 +16,8 @@ class WebKitContext;
// This is owned by WebKitContext and is all the dom storage information that's
// shared by all the ResourceMessageFilter/DOMStorageDispatcherHosts that share
// the same profile. The specifics of responsibilities are fairly well
-// documented here and in StorageNamespace and StorageArea.
+// documented here and in StorageNamespace and StorageArea. Everything is only
+// to be accessed on the WebKit thread unless noted otherwise.
class DOMStorageContext {
public:
explicit DOMStorageContext(WebKitContext* webkit_context);
@@ -44,6 +46,13 @@ class DOMStorageContext {
void UnregisterStorageNamespace(StorageNamespace* storage_namespace);
StorageNamespace* GetStorageNamespace(int64 id);
+ // Sometimes an event from one DOM storage dispatcher host requires
+ // communication to all of them.
+ typedef base::hash_set<DOMStorageDispatcherHost*> DispatcherHostSet;
+ void RegisterDispatcherHost(DOMStorageDispatcherHost* dispatcher_host);
+ void UnregisterDispatcherHost(DOMStorageDispatcherHost* dispatcher_host);
+ const DispatcherHostSet* GetDispatcherHostSet() const;
+
// The special ID used for local storage.
static const int64 kLocalStorageNamespaceId = 0;
@@ -57,6 +66,10 @@ class DOMStorageContext {
// We're owned by this WebKit context. Used while instantiating LocalStorage.
WebKitContext* webkit_context_;
+ // All the DOMStorageDispatcherHosts that are attached to us. ONLY USE ON THE
+ // IO THREAD!
+ DispatcherHostSet dispatcher_host_set_;
+
// Maps ids to StorageAreas. We do NOT own these objects. StorageNamespace
// (which does own them) will notify us when we should remove the entries.
typedef base::hash_map<int64, StorageArea*> StorageAreaMap;
diff --git a/chrome/browser/in_process_webkit/dom_storage_dispatcher_host.cc b/chrome/browser/in_process_webkit/dom_storage_dispatcher_host.cc
index ac39acb..1856a37 100644
--- a/chrome/browser/in_process_webkit/dom_storage_dispatcher_host.cc
+++ b/chrome/browser/in_process_webkit/dom_storage_dispatcher_host.cc
@@ -13,6 +13,23 @@
#include "chrome/browser/renderer_host/browser_render_process_host.h"
#include "chrome/common/render_messages.h"
+DOMStorageDispatcherHost* DOMStorageDispatcherHost::current_ = NULL;
+
+DOMStorageDispatcherHost::
+AutoSetCurrentDispatcherHost::AutoSetCurrentDispatcherHost(
+ DOMStorageDispatcherHost* dispatcher_host) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
+ DCHECK(!current_);
+ current_ = dispatcher_host;
+}
+
+DOMStorageDispatcherHost::
+AutoSetCurrentDispatcherHost::~AutoSetCurrentDispatcherHost() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
+ DCHECK(current_);
+ current_ = NULL;
+}
+
DOMStorageDispatcherHost::DOMStorageDispatcherHost(
IPC::Message::Sender* message_sender, WebKitContext* webkit_context,
WebKitThread* webkit_thread)
@@ -32,6 +49,9 @@ DOMStorageDispatcherHost::~DOMStorageDispatcherHost() {
}
void DOMStorageDispatcherHost::Init(base::ProcessHandle process_handle) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+ Context()->RegisterDispatcherHost(this);
+
DCHECK(!process_handle_);
process_handle_ = process_handle;
DCHECK(process_handle_);
@@ -39,6 +59,7 @@ void DOMStorageDispatcherHost::Init(base::ProcessHandle process_handle) {
void DOMStorageDispatcherHost::Shutdown() {
if (ChromeThread::CurrentlyOn(ChromeThread::IO)) {
+ Context()->UnregisterDispatcherHost(this);
message_sender_ = NULL;
if (!ever_used_) {
// No need to (possibly) spin up the WebKit thread for a no-op.
@@ -58,12 +79,24 @@ void DOMStorageDispatcherHost::Shutdown() {
DCHECK(!shutdown_);
shutdown_ = true;
- // TODO(jorlow): If we have any locks or are tracking resources that need to
- // be released on the WebKit thread, do it here.
+ // TODO(jorlow): Do stuff that needs to be run on the WebKit thread. Locks
+ // and others will likely need this, so let's not delete this
+ // code even though it doesn't do anyting yet.
}
-bool DOMStorageDispatcherHost::OnMessageReceived(
- const IPC::Message& message, bool *msg_is_ok) {
+/* static */
+void DOMStorageDispatcherHost::DispatchStorageEvent(const string16& key,
+ const NullableString16& old_value, const NullableString16& new_value,
+ const string16& origin, bool is_local_storage) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
+ DCHECK(current_);
+ current_->webkit_thread_->PostIOThreadTask(FROM_HERE, NewRunnableMethod(
+ current_, &DOMStorageDispatcherHost::OnStorageEvent, key, old_value,
+ new_value, origin, is_local_storage));
+}
+
+bool DOMStorageDispatcherHost::OnMessageReceived(const IPC::Message& message,
+ bool *msg_is_ok) {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
DCHECK(!shutdown_);
DCHECK(process_handle_);
@@ -272,6 +305,8 @@ void DOMStorageDispatcherHost::OnSetItem(int64 storage_area_id,
ViewHostMsg_DOMStorageSetItem::ID, process_handle_);
return;
}
+
+ AutoSetCurrentDispatcherHost auto_set(this);
storage_area->SetItem(key, value, &quota_exception);
DCHECK(!quota_exception); // This is tracked by the renderer.
}
@@ -293,6 +328,8 @@ void DOMStorageDispatcherHost::OnRemoveItem(int64 storage_area_id,
ViewHostMsg_DOMStorageRemoveItem::ID, process_handle_);
return;
}
+
+ AutoSetCurrentDispatcherHost auto_set(this);
storage_area->RemoveItem(key);
}
@@ -312,5 +349,24 @@ void DOMStorageDispatcherHost::OnClear(int64 storage_area_id) {
ViewHostMsg_DOMStorageClear::ID, process_handle_);
return;
}
+
+ AutoSetCurrentDispatcherHost auto_set(this);
storage_area->Clear();
}
+
+void DOMStorageDispatcherHost::OnStorageEvent(const string16& key,
+ const NullableString16& old_value, const NullableString16& new_value,
+ const string16& origin, bool is_local_storage) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+ DCHECK(is_local_storage); // Only LocalStorage is implemented right now.
+ DOMStorageType dom_storage_type = is_local_storage ? DOM_STORAGE_LOCAL
+ : DOM_STORAGE_SESSION;
+ const DOMStorageContext::DispatcherHostSet* set =
+ Context()->GetDispatcherHostSet();
+ DOMStorageContext::DispatcherHostSet::const_iterator cur = set->begin();
+ while (cur != set->end()) {
+ (*cur)->Send(new ViewMsg_DOMStorageEvent(key, old_value, new_value, origin,
+ dom_storage_type));
+ ++cur;
+ }
+}
diff --git a/chrome/browser/in_process_webkit/dom_storage_dispatcher_host.h b/chrome/browser/in_process_webkit/dom_storage_dispatcher_host.h
index a0d3d77..7b34ad7 100644
--- a/chrome/browser/in_process_webkit/dom_storage_dispatcher_host.h
+++ b/chrome/browser/in_process_webkit/dom_storage_dispatcher_host.h
@@ -29,14 +29,22 @@ class DOMStorageDispatcherHost :
// Only call from ResourceMessageFilter on the IO thread.
void Init(base::ProcessHandle process_handle);
- // Only call from ResourceMessageFilter on the IO thread.
+ // Only call from ResourceMessageFilter on the IO thread. Calls self on the
+ // WebKit thread in some cases.
void Shutdown();
+
+ // Only call from ResourceMessageFilter on the IO thread.
bool OnMessageReceived(const IPC::Message& message, bool *msg_is_ok);
// Send a message to the renderer process associated with our
// message_sender_ via the IO thread. May be called from any thread.
void Send(IPC::Message* message);
+ // Only call on the WebKit thread.
+ static void DispatchStorageEvent(const string16& key,
+ const NullableString16& old_value, const NullableString16& new_value,
+ const string16& origin, bool is_local_storage);
+
private:
friend class base::RefCountedThreadSafe<DOMStorageDispatcherHost>;
~DOMStorageDispatcherHost();
@@ -55,12 +63,27 @@ class DOMStorageDispatcherHost :
void OnRemoveItem(int64 storage_area_id, const string16& key);
void OnClear(int64 storage_area_id);
+ // Only call on the IO thread.
+ void OnStorageEvent(const string16& key, const NullableString16& old_value,
+ const NullableString16& new_value, const string16& origin,
+ bool is_local_storage);
+
// A shortcut for accessing our context.
DOMStorageContext* Context() {
DCHECK(!shutdown_);
- return webkit_context_->GetDOMStorageContext();
+ return webkit_context_->dom_storage_context();
}
+ // Use whenever there's a chance OnStorageEvent will be called.
+ class AutoSetCurrentDispatcherHost {
+ public:
+ AutoSetCurrentDispatcherHost(DOMStorageDispatcherHost* dispatcher_host);
+ ~AutoSetCurrentDispatcherHost();
+ };
+
+ // Only access on the WebKit thread! Used for storage events.
+ static DOMStorageDispatcherHost* current_;
+
// Data shared between renderer processes with the same profile.
scoped_refptr<WebKitContext> webkit_context_;
@@ -87,4 +110,17 @@ class DOMStorageDispatcherHost :
DISALLOW_IMPLICIT_CONSTRUCTORS(DOMStorageDispatcherHost);
};
+#if defined(COMPILER_GCC)
+namespace __gnu_cxx {
+
+template<>
+struct hash<DOMStorageDispatcherHost*> {
+ std::size_t operator()(DOMStorageDispatcherHost* const& p) const {
+ return reinterpret_cast<std::size_t>(p);
+ }
+};
+
+} // namespace __gnu_cxx
+#endif
+
#endif // CHROME_BROWSER_IN_PROCESS_WEBKIT_DOM_STORAGE_DISPATCHER_HOST_H_
diff --git a/chrome/browser/in_process_webkit/storage_namespace.cc b/chrome/browser/in_process_webkit/storage_namespace.cc
index fa2c74a..fb49259 100644
--- a/chrome/browser/in_process_webkit/storage_namespace.cc
+++ b/chrome/browser/in_process_webkit/storage_namespace.cc
@@ -42,11 +42,11 @@ StorageNamespace* StorageNamespace::CreateSessionStorageNamespace(
StorageNamespace::StorageNamespace(DOMStorageContext* dom_storage_context,
WebStorageNamespace* storage_namespace,
- int64 id, DOMStorageType storage_type)
+ int64 id, DOMStorageType dom_storage_type)
: dom_storage_context_(dom_storage_context),
storage_namespace_(storage_namespace),
id_(id),
- storage_type_(storage_type) {
+ dom_storage_type_(dom_storage_type) {
DCHECK(dom_storage_context_);
DCHECK(storage_namespace_);
dom_storage_context_->RegisterStorageNamespace(this);
@@ -82,12 +82,12 @@ StorageArea* StorageNamespace::GetStorageArea(const string16& origin) {
}
StorageNamespace* StorageNamespace::Copy() {
- DCHECK(storage_type_ == DOM_STORAGE_SESSION);
+ DCHECK(dom_storage_type_ == DOM_STORAGE_SESSION);
int64 id = dom_storage_context_->AllocateStorageNamespaceId();
DCHECK(!dom_storage_context_->GetStorageNamespace(id));
WebStorageNamespace* new_storage_namespace = storage_namespace_->copy();
return new StorageNamespace(dom_storage_context_, new_storage_namespace, id,
- storage_type_);
+ dom_storage_type_);
}
void StorageNamespace::Close() {
diff --git a/chrome/browser/in_process_webkit/storage_namespace.h b/chrome/browser/in_process_webkit/storage_namespace.h
index 91e0ae6..9752212 100644
--- a/chrome/browser/in_process_webkit/storage_namespace.h
+++ b/chrome/browser/in_process_webkit/storage_namespace.h
@@ -31,7 +31,11 @@ class StorageNamespace {
StorageNamespace* Copy();
void Close();
+ const DOMStorageContext* dom_storage_context() const {
+ return dom_storage_context_;
+ }
int64 id() const { return id_; }
+ DOMStorageType dom_storage_type() const { return dom_storage_type_; }
private:
// Called by the static factory methods above.
@@ -53,7 +57,7 @@ class StorageNamespace {
int64 id_;
// SessionStorage vs. LocalStorage.
- const DOMStorageType storage_type_;
+ const DOMStorageType dom_storage_type_;
DISALLOW_IMPLICIT_CONSTRUCTORS(StorageNamespace);
};
diff --git a/chrome/browser/in_process_webkit/webkit_context.cc b/chrome/browser/in_process_webkit/webkit_context.cc
index ae647d6..0768284 100644
--- a/chrome/browser/in_process_webkit/webkit_context.cc
+++ b/chrome/browser/in_process_webkit/webkit_context.cc
@@ -9,24 +9,17 @@
WebKitContext::WebKitContext(const FilePath& data_path, bool is_incognito)
: data_path_(data_path),
- is_incognito_(is_incognito) {
+ is_incognito_(is_incognito),
+ ALLOW_THIS_IN_INITIALIZER_LIST(
+ dom_storage_context_(new DOMStorageContext(this))) {
}
WebKitContext::~WebKitContext() {
- // If a dom storage context was ever created, we need to destroy it on the
- // WebKit thread. Luckily we're guaranteed that the WebKit thread is still
- // alive since the ResourceDispatcherHost (which owns the WebKit thread) goes
- // away after all the ResourceMessageFilters and the profiles (i.e. all the
- // objects with a reference to us).
- if (dom_storage_context_.get()) {
- MessageLoop* loop = ChromeThread::GetMessageLoop(ChromeThread::WEBKIT);
- loop->DeleteSoon(FROM_HERE, dom_storage_context_.release());
- }
-}
-
-DOMStorageContext* WebKitContext::GetDOMStorageContext() {
- DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
- if (!dom_storage_context_.get())
- dom_storage_context_.reset(new DOMStorageContext(this));
- return dom_storage_context_.get();
+ // If the WebKit thread was ever spun up, delete the object there. If we're
+ // on the IO thread, this is safe because the WebKit thread goes away after
+ // the IO. If we're on the UI thread, we're safe because the UI thread kills
+ // the WebKit thread.
+ MessageLoop* webkit_loop = ChromeThread::GetMessageLoop(ChromeThread::WEBKIT);
+ if (webkit_loop)
+ webkit_loop->DeleteSoon(FROM_HERE, dom_storage_context_.release());
}
diff --git a/chrome/browser/in_process_webkit/webkit_context.h b/chrome/browser/in_process_webkit/webkit_context.h
index ee4c61b..b359ab0 100644
--- a/chrome/browser/in_process_webkit/webkit_context.h
+++ b/chrome/browser/in_process_webkit/webkit_context.h
@@ -10,6 +10,7 @@
#include "base/scoped_ptr.h"
class DOMStorageContext;
+class WebKitThread;
// There's one WebKitContext per profile. Various DispatcherHost classes
// have a pointer to the Context to store shared state.
@@ -19,9 +20,9 @@ class WebKitContext : public base::RefCountedThreadSafe<WebKitContext> {
const FilePath& data_path() const { return data_path_; }
bool is_incognito() const { return is_incognito_; }
-
- // Initialized lazily. Pointer is valid for the lifetime of this instance.
- DOMStorageContext* GetDOMStorageContext();
+ DOMStorageContext* dom_storage_context() {
+ return dom_storage_context_.get();
+ }
private:
friend class base::RefCountedThreadSafe<WebKitContext>;
@@ -31,7 +32,6 @@ class WebKitContext : public base::RefCountedThreadSafe<WebKitContext> {
const FilePath data_path_;
const bool is_incognito_;
- // The state for DOM Storage.
scoped_ptr<DOMStorageContext> dom_storage_context_;
DISALLOW_IMPLICIT_CONSTRUCTORS(WebKitContext);
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index 008ba88..1063bfe 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -734,6 +734,14 @@ IPC_BEGIN_MESSAGES(View)
int32 /* the ID of the message we're replying to */,
int64 /* the size of the given DB file */)
+ // Storage events are broadcast to renderer processes.
+ IPC_MESSAGE_CONTROL5(ViewMsg_DOMStorageEvent,
+ string16 /* key */,
+ NullableString16 /* old_value */,
+ NullableString16 /* new_value */,
+ string16 /* origin */,
+ DOMStorageType /* dom_storage_type */)
+
#if defined(IPC_MESSAGE_LOG_ENABLED)
// Tell the renderer process to begin or end IPC message logging.
IPC_MESSAGE_CONTROL1(ViewMsg_SetIPCLoggingEnabled,
diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc
index 60b7391..104d55c 100644
--- a/chrome/renderer/render_thread.cc
+++ b/chrome/renderer/render_thread.cc
@@ -11,8 +11,10 @@
#include "base/command_line.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
+#include "base/nullable_string16.h"
#include "base/shared_memory.h"
#include "base/stats_table.h"
+#include "base/string_util.h"
#include "base/thread_local.h"
#include "chrome/common/appcache/appcache_dispatcher.h"
#include "chrome/common/chrome_switches.h"
@@ -45,6 +47,7 @@
#include "webkit/api/public/WebColor.h"
#include "webkit/api/public/WebCache.h"
#include "webkit/api/public/WebKit.h"
+#include "webkit/api/public/WebStorageEventDispatcher.h"
#include "webkit/api/public/WebString.h"
#include "webkit/extensions/v8/benchmarking_extension.h"
#include "webkit/extensions/v8/gears_extension.h"
@@ -59,6 +62,7 @@
using WebKit::WebCache;
using WebKit::WebString;
+using WebKit::WebStorageEventDispatcher;
namespace {
static const unsigned int kCacheStatsDelayMS = 2000 /* milliseconds */;
@@ -240,6 +244,16 @@ void RenderThread::OnExtensionSetHostPermissions(
ExtensionProcessBindings::SetHostPermissions(extension_url, permissions);
}
+void RenderThread::OnDOMStorageEvent(const string16& key,
+ const NullableString16& old_value, const NullableString16& new_value,
+ const string16& origin, DOMStorageType dom_storage_type) {
+ if (!dom_storage_event_dispatcher_.get()) {
+ dom_storage_event_dispatcher_.reset(WebStorageEventDispatcher::create());
+ }
+ dom_storage_event_dispatcher_->dispatchStorageEvent(key, old_value, new_value,
+ origin, dom_storage_type == DOM_STORAGE_LOCAL);
+}
+
void RenderThread::OnExtensionSetL10nMessages(
const std::string& extension_id,
const std::map<std::string, std::string>& l10n_messages) {
@@ -281,6 +295,8 @@ void RenderThread::OnControlMessageReceived(const IPC::Message& msg) {
OnExtensionSetAPIPermissions)
IPC_MESSAGE_HANDLER(ViewMsg_Extension_SetHostPermissions,
OnExtensionSetHostPermissions)
+ IPC_MESSAGE_HANDLER(ViewMsg_DOMStorageEvent,
+ OnDOMStorageEvent)
IPC_MESSAGE_HANDLER(ViewMsg_Extension_SetL10nMessages,
OnExtensionSetL10nMessages)
#if defined(IPC_MESSAGE_LOG_ENABLED)
diff --git a/chrome/renderer/render_thread.h b/chrome/renderer/render_thread.h
index 5be1585..89f2c05 100644
--- a/chrome/renderer/render_thread.h
+++ b/chrome/renderer/render_thread.h
@@ -14,6 +14,7 @@
#include "build/build_config.h"
#include "chrome/common/child_thread.h"
#include "chrome/common/css_colors.h"
+#include "chrome/common/dom_storage_type.h"
#include "chrome/renderer/renderer_histogram_snapshots.h"
#include "chrome/renderer/visitedlink_slave.h"
@@ -22,6 +23,7 @@ class DBMessageFilter;
class DevToolsAgentFilter;
class FilePath;
class ListValue;
+class NullableString16;
class RenderDnsMaster;
class RendererHistogram;
class RendererWebKitClientImpl;
@@ -32,6 +34,10 @@ class URLPattern;
struct RendererPreferences;
struct WebPreferences;
+namespace WebKit {
+class WebStorageEventDispatcher;
+}
+
// The RenderThreadBase is the minimal interface that a RenderView/Widget
// expects from a render thread. The interface basically abstracts a way to send
// and receive messages.
@@ -138,7 +144,10 @@ class RenderThread : public RenderThreadBase,
void OnUpdateUserScripts(base::SharedMemoryHandle table);
void OnSetExtensionFunctionNames(const std::vector<std::string>& names);
void OnPageActionsUpdated(const std::string& extension_id,
- const std::vector<std::string>& page_actions);
+ const std::vector<std::string>& page_actions);
+ void OnDOMStorageEvent(const string16& key, const NullableString16& old_value,
+ const NullableString16& new_value, const string16& origin,
+ DOMStorageType dom_storage_type);
void OnExtensionSetAPIPermissions(
const std::string& extension_id,
const std::vector<std::string>& permissions);
@@ -187,6 +196,7 @@ class RenderThread : public RenderThreadBase,
scoped_refptr<DevToolsAgentFilter> devtools_agent_filter_;
scoped_ptr<RendererHistogramSnapshots> histogram_snapshots_;
scoped_ptr<RendererWebKitClientImpl> webkit_client_;
+ scoped_ptr<WebKit::WebStorageEventDispatcher> dom_storage_event_dispatcher_;
scoped_refptr<DBMessageFilter> db_message_filter_;
diff --git a/chrome/renderer/renderer_webstoragenamespace_impl.cc b/chrome/renderer/renderer_webstoragenamespace_impl.cc
index c63d6da..41a8c6c 100644
--- a/chrome/renderer/renderer_webstoragenamespace_impl.cc
+++ b/chrome/renderer/renderer_webstoragenamespace_impl.cc
@@ -8,6 +8,10 @@
#include "chrome/renderer/render_thread.h"
#include "chrome/renderer/renderer_webstoragearea_impl.h"
+using WebKit::WebStorageArea;
+using WebKit::WebStorageNamespace;
+using WebKit::WebString;
+
RendererWebStorageNamespaceImpl::RendererWebStorageNamespaceImpl(
DOMStorageType storage_type)
: storage_type_(storage_type),
@@ -24,8 +28,8 @@ RendererWebStorageNamespaceImpl::RendererWebStorageNamespaceImpl(
RendererWebStorageNamespaceImpl::~RendererWebStorageNamespaceImpl() {
}
-WebKit::WebStorageArea* RendererWebStorageNamespaceImpl::createStorageArea(
- const WebKit::WebString& origin) {
+WebStorageArea* RendererWebStorageNamespaceImpl::createStorageArea(
+ const WebString& origin) {
// This could be done async in the background (started when this class is
// first instantiated) rather than lazily on first use, but it's unclear
// whether it's worth the complexity.
@@ -42,12 +46,12 @@ WebKit::WebStorageArea* RendererWebStorageNamespaceImpl::createStorageArea(
return new RendererWebStorageAreaImpl(namespace_id_, origin);
}
-WebKit::WebStorageNamespace* RendererWebStorageNamespaceImpl::copy() {
+WebStorageNamespace* RendererWebStorageNamespaceImpl::copy() {
// If we haven't been used yet, we might as well start out fresh (and lazy).
if (namespace_id_ == kUninitializedNamespaceId)
return new RendererWebStorageNamespaceImpl(storage_type_);
- // This cannot easily be differed because we need a snapshot in time.
+ // This cannot easily be deferred because we need a snapshot in time.
int64 new_namespace_id;
RenderThread::current()->Send(
new ViewHostMsg_DOMStorageCloneNamespaceId(namespace_id_,
diff --git a/webkit/api/public/WebKitClient.h b/webkit/api/public/WebKitClient.h
index b95dc1f..b695bba 100644
--- a/webkit/api/public/WebKitClient.h
+++ b/webkit/api/public/WebKitClient.h
@@ -85,12 +85,16 @@ namespace WebKit {
// Return a LocalStorage namespace that corresponds to the following
// path.
- virtual WebStorageNamespace* createLocalStorageNamespace(
- const WebString& path) = 0;
+ virtual WebStorageNamespace* createLocalStorageNamespace(const WebString& path) = 0;
// Return a new SessionStorage namespace.
virtual WebStorageNamespace* createSessionStorageNamespace() = 0;
+ // Called when storage events fire.
+ virtual void dispatchStorageEvent(const WebString& key, const WebString& oldValue,
+ const WebString& newValue, const WebString& origin,
+ bool isLocalStorage) = 0;
+
// File ----------------------------------------------------------------
diff --git a/webkit/api/public/WebStorageEventDispatcher.h b/webkit/api/public/WebStorageEventDispatcher.h
new file mode 100644
index 0000000..88d0ea9
--- /dev/null
+++ b/webkit/api/public/WebStorageEventDispatcher.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebStorageEventDispatcher_h
+#define WebStorageEventDispatcher_h
+
+#include "WebString.h"
+
+namespace WebKit {
+
+ // This is used to dispatch storage events to all pages.
+ // FIXME: Make this (or something) work for SessionStorage!
+ class WebStorageEventDispatcher {
+ public:
+ static WebStorageEventDispatcher* create();
+
+ virtual ~WebStorageEventDispatcher() { }
+
+ // Dispatch the actual event. Doesn't yet work for SessionStorage.
+ virtual void dispatchStorageEvent(const WebString& key, const WebString& oldValue,
+ const WebString& newValue, const WebString& origin,
+ bool isLocalStorage) = 0;
+ };
+
+} // namespace WebKit
+
+#endif // WebStorageEventDispatcher_h
diff --git a/webkit/api/src/StorageEventDispatcherChromium.cpp b/webkit/api/src/StorageEventDispatcherChromium.cpp
index 8f0c61c..9c283cd 100644
--- a/webkit/api/src/StorageEventDispatcherChromium.cpp
+++ b/webkit/api/src/StorageEventDispatcherChromium.cpp
@@ -46,7 +46,8 @@ void StorageEventDispatcher::dispatch(const String& key, const String& oldValue,
const String& newValue, StorageType storageType,
SecurityOrigin* origin, Frame* sourceFrame)
{
- // FIXME: Implement.
+ ASSERT(!sourceFrame); // Sad, but true.
+ WebKit::webKitClient()->dispatchStorageEvent(key, oldValue, newValue, origin->toString(), storageType == LocalStorage);
}
} // namespace WebCore
diff --git a/webkit/api/src/StorageEventDispatcherImpl.cpp b/webkit/api/src/StorageEventDispatcherImpl.cpp
new file mode 100644
index 0000000..6916e0b
--- /dev/null
+++ b/webkit/api/src/StorageEventDispatcherImpl.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "StorageEventDispatcherImpl.h"
+
+#if ENABLE(DOM_STORAGE)
+
+#include "DOMWindow.h"
+#include "EventNames.h"
+#include "Frame.h"
+#include "Page.h"
+#include "PageGroup.h"
+#include "SecurityOrigin.h"
+#include "StorageEvent.h"
+
+namespace WebCore {
+
+StorageEventDispatcherImpl::StorageEventDispatcherImpl(const String& groupName)
+ : m_pageGroup(PageGroup::pageGroup(groupName))
+{
+ ASSERT(m_pageGroup);
+}
+
+void StorageEventDispatcherImpl::dispatchStorageEvent(const String& key, const String& oldValue,
+ const String& newValue, StorageType storageType,
+ SecurityOrigin* securityOrigin)
+{
+ // FIXME: Implement
+ if (storageType == SessionStorage)
+ return;
+
+ // We need to copy all relevant frames from every page to a vector since sending the event to one frame might mutate the frame tree
+ // of any given page in the group or mutate the page group itself.
+ Vector<RefPtr<Frame> > frames;
+
+ const HashSet<Page*>& pages = m_pageGroup->pages();
+ HashSet<Page*>::const_iterator end = pages.end();
+ for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) {
+ for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
+ if (frame->document()->securityOrigin()->equal(securityOrigin))
+ frames.append(frame);
+ }
+ }
+
+ // FIXME: Figure out how to pass in the document URI.
+ for (unsigned i = 0; i < frames.size(); ++i) {
+ frames[i]->document()->dispatchWindowEvent(StorageEvent::create(eventNames().storageEvent, key,oldValue, newValue,
+ String(), 0, frames[i]->domWindow()->localStorage()));
+ }
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(DOM_STORAGE)
diff --git a/webkit/api/src/StorageEventDispatcherImpl.h b/webkit/api/src/StorageEventDispatcherImpl.h
new file mode 100644
index 0000000..e0f57e2
--- /dev/null
+++ b/webkit/api/src/StorageEventDispatcherImpl.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef StorageEventDispatcherImpl_h
+#define StorageEventDispatcherImpl_h
+
+#if ENABLE(DOM_STORAGE)
+
+#include "PlatformString.h"
+#include "StorageArea.h"
+
+namespace WebCore {
+
+ class PageGroup;
+ class SecurityOrigin;
+
+ class StorageEventDispatcherImpl {
+ public:
+ StorageEventDispatcherImpl(const String& groupName);
+
+ void dispatchStorageEvent(const String& key, const String& oldValue,
+ const String& newValue, StorageType,
+ SecurityOrigin*);
+
+ private:
+ PageGroup* m_pageGroup;
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(DOM_STORAGE)
+
+#endif // StorageEventDispatcherImpl_h
diff --git a/webkit/api/src/WebStorageEventDispatcherImpl.cpp b/webkit/api/src/WebStorageEventDispatcherImpl.cpp
new file mode 100644
index 0000000..a6da503
--- /dev/null
+++ b/webkit/api/src/WebStorageEventDispatcherImpl.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebStorageEventDispatcherImpl.h"
+
+#if ENABLE(DOM_STORAGE)
+
+#include "SecurityOrigin.h"
+
+extern const char* pageGroupName;
+
+namespace WebKit {
+
+WebStorageEventDispatcher* WebStorageEventDispatcher::create()
+{
+ return new WebStorageEventDispatcherImpl();
+}
+
+WebStorageEventDispatcherImpl::WebStorageEventDispatcherImpl()
+ : m_eventDispatcher(new WebCore::StorageEventDispatcherImpl(pageGroupName))
+{
+ ASSERT(m_eventDispatcher);
+}
+
+void WebStorageEventDispatcherImpl::dispatchStorageEvent(const WebString& key, const WebString& oldValue,
+ const WebString& newValue, const WebString& origin,
+ bool isLocalStorage)
+{
+ WebCore::StorageType storageType = isLocalStorage ? WebCore::LocalStorage : WebCore::SessionStorage;
+ RefPtr<WebCore::SecurityOrigin> securityOrigin = WebCore::SecurityOrigin::createFromString(origin);
+ m_eventDispatcher->dispatchStorageEvent(key, oldValue, newValue, storageType, securityOrigin.get());
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(DOM_STORAGE)
diff --git a/webkit/api/src/WebStorageEventDispatcherImpl.h b/webkit/api/src/WebStorageEventDispatcherImpl.h
new file mode 100644
index 0000000..464c4f3
--- /dev/null
+++ b/webkit/api/src/WebStorageEventDispatcherImpl.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebStorageEventDispatcherImpl_h
+#define WebStorageEventDispatcherImpl_h
+
+#if ENABLE(DOM_STORAGE)
+
+#include "StorageEventDispatcherImpl.h"
+#include <wtf/OwnPtr.h>
+
+#include "WebStorageEventDispatcher.h"
+
+namespace WebKit {
+
+ class WebStorageEventDispatcherImpl : public WebStorageEventDispatcher {
+ public:
+ WebStorageEventDispatcherImpl();
+
+ virtual void dispatchStorageEvent(const WebString& key, const WebString& oldValue,
+ const WebString& newValue, const WebString& origin,
+ bool isLocalStorage);
+
+ private:
+ OwnPtr<WebCore::StorageEventDispatcherImpl> m_eventDispatcher;
+ };
+
+} // namespace WebKit
+
+#endif // ENABLE(DOM_STORAGE)
+
+#endif // WebStorageEventDispatcherImpl_h
diff --git a/webkit/glue/webkitclient_impl.cc b/webkit/glue/webkitclient_impl.cc
index 34c7ba5..1db4975 100644
--- a/webkit/glue/webkitclient_impl.cc
+++ b/webkit/glue/webkitclient_impl.cc
@@ -283,6 +283,12 @@ void WebKitClientImpl::callOnMainThread(void (*func)()) {
main_loop_->PostTask(FROM_HERE, NewRunnableFunction(func));
}
+void WebKitClientImpl::dispatchStorageEvent(const WebString& key,
+ const WebString& oldValue, const WebString& newValue,
+ const WebString& origin, bool isLocalStorage) {
+ NOTREACHED();
+}
+
base::PlatformFile WebKitClientImpl::databaseOpenFile(
const WebKit::WebString& file_name, int desired_flags,
base::PlatformFile* dir_handle) {
diff --git a/webkit/glue/webkitclient_impl.h b/webkit/glue/webkitclient_impl.h
index ba25918..16b1142 100644
--- a/webkit/glue/webkitclient_impl.h
+++ b/webkit/glue/webkitclient_impl.h
@@ -39,6 +39,9 @@ class WebKitClientImpl : public WebKit::WebKitClient {
virtual void stopSharedTimer();
virtual void callOnMainThread(void (*func)());
virtual void suddenTerminationChanged(bool enabled) { }
+ virtual void dispatchStorageEvent(const WebKit::WebString& key,
+ const WebKit::WebString& oldValue, const WebKit::WebString& newValue,
+ const WebKit::WebString& origin, bool isLocalStorage);
virtual base::PlatformFile databaseOpenFile(
const WebKit::WebString& file_name, int desired_flags,
diff --git a/webkit/glue/webview_impl.cc b/webkit/glue/webview_impl.cc
index 86cca15..df6e49a 100644
--- a/webkit/glue/webview_impl.cc
+++ b/webkit/glue/webview_impl.cc
@@ -131,7 +131,9 @@ static const double kMaxTextSizeMultiplier = 3.0;
// for some programs that use HTML views to display things that don't seem like
// web pages to the user (so shouldn't have visited link coloring). We only use
// one page group.
-static const char* kPageGroupName = "default";
+// FIXME: This needs to go into the WebKit API implementation and be hidden
+// from the API's users.
+const char* pageGroupName = "default";
// Ensure that the WebKit::WebDragOperation enum values stay in sync with
// the original WebCore::DragOperation constants.
@@ -361,13 +363,13 @@ void WebViewImpl::InitializeMainFrame(WebFrameClient* frame_client) {
// static
void WebView::UpdateVisitedLinkState(uint64 link_hash) {
WebCore::Page::visitedStateChanged(
- WebCore::PageGroup::pageGroup(kPageGroupName), link_hash);
+ WebCore::PageGroup::pageGroup(pageGroupName), link_hash);
}
// static
void WebView::ResetVisitedLinkState() {
WebCore::Page::allVisitedStateChanged(
- WebCore::PageGroup::pageGroup(kPageGroupName));
+ WebCore::PageGroup::pageGroup(pageGroupName));
}
@@ -414,7 +416,7 @@ WebViewImpl::WebViewImpl(WebViewDelegate* delegate)
NULL));
page_->backForwardList()->setClient(&back_forward_list_client_impl_);
- page_->setGroupName(kPageGroupName);
+ page_->setGroupName(pageGroupName);
}
WebViewImpl::~WebViewImpl() {
diff --git a/webkit/webkit.gyp b/webkit/webkit.gyp
index a2b8622..db8a9eb 100644
--- a/webkit/webkit.gyp
+++ b/webkit/webkit.gyp
@@ -107,6 +107,7 @@
'api/public/WebSettings.h',
'api/public/WebSize.h',
'api/public/WebStorageArea.h',
+ 'api/public/WebStorageEventDispatcher.h',
'api/public/WebStorageNamespace.h',
'api/public/WebString.h',
'api/public/WebTextAffinity.h',
@@ -150,6 +151,8 @@
'api/src/StorageAreaProxy.cpp',
'api/src/StorageAreaProxy.h',
'api/src/StorageEventDispatcherChromium.cpp',
+ 'api/src/StorageEventDispatcherImpl.cpp',
+ 'api/src/StorageEventDispatcherImpl.h',
'api/src/StorageNamespaceProxy.cpp',
'api/src/StorageNamespaceProxy.h',
'api/src/TemporaryGlue.h',
@@ -187,6 +190,8 @@
'api/src/WebSettingsImpl.h',
'api/src/WebStorageAreaImpl.cpp',
'api/src/WebStorageAreaImpl.h',
+ 'api/src/WebStorageEventDispatcherImpl.cpp',
+ 'api/src/WebStorageEventDispatcherImpl.h',
'api/src/WebStorageNamespaceImpl.cpp',
'api/src/WebStorageNamespaceImpl.h',
'api/src/WebString.cpp',