- Persist localStorage data across sessions when a cache path is specified (issue #139).
- Add a localStorage test to cefclient. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@140 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
6ad535823a
commit
3dd54c536c
11
cef.gyp
11
cef.gyp
|
@ -493,6 +493,10 @@
|
|||
'libcef/browser_webcookiejar_impl.h',
|
||||
'libcef/browser_webblobregistry_impl.cc',
|
||||
'libcef/browser_webblobregistry_impl.h',
|
||||
'libcef/browser_webstoragearea_impl.cc',
|
||||
'libcef/browser_webstoragearea_impl.h',
|
||||
'libcef/browser_webstoragenamespace_impl.cc',
|
||||
'libcef/browser_webstoragenamespace_impl.h',
|
||||
'libcef/browser_webkit_glue.cc',
|
||||
'libcef/browser_webkit_glue.h',
|
||||
'libcef/browser_webkit_init.h',
|
||||
|
@ -513,6 +517,13 @@
|
|||
'libcef/cef_string_map.cc',
|
||||
'libcef/cef_thread.cc',
|
||||
'libcef/cef_thread.h',
|
||||
'libcef/dom_storage_area.cc',
|
||||
'libcef/dom_storage_area.h',
|
||||
'libcef/dom_storage_common.h',
|
||||
'libcef/dom_storage_context.cc',
|
||||
'libcef/dom_storage_context.h',
|
||||
'libcef/dom_storage_namespace.cc',
|
||||
'libcef/dom_storage_namespace.h',
|
||||
'libcef/request_impl.cc',
|
||||
'libcef/request_impl.h',
|
||||
'libcef/scheme_impl.cc',
|
||||
|
|
|
@ -187,6 +187,10 @@ FilePath BrowserDatabaseSystem::GetFullFilePathForVfsFile(
|
|||
return FilePath();
|
||||
|
||||
AutoLock file_names_auto_lock(file_names_lock_);
|
||||
DCHECK(file_names_.find(vfs_file_name) != file_names_.end());
|
||||
return file_names_[vfs_file_name];
|
||||
if(file_names_.find(vfs_file_name) != file_names_.end())
|
||||
return file_names_[vfs_file_name];
|
||||
|
||||
// This method is getting called when an empty localStorage database is
|
||||
// deleted. In that case, just return the path.
|
||||
return FilePath(vfs_file_name);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,14 @@
|
|||
#ifndef _BROWSER_WEBKIT_INIT_H
|
||||
#define _BROWSER_WEBKIT_INIT_H
|
||||
|
||||
#include "browser_appcache_system.h"
|
||||
#include "browser_database_system.h"
|
||||
#include "browser_file_system.h"
|
||||
#include "browser_resource_loader_bridge.h"
|
||||
#include "browser_webblobregistry_impl.h"
|
||||
#include "browser_webcookiejar_impl.h"
|
||||
#include "browser_webstoragenamespace_impl.h"
|
||||
|
||||
#include "base/file_util.h"
|
||||
#include "base/metrics/stats_counters.h"
|
||||
#include "base/path_service.h"
|
||||
|
@ -35,12 +43,6 @@
|
|||
#include "webkit/glue/webfileutilities_impl.h"
|
||||
#include "webkit/glue/webkit_glue.h"
|
||||
#include "webkit/glue/webkitclient_impl.h"
|
||||
#include "browser_appcache_system.h"
|
||||
#include "browser_database_system.h"
|
||||
#include "browser_file_system.h"
|
||||
#include "browser_resource_loader_bridge.h"
|
||||
#include "browser_webblobregistry_impl.h"
|
||||
#include "browser_webcookiejar_impl.h"
|
||||
|
||||
|
||||
class BrowserWebKitInit : public webkit_glue::WebKitClientImpl {
|
||||
|
@ -193,6 +195,12 @@ class BrowserWebKitInit : public webkit_glue::WebKitClientImpl {
|
|||
|
||||
virtual WebKit::WebStorageNamespace* createLocalStorageNamespace(
|
||||
const WebKit::WebString& path, unsigned quota) {
|
||||
if (BrowserWebStorageNamespaceImpl::IsStorageActive()) {
|
||||
// Use the localStorage implementation that writes data to disk.
|
||||
return new BrowserWebStorageNamespaceImpl(DOM_STORAGE_LOCAL);
|
||||
}
|
||||
|
||||
// Use the default localStorage implementation.
|
||||
return WebKit::WebStorageNamespace::createLocalStorageNamespace(path,
|
||||
WebKit::WebStorageNamespace::m_localStorageQuota);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
// Copyright (c) 2010 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that can
|
||||
// be found in the LICENSE file.
|
||||
|
||||
#include "browser_webstoragearea_impl.h"
|
||||
#include "cef_context.h"
|
||||
#include "dom_storage_area.h"
|
||||
#include "dom_storage_namespace.h"
|
||||
|
||||
#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
|
||||
#include "third_party/WebKit/WebKit/chromium/public/WebURL.h"
|
||||
#include "third_party/WebKit/WebKit/chromium/public/WebView.h"
|
||||
|
||||
using WebKit::WebFrame;
|
||||
using WebKit::WebString;
|
||||
using WebKit::WebURL;
|
||||
using WebKit::WebView;
|
||||
|
||||
BrowserWebStorageAreaImpl::BrowserWebStorageAreaImpl(
|
||||
int64 namespace_id, const WebString& origin) {
|
||||
area_ = _Context->storage_context()->GetStorageNamespace(namespace_id, true)->
|
||||
GetStorageArea(origin);
|
||||
DCHECK(area_ != NULL);
|
||||
}
|
||||
|
||||
BrowserWebStorageAreaImpl::~BrowserWebStorageAreaImpl() {
|
||||
}
|
||||
|
||||
unsigned BrowserWebStorageAreaImpl::length() {
|
||||
return area_->Length();
|
||||
}
|
||||
|
||||
WebString BrowserWebStorageAreaImpl::key(unsigned index) {
|
||||
return area_->Key(index);
|
||||
}
|
||||
|
||||
WebString BrowserWebStorageAreaImpl::getItem(const WebString& key) {
|
||||
return area_->GetItem(key);
|
||||
}
|
||||
|
||||
void BrowserWebStorageAreaImpl::setItem(
|
||||
const WebString& key, const WebString& value, const WebURL& url,
|
||||
WebStorageArea::Result& result, WebString& old_value_webkit,
|
||||
WebFrame* web_frame) {
|
||||
old_value_webkit = area_->SetItem(key, value, &result);
|
||||
}
|
||||
|
||||
void BrowserWebStorageAreaImpl::removeItem(
|
||||
const WebString& key, const WebURL& url, WebString& old_value_webkit) {
|
||||
old_value_webkit = area_->RemoveItem(key);
|
||||
}
|
||||
|
||||
void BrowserWebStorageAreaImpl::clear(
|
||||
const WebURL& url, bool& cleared_something) {
|
||||
cleared_something = area_->Clear();
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
// Copyright (c) 2010 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that can
|
||||
// be found in the LICENSE file.
|
||||
|
||||
#ifndef _BROWSER_WEBSTORAGEAREA_IMPL_H
|
||||
#define _BROWSER_WEBSTORAGEAREA_IMPL_H
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "third_party/WebKit/WebKit/chromium/public/WebStorageArea.h"
|
||||
#include "third_party/WebKit/WebKit/chromium/public/WebString.h"
|
||||
|
||||
class DOMStorageArea;
|
||||
|
||||
class BrowserWebStorageAreaImpl : public WebKit::WebStorageArea {
|
||||
public:
|
||||
BrowserWebStorageAreaImpl(int64 namespace_id, const WebKit::WebString& origin);
|
||||
virtual ~BrowserWebStorageAreaImpl();
|
||||
|
||||
// See WebStorageArea.h for documentation on these functions.
|
||||
virtual unsigned length();
|
||||
virtual WebKit::WebString key(unsigned index);
|
||||
virtual WebKit::WebString getItem(const WebKit::WebString& key);
|
||||
virtual void setItem(
|
||||
const WebKit::WebString& key, const WebKit::WebString& value,
|
||||
const WebKit::WebURL& url, WebStorageArea::Result& result,
|
||||
WebKit::WebString& old_value, WebKit::WebFrame* web_view);
|
||||
virtual void removeItem(
|
||||
const WebKit::WebString& key, const WebKit::WebURL& url,
|
||||
WebKit::WebString& old_value);
|
||||
virtual void clear(const WebKit::WebURL& url, bool& cleared_something);
|
||||
|
||||
private:
|
||||
// The object is owned by DOMStorageNamespace.
|
||||
DOMStorageArea* area_;
|
||||
};
|
||||
|
||||
#endif // _BROWSER_WEBSTORAGEAREA_IMPL_H
|
|
@ -0,0 +1,57 @@
|
|||
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "browser_webstoragenamespace_impl.h"
|
||||
#include "browser_webstoragearea_impl.h"
|
||||
#include "cef_context.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
|
||||
using WebKit::WebStorageArea;
|
||||
using WebKit::WebStorageNamespace;
|
||||
using WebKit::WebString;
|
||||
|
||||
BrowserWebStorageNamespaceImpl::BrowserWebStorageNamespaceImpl(
|
||||
DOMStorageType storage_type)
|
||||
: storage_type_(storage_type),
|
||||
namespace_id_(kLocalStorageNamespaceId) {
|
||||
DCHECK(storage_type == DOM_STORAGE_LOCAL);
|
||||
}
|
||||
|
||||
BrowserWebStorageNamespaceImpl::BrowserWebStorageNamespaceImpl(
|
||||
DOMStorageType storage_type, int64 namespace_id)
|
||||
: storage_type_(storage_type),
|
||||
namespace_id_(namespace_id) {
|
||||
DCHECK(storage_type == DOM_STORAGE_SESSION);
|
||||
}
|
||||
|
||||
BrowserWebStorageNamespaceImpl::~BrowserWebStorageNamespaceImpl() {
|
||||
}
|
||||
|
||||
WebStorageArea* BrowserWebStorageNamespaceImpl::createStorageArea(
|
||||
const WebString& origin) {
|
||||
// Ideally, we'd keep a hash map of origin to these objects. Unfortunately
|
||||
// this doesn't seem practical because there's no good way to ref-count these
|
||||
// objects, and it'd be unclear who owned them. So, instead, we'll pay the
|
||||
// price in terms of wasted memory.
|
||||
return new BrowserWebStorageAreaImpl(namespace_id_, origin);
|
||||
}
|
||||
|
||||
WebStorageNamespace* BrowserWebStorageNamespaceImpl::copy() {
|
||||
// By returning NULL, we're telling WebKit to lazily fetch it the next time
|
||||
// session storage is used. In the WebViewClient::createView, we do the
|
||||
// book-keeping necessary to make it a true copy-on-write despite not doing
|
||||
// anything here, now.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void BrowserWebStorageNamespaceImpl::close() {
|
||||
// This is called only on LocalStorage namespaces when WebKit thinks its
|
||||
// shutting down. This has no impact on Chromium.
|
||||
}
|
||||
|
||||
//static
|
||||
bool BrowserWebStorageNamespaceImpl::IsStorageActive() {
|
||||
return (_Context->storage_context() != NULL);
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef _BROWSER_WEBSTORAGENAMESPACE_IMPL_H
|
||||
#define _BROWSER_WEBSTORAGENAMESPACE_IMPL_H
|
||||
|
||||
#include "dom_storage_common.h"
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "third_party/WebKit/WebKit/chromium/public/WebStorageNamespace.h"
|
||||
|
||||
class BrowserWebStorageNamespaceImpl : public WebKit::WebStorageNamespace {
|
||||
public:
|
||||
explicit BrowserWebStorageNamespaceImpl(DOMStorageType storage_type);
|
||||
BrowserWebStorageNamespaceImpl(DOMStorageType storage_type,
|
||||
int64 namespace_id);
|
||||
|
||||
// See WebStorageNamespace.h for documentation on these functions.
|
||||
virtual ~BrowserWebStorageNamespaceImpl();
|
||||
virtual WebKit::WebStorageArea* createStorageArea(
|
||||
const WebKit::WebString& origin);
|
||||
virtual WebKit::WebStorageNamespace* copy();
|
||||
virtual void close();
|
||||
|
||||
// Returns true if storage data is being cached to disk.
|
||||
static bool IsStorageActive();
|
||||
|
||||
private:
|
||||
// Used during lazy initialization of namespace_id_.
|
||||
const DOMStorageType storage_type_;
|
||||
|
||||
// Our namespace ID.
|
||||
int64 namespace_id_;
|
||||
};
|
||||
|
||||
#endif // _BROWSER_WEBSTORAGENAMESPACE_IMPL_H
|
|
@ -198,7 +198,9 @@ WebWidget* BrowserWebViewDelegate::createPopupMenu(WebPopupType popup_type) {
|
|||
|
||||
WebStorageNamespace* BrowserWebViewDelegate::createSessionStorageNamespace(
|
||||
unsigned quota) {
|
||||
// Enforce quota, ignoring the parameter from WebCore as in Chrome.
|
||||
// Enforce quota, ignoring the parameter from WebCore as in Chrome. We could
|
||||
// potentially use DOMStorageContext to manage session storage but there's
|
||||
// currently no need since session storage data is not written to disk.
|
||||
return WebKit::WebStorageNamespace::createSessionStorageNamespace(
|
||||
WebStorageNamespace::m_sessionStorageQuota);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "browser_request_context.h"
|
||||
#include "cef_process.h"
|
||||
#include "cef_thread.h"
|
||||
#include "dom_storage_context.h"
|
||||
|
||||
#include "base/at_exit.h"
|
||||
#include "base/file_path.h"
|
||||
|
@ -56,6 +57,11 @@ public:
|
|||
scoped_refptr<BrowserRequestContext> request_context()
|
||||
{ return request_context_; }
|
||||
|
||||
// The DOMStorageContext object is managed by CefProcessUIThread.
|
||||
void set_storage_context(DOMStorageContext* storage_context)
|
||||
{ storage_context_.reset(storage_context); }
|
||||
DOMStorageContext* storage_context() { return storage_context_.get(); }
|
||||
|
||||
private:
|
||||
// Manages the various process threads.
|
||||
scoped_refptr<CefProcess> process_;
|
||||
|
@ -67,10 +73,11 @@ private:
|
|||
std::wstring cache_path_;
|
||||
WebPreferences* webprefs_;
|
||||
scoped_refptr<BrowserRequestContext> request_context_;
|
||||
|
||||
scoped_ptr<DOMStorageContext> storage_context_;
|
||||
|
||||
// Map of browsers that currently exist.
|
||||
BrowserList browserlist_;
|
||||
|
||||
|
||||
// Used for assigning unique IDs to browser instances.
|
||||
int next_browser_id_;
|
||||
};
|
||||
|
|
|
@ -116,6 +116,11 @@ void CefProcessUIThread::Init() {
|
|||
gfx::InitializeGLBindings(gfx::kGLImplementationDesktopGL);
|
||||
|
||||
URLRequest::RegisterProtocolFactory("blob", &BlobURLRequestJobFactory);
|
||||
|
||||
if(!_Context->cache_path().empty()) {
|
||||
// Create the storage context object.
|
||||
_Context->set_storage_context(new DOMStorageContext());
|
||||
}
|
||||
}
|
||||
|
||||
void CefProcessUIThread::CleanUp() {
|
||||
|
@ -124,6 +129,9 @@ void CefProcessUIThread::CleanUp() {
|
|||
// purify leak-test results.
|
||||
MessageLoop::current()->RunAllPending();
|
||||
|
||||
// Destroy the storage context object.
|
||||
_Context->set_storage_context(NULL);
|
||||
|
||||
// Tear down the shared StatsTable.
|
||||
base::StatsTable::set_current(NULL);
|
||||
delete statstable_;
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "dom_storage_area.h"
|
||||
#include "dom_storage_context.h"
|
||||
#include "dom_storage_namespace.h"
|
||||
|
||||
#include "base/task.h"
|
||||
#include "third_party/WebKit/WebKit/chromium/public/WebSecurityOrigin.h"
|
||||
#include "third_party/WebKit/WebKit/chromium/public/WebStorageArea.h"
|
||||
#include "third_party/WebKit/WebKit/chromium/public/WebString.h"
|
||||
#include "third_party/WebKit/WebKit/chromium/public/WebURL.h"
|
||||
#include "webkit/glue/webkit_glue.h"
|
||||
|
||||
using WebKit::WebSecurityOrigin;
|
||||
using WebKit::WebStorageArea;
|
||||
using WebKit::WebString;
|
||||
using WebKit::WebURL;
|
||||
|
||||
DOMStorageArea::DOMStorageArea(
|
||||
const string16& origin,
|
||||
int64 id,
|
||||
DOMStorageNamespace* owner)
|
||||
: origin_(origin),
|
||||
origin_url_(origin),
|
||||
id_(id),
|
||||
owner_(owner) {
|
||||
DCHECK(owner_);
|
||||
}
|
||||
|
||||
DOMStorageArea::~DOMStorageArea() {
|
||||
}
|
||||
|
||||
unsigned DOMStorageArea::Length() {
|
||||
CreateWebStorageAreaIfNecessary();
|
||||
return storage_area_->length();
|
||||
}
|
||||
|
||||
NullableString16 DOMStorageArea::Key(unsigned index) {
|
||||
CreateWebStorageAreaIfNecessary();
|
||||
return storage_area_->key(index);
|
||||
}
|
||||
|
||||
NullableString16 DOMStorageArea::GetItem(const string16& key) {
|
||||
CreateWebStorageAreaIfNecessary();
|
||||
return storage_area_->getItem(key);
|
||||
}
|
||||
|
||||
NullableString16 DOMStorageArea::SetItem(
|
||||
const string16& key, const string16& value,
|
||||
WebStorageArea::Result* result) {
|
||||
if (!CheckContentSetting(key, value)) {
|
||||
*result = WebStorageArea::ResultBlockedByPolicy;
|
||||
return NullableString16(true); // Ignored if the content was blocked.
|
||||
}
|
||||
|
||||
CreateWebStorageAreaIfNecessary();
|
||||
WebString old_value;
|
||||
storage_area_->setItem(key, value, WebURL(), *result, old_value);
|
||||
return old_value;
|
||||
}
|
||||
|
||||
NullableString16 DOMStorageArea::RemoveItem(const string16& key) {
|
||||
CreateWebStorageAreaIfNecessary();
|
||||
WebString old_value;
|
||||
storage_area_->removeItem(key, WebURL(), old_value);
|
||||
return old_value;
|
||||
}
|
||||
|
||||
bool DOMStorageArea::Clear() {
|
||||
CreateWebStorageAreaIfNecessary();
|
||||
bool somethingCleared;
|
||||
storage_area_->clear(WebURL(), somethingCleared);
|
||||
return somethingCleared;
|
||||
}
|
||||
|
||||
void DOMStorageArea::PurgeMemory() {
|
||||
storage_area_.reset();
|
||||
}
|
||||
|
||||
void DOMStorageArea::CreateWebStorageAreaIfNecessary() {
|
||||
if (!storage_area_.get())
|
||||
storage_area_.reset(owner_->CreateWebStorageArea(origin_));
|
||||
}
|
||||
|
||||
bool DOMStorageArea::CheckContentSetting(
|
||||
const string16& key, const string16& value) {
|
||||
// TODO(cef): Potentially give the host an option to deny write access.
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef _DOM_STORAGE_AREA_H
|
||||
#define _DOM_STORAGE_AREA_H
|
||||
|
||||
#include "base/hash_tables.h"
|
||||
#include "base/nullable_string16.h"
|
||||
#include "base/ref_counted.h"
|
||||
#include "base/scoped_ptr.h"
|
||||
#include "base/string16.h"
|
||||
#include "googleurl/src/gurl.h"
|
||||
#include "third_party/WebKit/WebKit/chromium/public/WebStorageArea.h"
|
||||
|
||||
class DOMStorageNamespace;
|
||||
|
||||
// Only use on the WebKit thread. DOMStorageNamespace manages our registration
|
||||
// with DOMStorageContext.
|
||||
class DOMStorageArea {
|
||||
public:
|
||||
DOMStorageArea(const string16& origin,
|
||||
int64 id,
|
||||
DOMStorageNamespace* owner);
|
||||
~DOMStorageArea();
|
||||
|
||||
unsigned Length();
|
||||
NullableString16 Key(unsigned index);
|
||||
NullableString16 GetItem(const string16& key);
|
||||
NullableString16 SetItem(
|
||||
const string16& key, const string16& value,
|
||||
WebKit::WebStorageArea::Result* result);
|
||||
NullableString16 RemoveItem(const string16& key);
|
||||
bool Clear();
|
||||
void PurgeMemory();
|
||||
|
||||
int64 id() const { return id_; }
|
||||
|
||||
DOMStorageNamespace* owner() const { return owner_; }
|
||||
|
||||
private:
|
||||
// Creates the underlying WebStorageArea on demand.
|
||||
void CreateWebStorageAreaIfNecessary();
|
||||
|
||||
// Used to see if setItem has permission to do its thing.
|
||||
bool CheckContentSetting(const string16& key, const string16& value);
|
||||
|
||||
// The origin this storage area represents.
|
||||
string16 origin_;
|
||||
GURL origin_url_;
|
||||
|
||||
// The storage area we wrap.
|
||||
scoped_ptr<WebKit::WebStorageArea> storage_area_;
|
||||
|
||||
// Our storage area id. Unique to our parent context.
|
||||
int64 id_;
|
||||
|
||||
// The DOMStorageNamespace that owns us.
|
||||
DOMStorageNamespace* owner_;
|
||||
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(DOMStorageArea);
|
||||
};
|
||||
|
||||
#if defined(COMPILER_GCC)
|
||||
namespace __gnu_cxx {
|
||||
|
||||
template<>
|
||||
struct hash<DOMStorageArea*> {
|
||||
std::size_t operator()(DOMStorageArea* const& p) const {
|
||||
return reinterpret_cast<std::size_t>(p);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace __gnu_cxx
|
||||
#endif
|
||||
|
||||
#endif // _DOM_STORAGE_AREA_H
|
|
@ -0,0 +1,18 @@
|
|||
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef _DOM_STORAGE_COMMON_H
|
||||
#define _DOM_STORAGE_COMMON_H
|
||||
|
||||
#include "base/basictypes.h"
|
||||
|
||||
const int64 kLocalStorageNamespaceId = 0;
|
||||
const int64 kInvalidSessionStorageNamespaceId = kLocalStorageNamespaceId;
|
||||
|
||||
enum DOMStorageType {
|
||||
DOM_STORAGE_LOCAL = 0,
|
||||
DOM_STORAGE_SESSION
|
||||
};
|
||||
|
||||
#endif // _DOM_STORAGE_COMMON_H
|
|
@ -0,0 +1,250 @@
|
|||
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "dom_storage_context.h"
|
||||
#include "cef_context.h"
|
||||
#include "cef_thread.h"
|
||||
#include "dom_storage_namespace.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "base/file_path.h"
|
||||
#include "base/file_util.h"
|
||||
#include "base/string_util.h"
|
||||
#include "dom_storage_area.h"
|
||||
#include "third_party/WebKit/WebKit/chromium/public/WebSecurityOrigin.h"
|
||||
#include "third_party/WebKit/WebKit/chromium/public/WebString.h"
|
||||
#include "webkit/glue/webkit_glue.h"
|
||||
|
||||
const FilePath::CharType DOMStorageContext::kLocalStorageDirectory[] =
|
||||
FILE_PATH_LITERAL("Local Storage");
|
||||
|
||||
const FilePath::CharType DOMStorageContext::kLocalStorageExtension[] =
|
||||
FILE_PATH_LITERAL(".localstorage");
|
||||
|
||||
DOMStorageContext::DOMStorageContext()
|
||||
: last_storage_area_id_(0),
|
||||
last_session_storage_namespace_id_on_ui_thread_(kLocalStorageNamespaceId),
|
||||
last_session_storage_namespace_id_on_io_thread_(kLocalStorageNamespaceId){
|
||||
}
|
||||
|
||||
DOMStorageContext::~DOMStorageContext() {
|
||||
for (StorageNamespaceMap::iterator iter(storage_namespace_map_.begin());
|
||||
iter != storage_namespace_map_.end(); ++iter) {
|
||||
delete iter->second;
|
||||
}
|
||||
}
|
||||
|
||||
int64 DOMStorageContext::AllocateStorageAreaId() {
|
||||
DCHECK(CefThread::CurrentlyOn(CefThread::UI));
|
||||
return ++last_storage_area_id_;
|
||||
}
|
||||
|
||||
int64 DOMStorageContext::AllocateSessionStorageNamespaceId() {
|
||||
if (CefThread::CurrentlyOn(CefThread::UI))
|
||||
return ++last_session_storage_namespace_id_on_ui_thread_;
|
||||
return --last_session_storage_namespace_id_on_io_thread_;
|
||||
}
|
||||
|
||||
int64 DOMStorageContext::CloneSessionStorage(int64 original_id) {
|
||||
DCHECK(!CefThread::CurrentlyOn(CefThread::UI));
|
||||
int64 clone_id = AllocateSessionStorageNamespaceId();
|
||||
CefThread::PostTask(
|
||||
CefThread::UI, FROM_HERE, NewRunnableFunction(
|
||||
&DOMStorageContext::CompleteCloningSessionStorage,
|
||||
this, original_id, clone_id));
|
||||
return clone_id;
|
||||
}
|
||||
|
||||
void DOMStorageContext::RegisterStorageArea(DOMStorageArea* storage_area) {
|
||||
DCHECK(CefThread::CurrentlyOn(CefThread::UI));
|
||||
int64 id = storage_area->id();
|
||||
DCHECK(!GetStorageArea(id));
|
||||
storage_area_map_[id] = storage_area;
|
||||
}
|
||||
|
||||
void DOMStorageContext::UnregisterStorageArea(DOMStorageArea* storage_area) {
|
||||
DCHECK(CefThread::CurrentlyOn(CefThread::UI));
|
||||
int64 id = storage_area->id();
|
||||
DCHECK(GetStorageArea(id));
|
||||
storage_area_map_.erase(id);
|
||||
}
|
||||
|
||||
DOMStorageArea* DOMStorageContext::GetStorageArea(int64 id) {
|
||||
DCHECK(CefThread::CurrentlyOn(CefThread::UI));
|
||||
StorageAreaMap::iterator iter = storage_area_map_.find(id);
|
||||
if (iter == storage_area_map_.end())
|
||||
return NULL;
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
void DOMStorageContext::DeleteSessionStorageNamespace(int64 namespace_id) {
|
||||
DCHECK(CefThread::CurrentlyOn(CefThread::UI));
|
||||
StorageNamespaceMap::iterator iter =
|
||||
storage_namespace_map_.find(namespace_id);
|
||||
if (iter == storage_namespace_map_.end())
|
||||
return;
|
||||
DCHECK(iter->second->dom_storage_type() == DOM_STORAGE_SESSION);
|
||||
delete iter->second;
|
||||
storage_namespace_map_.erase(iter);
|
||||
}
|
||||
|
||||
DOMStorageNamespace* DOMStorageContext::GetStorageNamespace(
|
||||
int64 id, bool allocation_allowed) {
|
||||
DCHECK(CefThread::CurrentlyOn(CefThread::UI));
|
||||
StorageNamespaceMap::iterator iter = storage_namespace_map_.find(id);
|
||||
if (iter != storage_namespace_map_.end())
|
||||
return iter->second;
|
||||
if (!allocation_allowed)
|
||||
return NULL;
|
||||
if (id == kLocalStorageNamespaceId)
|
||||
return CreateLocalStorage();
|
||||
return CreateSessionStorage(id);
|
||||
}
|
||||
|
||||
void DOMStorageContext::PurgeMemory() {
|
||||
// It is only safe to purge the memory from the LocalStorage namespace,
|
||||
// because it is backed by disk and can be reloaded later. If we purge a
|
||||
// SessionStorage namespace, its data will be gone forever, because it isn't
|
||||
// currently backed by disk.
|
||||
DOMStorageNamespace* local_storage =
|
||||
GetStorageNamespace(kLocalStorageNamespaceId, false);
|
||||
if (local_storage)
|
||||
local_storage->PurgeMemory();
|
||||
}
|
||||
|
||||
void DOMStorageContext::DeleteDataModifiedSince(
|
||||
const base::Time& cutoff,
|
||||
const char* url_scheme_to_be_skipped,
|
||||
const std::vector<string16>& protected_origins) {
|
||||
// Make sure that we don't delete a database that's currently being accessed
|
||||
// by unloading all of the databases temporarily.
|
||||
PurgeMemory();
|
||||
|
||||
FilePath data_path(_Context->cache_path());
|
||||
file_util::FileEnumerator file_enumerator(
|
||||
data_path.Append(kLocalStorageDirectory), false,
|
||||
file_util::FileEnumerator::FILES);
|
||||
for (FilePath path = file_enumerator.Next(); !path.value().empty();
|
||||
path = file_enumerator.Next()) {
|
||||
WebKit::WebSecurityOrigin web_security_origin =
|
||||
WebKit::WebSecurityOrigin::createFromDatabaseIdentifier(
|
||||
webkit_glue::FilePathToWebString(path.BaseName()));
|
||||
if (EqualsASCII(web_security_origin.protocol(), url_scheme_to_be_skipped))
|
||||
continue;
|
||||
|
||||
std::vector<string16>::const_iterator find_iter =
|
||||
std::find(protected_origins.begin(), protected_origins.end(),
|
||||
web_security_origin.databaseIdentifier());
|
||||
if (find_iter != protected_origins.end())
|
||||
continue;
|
||||
|
||||
file_util::FileEnumerator::FindInfo find_info;
|
||||
file_enumerator.GetFindInfo(&find_info);
|
||||
if (file_util::HasFileBeenModifiedSince(find_info, cutoff))
|
||||
file_util::Delete(path, false);
|
||||
}
|
||||
}
|
||||
|
||||
void DOMStorageContext::DeleteLocalStorageFile(const FilePath& file_path) {
|
||||
DCHECK(CefThread::CurrentlyOn(CefThread::UI));
|
||||
|
||||
// Make sure that we don't delete a database that's currently being accessed
|
||||
// by unloading all of the databases temporarily.
|
||||
// TODO(bulach): both this method and DeleteDataModifiedSince could purge
|
||||
// only the memory used by the specific file instead of all memory at once.
|
||||
// See http://crbug.com/32000
|
||||
PurgeMemory();
|
||||
file_util::Delete(file_path, false);
|
||||
}
|
||||
|
||||
void DOMStorageContext::DeleteLocalStorageForOrigin(const string16& origin_id) {
|
||||
DCHECK(CefThread::CurrentlyOn(CefThread::UI));
|
||||
DeleteLocalStorageFile(GetLocalStorageFilePath(origin_id));
|
||||
}
|
||||
|
||||
void DOMStorageContext::DeleteAllLocalStorageFiles() {
|
||||
DCHECK(CefThread::CurrentlyOn(CefThread::UI));
|
||||
|
||||
// Make sure that we don't delete a database that's currently being accessed
|
||||
// by unloading all of the databases temporarily.
|
||||
PurgeMemory();
|
||||
|
||||
FilePath data_path(_Context->cache_path());
|
||||
file_util::FileEnumerator file_enumerator(
|
||||
data_path.Append(kLocalStorageDirectory), false,
|
||||
file_util::FileEnumerator::FILES);
|
||||
for (FilePath file_path = file_enumerator.Next(); !file_path.empty();
|
||||
file_path = file_enumerator.Next()) {
|
||||
if (file_path.Extension() == kLocalStorageExtension)
|
||||
file_util::Delete(file_path, false);
|
||||
}
|
||||
}
|
||||
|
||||
DOMStorageNamespace* DOMStorageContext::CreateLocalStorage() {
|
||||
FilePath data_path(_Context->cache_path());
|
||||
FilePath dir_path;
|
||||
if (!data_path.empty())
|
||||
dir_path = data_path.Append(kLocalStorageDirectory);
|
||||
|
||||
DOMStorageNamespace* new_namespace =
|
||||
DOMStorageNamespace::CreateLocalStorageNamespace(this, dir_path);
|
||||
RegisterStorageNamespace(new_namespace);
|
||||
return new_namespace;
|
||||
}
|
||||
|
||||
DOMStorageNamespace* DOMStorageContext::CreateSessionStorage(
|
||||
int64 namespace_id) {
|
||||
DOMStorageNamespace* new_namespace =
|
||||
DOMStorageNamespace::CreateSessionStorageNamespace(this, namespace_id);
|
||||
RegisterStorageNamespace(new_namespace);
|
||||
return new_namespace;
|
||||
}
|
||||
|
||||
void DOMStorageContext::RegisterStorageNamespace(
|
||||
DOMStorageNamespace* storage_namespace) {
|
||||
DCHECK(CefThread::CurrentlyOn(CefThread::UI));
|
||||
int64 id = storage_namespace->id();
|
||||
DCHECK(!GetStorageNamespace(id, false));
|
||||
storage_namespace_map_[id] = storage_namespace;
|
||||
}
|
||||
|
||||
/* static */
|
||||
void DOMStorageContext::CompleteCloningSessionStorage(
|
||||
DOMStorageContext* context, int64 existing_id, int64 clone_id) {
|
||||
DCHECK(CefThread::CurrentlyOn(CefThread::UI));
|
||||
DOMStorageNamespace* existing_namespace =
|
||||
context->GetStorageNamespace(existing_id, false);
|
||||
// If nothing exists, then there's nothing to clone.
|
||||
if (existing_namespace)
|
||||
context->RegisterStorageNamespace(existing_namespace->Copy(clone_id));
|
||||
}
|
||||
|
||||
// static
|
||||
void DOMStorageContext::ClearLocalState(const FilePath& profile_path,
|
||||
const char* url_scheme_to_be_skipped) {
|
||||
file_util::FileEnumerator file_enumerator(profile_path.Append(
|
||||
kLocalStorageDirectory), false, file_util::FileEnumerator::FILES);
|
||||
for (FilePath file_path = file_enumerator.Next(); !file_path.empty();
|
||||
file_path = file_enumerator.Next()) {
|
||||
if (file_path.Extension() == kLocalStorageExtension) {
|
||||
WebKit::WebSecurityOrigin web_security_origin =
|
||||
WebKit::WebSecurityOrigin::createFromDatabaseIdentifier(
|
||||
webkit_glue::FilePathToWebString(file_path.BaseName()));
|
||||
if (!EqualsASCII(web_security_origin.protocol(),
|
||||
url_scheme_to_be_skipped))
|
||||
file_util::Delete(file_path, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FilePath DOMStorageContext::GetLocalStorageFilePath(
|
||||
const string16& origin_id) const {
|
||||
FilePath data_path(_Context->cache_path());
|
||||
FilePath storageDir = data_path.Append(
|
||||
DOMStorageContext::kLocalStorageDirectory);
|
||||
FilePath::StringType id =
|
||||
webkit_glue::WebStringToFilePathString(origin_id);
|
||||
return storageDir.Append(id.append(kLocalStorageExtension));
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef _DOM_STORAGE_CONTEXT_H
|
||||
#define _DOM_STORAGE_CONTEXT_H
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
#include "base/file_path.h"
|
||||
#include "base/string16.h"
|
||||
#include "base/time.h"
|
||||
|
||||
class DOMStorageArea;
|
||||
class DOMStorageNamespace;
|
||||
|
||||
// This is owned by CefContext and is all the dom storage information that's
|
||||
// shared by all of the browser windows. The specifics of responsibilities are
|
||||
// fairly well documented here and in StorageNamespace and StorageArea.
|
||||
// Everything is only to be accessed on the WebKit thread unless noted
|
||||
// otherwise.
|
||||
//
|
||||
// NOTE: Virtual methods facilitate mocking functions for testing.
|
||||
class DOMStorageContext {
|
||||
public:
|
||||
DOMStorageContext();
|
||||
virtual ~DOMStorageContext();
|
||||
|
||||
// Allocate a new storage area id. Only call on the WebKit thread.
|
||||
int64 AllocateStorageAreaId();
|
||||
|
||||
// Allocate a new session storage id. Only call on the UI or IO thread.
|
||||
int64 AllocateSessionStorageNamespaceId();
|
||||
|
||||
// Clones a session storage namespace and returns the cloned namespaces' id.
|
||||
// Only call on the IO thread.
|
||||
int64 CloneSessionStorage(int64 original_id);
|
||||
|
||||
// Various storage area methods. The storage area is owned by one of the
|
||||
// namespaces that's owned by this class.
|
||||
void RegisterStorageArea(DOMStorageArea* storage_area);
|
||||
void UnregisterStorageArea(DOMStorageArea* storage_area);
|
||||
DOMStorageArea* GetStorageArea(int64 id);
|
||||
|
||||
// Called on WebKit thread when a session storage namespace can be deleted.
|
||||
void DeleteSessionStorageNamespace(int64 namespace_id);
|
||||
|
||||
// Get a namespace from an id. What's returned is owned by this class. If
|
||||
// allocation_allowed is true, then this function will create the storage
|
||||
// namespace if it hasn't been already.
|
||||
DOMStorageNamespace* GetStorageNamespace(int64 id, bool allocation_allowed);
|
||||
|
||||
// Tells storage namespaces to purge any memory they do not need.
|
||||
virtual void PurgeMemory();
|
||||
|
||||
// Delete any local storage files that have been touched since the cutoff
|
||||
// date that's supplied.
|
||||
void DeleteDataModifiedSince(const base::Time& cutoff,
|
||||
const char* url_scheme_to_be_skipped,
|
||||
const std::vector<string16>& protected_origins);
|
||||
|
||||
// Deletes a single local storage file.
|
||||
void DeleteLocalStorageFile(const FilePath& file_path);
|
||||
|
||||
// Deletes the local storage file for the given origin.
|
||||
void DeleteLocalStorageForOrigin(const string16& origin_id);
|
||||
|
||||
// Deletes all local storage files.
|
||||
void DeleteAllLocalStorageFiles();
|
||||
|
||||
// The local storage directory.
|
||||
static const FilePath::CharType kLocalStorageDirectory[];
|
||||
|
||||
// The local storage file extension.
|
||||
static const FilePath::CharType kLocalStorageExtension[];
|
||||
|
||||
// Delete all non-extension local storage files.
|
||||
static void ClearLocalState(const FilePath& profile_path,
|
||||
const char* url_scheme_to_be_skipped);
|
||||
|
||||
// Get the file name of the local storage file for the given origin.
|
||||
FilePath GetLocalStorageFilePath(const string16& origin_id) const;
|
||||
|
||||
private:
|
||||
// Get the local storage instance. The object is owned by this class.
|
||||
DOMStorageNamespace* CreateLocalStorage();
|
||||
|
||||
// Get a new session storage namespace. The object is owned by this class.
|
||||
DOMStorageNamespace* CreateSessionStorage(int64 namespace_id);
|
||||
|
||||
// Used internally to register storage namespaces we create.
|
||||
void RegisterStorageNamespace(DOMStorageNamespace* storage_namespace);
|
||||
|
||||
// The WebKit thread half of CloneSessionStorage above. Static because
|
||||
// DOMStorageContext isn't ref counted thus we can't use a runnable method.
|
||||
// That said, we know this is safe because this class is destroyed on the
|
||||
// WebKit thread, so there's no way it could be destroyed before this is run.
|
||||
static void CompleteCloningSessionStorage(DOMStorageContext* context,
|
||||
int64 existing_id, int64 clone_id);
|
||||
|
||||
// The last used storage_area_id and storage_namespace_id's. For the storage
|
||||
// namespaces, IDs allocated on the UI thread are positive and count up while
|
||||
// IDs allocated on the IO thread are negative and count down. This allows us
|
||||
// to allocate unique IDs on both without any locking. All storage area ids
|
||||
// are allocated on the WebKit thread.
|
||||
int64 last_storage_area_id_;
|
||||
int64 last_session_storage_namespace_id_on_ui_thread_;
|
||||
int64 last_session_storage_namespace_id_on_io_thread_;
|
||||
|
||||
// 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 std::map<int64, DOMStorageArea*> StorageAreaMap;
|
||||
StorageAreaMap storage_area_map_;
|
||||
|
||||
// Maps ids to StorageNamespaces. We own these objects.
|
||||
typedef std::map<int64, DOMStorageNamespace*> StorageNamespaceMap;
|
||||
StorageNamespaceMap storage_namespace_map_;
|
||||
};
|
||||
|
||||
#endif // _DOM_STORAGE_CONTEXT_H
|
|
@ -0,0 +1,110 @@
|
|||
// Copyright (c) 2010 The Chromium Authors. All rights reserved. Use of this
|
||||
// source code is governed by a BSD-style license that can be found in the
|
||||
// LICENSE file.
|
||||
|
||||
#include "dom_storage_namespace.h"
|
||||
#include "dom_storage_area.h"
|
||||
#include "dom_storage_context.h"
|
||||
|
||||
#include "base/file_path.h"
|
||||
#include "base/logging.h"
|
||||
#include "third_party/WebKit/WebKit/chromium/public/WebStorageArea.h"
|
||||
#include "third_party/WebKit/WebKit/chromium/public/WebStorageNamespace.h"
|
||||
#include "webkit/glue/webkit_glue.h"
|
||||
|
||||
using WebKit::WebStorageArea;
|
||||
using WebKit::WebStorageNamespace;
|
||||
using WebKit::WebString;
|
||||
|
||||
/* static */
|
||||
DOMStorageNamespace* DOMStorageNamespace::CreateLocalStorageNamespace(
|
||||
DOMStorageContext* dom_storage_context, const FilePath& data_dir_path) {
|
||||
int64 id = kLocalStorageNamespaceId;
|
||||
DCHECK(!dom_storage_context->GetStorageNamespace(id, false));
|
||||
return new DOMStorageNamespace(dom_storage_context, id,
|
||||
webkit_glue::FilePathToWebString(data_dir_path), DOM_STORAGE_LOCAL);
|
||||
}
|
||||
|
||||
/* static */
|
||||
DOMStorageNamespace* DOMStorageNamespace::CreateSessionStorageNamespace(
|
||||
DOMStorageContext* dom_storage_context, int64 id) {
|
||||
DCHECK(!dom_storage_context->GetStorageNamespace(id, false));
|
||||
return new DOMStorageNamespace(dom_storage_context, id, WebString(),
|
||||
DOM_STORAGE_SESSION);
|
||||
}
|
||||
|
||||
DOMStorageNamespace::DOMStorageNamespace(DOMStorageContext* dom_storage_context,
|
||||
int64 id,
|
||||
const WebString& data_dir_path,
|
||||
DOMStorageType dom_storage_type)
|
||||
: dom_storage_context_(dom_storage_context),
|
||||
id_(id),
|
||||
data_dir_path_(data_dir_path),
|
||||
dom_storage_type_(dom_storage_type) {
|
||||
DCHECK(dom_storage_context_);
|
||||
}
|
||||
|
||||
DOMStorageNamespace::~DOMStorageNamespace() {
|
||||
// TODO(jorlow): If the DOMStorageContext is being destructed, there's no need
|
||||
// to do these calls. Maybe we should add a fast path?
|
||||
for (OriginToStorageAreaMap::iterator iter(origin_to_storage_area_.begin());
|
||||
iter != origin_to_storage_area_.end(); ++iter) {
|
||||
dom_storage_context_->UnregisterStorageArea(iter->second);
|
||||
delete iter->second;
|
||||
}
|
||||
}
|
||||
|
||||
DOMStorageArea* DOMStorageNamespace::GetStorageArea(
|
||||
const string16& origin) {
|
||||
// We may have already created it for another dispatcher host.
|
||||
OriginToStorageAreaMap::iterator iter = origin_to_storage_area_.find(origin);
|
||||
if (iter != origin_to_storage_area_.end())
|
||||
return iter->second;
|
||||
|
||||
// We need to create a new one.
|
||||
int64 id = dom_storage_context_->AllocateStorageAreaId();
|
||||
DCHECK(!dom_storage_context_->GetStorageArea(id));
|
||||
DOMStorageArea* storage_area = new DOMStorageArea(origin, id, this);
|
||||
origin_to_storage_area_[origin] = storage_area;
|
||||
dom_storage_context_->RegisterStorageArea(storage_area);
|
||||
return storage_area;
|
||||
}
|
||||
|
||||
DOMStorageNamespace* DOMStorageNamespace::Copy(int64 id) {
|
||||
DCHECK(dom_storage_type_ == DOM_STORAGE_SESSION);
|
||||
DCHECK(!dom_storage_context_->GetStorageNamespace(id, false));
|
||||
DOMStorageNamespace* new_storage_namespace = new DOMStorageNamespace(
|
||||
dom_storage_context_, id, data_dir_path_, dom_storage_type_);
|
||||
// If we haven't used the namespace yet, there's nothing to copy.
|
||||
if (storage_namespace_.get())
|
||||
new_storage_namespace->storage_namespace_.reset(storage_namespace_->copy());
|
||||
return new_storage_namespace;
|
||||
}
|
||||
|
||||
void DOMStorageNamespace::PurgeMemory() {
|
||||
DCHECK(dom_storage_type_ == DOM_STORAGE_LOCAL);
|
||||
for (OriginToStorageAreaMap::iterator iter(origin_to_storage_area_.begin());
|
||||
iter != origin_to_storage_area_.end(); ++iter)
|
||||
iter->second->PurgeMemory();
|
||||
storage_namespace_.reset();
|
||||
}
|
||||
|
||||
WebStorageArea* DOMStorageNamespace::CreateWebStorageArea(
|
||||
const string16& origin) {
|
||||
CreateWebStorageNamespaceIfNecessary();
|
||||
return storage_namespace_->createStorageArea(origin);
|
||||
}
|
||||
|
||||
void DOMStorageNamespace::CreateWebStorageNamespaceIfNecessary() {
|
||||
if (storage_namespace_.get())
|
||||
return;
|
||||
|
||||
if (dom_storage_type_ == DOM_STORAGE_LOCAL) {
|
||||
storage_namespace_.reset(
|
||||
WebStorageNamespace::createLocalStorageNamespace(data_dir_path_,
|
||||
WebStorageNamespace::m_localStorageQuota));
|
||||
} else {
|
||||
storage_namespace_.reset(WebStorageNamespace::createSessionStorageNamespace(
|
||||
WebStorageNamespace::m_sessionStorageQuota));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef _DOM_STORAGE_NAMESPACE_H
|
||||
#define _DOM_STORAGE_NAMESPACE_H
|
||||
|
||||
#include "dom_storage_common.h"
|
||||
|
||||
#include "base/hash_tables.h"
|
||||
#include "base/scoped_ptr.h"
|
||||
#include "base/string16.h"
|
||||
#include "third_party/WebKit/WebKit/chromium/public/WebString.h"
|
||||
|
||||
class DOMStorageArea;
|
||||
class DOMStorageContext;
|
||||
class FilePath;
|
||||
|
||||
namespace WebKit {
|
||||
class WebStorageArea;
|
||||
class WebStorageNamespace;
|
||||
}
|
||||
|
||||
// Only to be used on the WebKit thread.
|
||||
class DOMStorageNamespace {
|
||||
public:
|
||||
static DOMStorageNamespace* CreateLocalStorageNamespace(
|
||||
DOMStorageContext* dom_storage_context, const FilePath& data_dir_path);
|
||||
static DOMStorageNamespace* CreateSessionStorageNamespace(
|
||||
DOMStorageContext* dom_storage_context, int64 namespace_id);
|
||||
|
||||
~DOMStorageNamespace();
|
||||
|
||||
DOMStorageArea* GetStorageArea(const string16& origin);
|
||||
DOMStorageNamespace* Copy(int64 clone_namespace_id);
|
||||
|
||||
void PurgeMemory();
|
||||
|
||||
const DOMStorageContext* dom_storage_context() const {
|
||||
return dom_storage_context_;
|
||||
}
|
||||
int64 id() const { return id_; }
|
||||
const WebKit::WebString& data_dir_path() const { return data_dir_path_; }
|
||||
DOMStorageType dom_storage_type() const { return dom_storage_type_; }
|
||||
|
||||
// Creates a WebStorageArea for the given origin. This should only be called
|
||||
// by an owned DOMStorageArea.
|
||||
WebKit::WebStorageArea* CreateWebStorageArea(const string16& origin);
|
||||
|
||||
private:
|
||||
// Called by the static factory methods above.
|
||||
DOMStorageNamespace(DOMStorageContext* dom_storage_context,
|
||||
int64 id,
|
||||
const WebKit::WebString& data_dir_path,
|
||||
DOMStorageType storage_type);
|
||||
|
||||
// Creates the underlying WebStorageNamespace on demand.
|
||||
void CreateWebStorageNamespaceIfNecessary();
|
||||
|
||||
// All the storage areas we own.
|
||||
typedef base::hash_map<string16, DOMStorageArea*> OriginToStorageAreaMap;
|
||||
OriginToStorageAreaMap origin_to_storage_area_;
|
||||
|
||||
// The DOMStorageContext that owns us.
|
||||
DOMStorageContext* dom_storage_context_;
|
||||
|
||||
// The WebKit storage namespace we manage.
|
||||
scoped_ptr<WebKit::WebStorageNamespace> storage_namespace_;
|
||||
|
||||
// Our id. Unique to our parent context class.
|
||||
int64 id_;
|
||||
|
||||
// The path used to create us, so we can recreate our WebStorageNamespace on
|
||||
// demand.
|
||||
WebKit::WebString data_dir_path_;
|
||||
|
||||
// SessionStorage vs. LocalStorage.
|
||||
const DOMStorageType dom_storage_type_;
|
||||
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(DOMStorageNamespace);
|
||||
};
|
||||
|
||||
#endif // _DOM_STORAGE_NAMESPACE_H
|
|
@ -338,3 +338,8 @@ void RunPopupTest(CefRefPtr<CefBrowser> browser)
|
|||
browser->GetMainFrame()->ExecuteJavaScript(
|
||||
L"window.open('http://www.google.com');", L"about:blank", 0);
|
||||
}
|
||||
|
||||
void RunLocalStorageTest(CefRefPtr<CefBrowser> browser)
|
||||
{
|
||||
browser->GetMainFrame()->LoadURL(L"http://tests/localstorage");
|
||||
}
|
||||
|
|
|
@ -361,5 +361,6 @@ void RunGetTextTest(CefRefPtr<CefFrame> frame);
|
|||
void RunRequestTest(CefRefPtr<CefBrowser> browser);
|
||||
void RunJavaScriptExecuteTest(CefRefPtr<CefBrowser> browser);
|
||||
void RunPopupTest(CefRefPtr<CefBrowser> browser);
|
||||
void RunLocalStorageTest(CefRefPtr<CefBrowser> browser);
|
||||
|
||||
#endif // _CEFCLIENT_H
|
||||
|
|
|
@ -31,6 +31,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|||
IDS_LOGO BINARY "res\logo.png"
|
||||
IDS_UIPLUGIN BINARY "res\uiplugin.html"
|
||||
IDS_LOGOBALL BINARY "res\logoball.png"
|
||||
IDS_LOCALSTORAGE BINARY "res\localstorage.html"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
@ -73,7 +74,8 @@ BEGIN
|
|||
MENUITEM "Request", ID_TESTS_REQUEST
|
||||
MENUITEM "Scheme Handler", ID_TESTS_SCHEME_HANDLER
|
||||
MENUITEM "UI App Example", ID_TESTS_UIAPP
|
||||
END
|
||||
MENUITEM "Local Storage", ID_TESTS_LOCALSTORAGE
|
||||
END
|
||||
END
|
||||
|
||||
|
||||
|
|
|
@ -533,6 +533,10 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||
if(browser.get())
|
||||
RunUIPluginTest(browser);
|
||||
return 0;
|
||||
case ID_TESTS_LOCALSTORAGE: // Test localStorage
|
||||
if(browser.get())
|
||||
RunLocalStorageTest(browser);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -656,14 +660,20 @@ CefHandler::RetVal ClientHandler::HandleBeforeResourceLoad(
|
|||
resourceStream = CefStreamReader::CreateForData(
|
||||
(void*)dump.c_str(), dump.size() * sizeof(wchar_t));
|
||||
mimeType = L"text/plain";
|
||||
}
|
||||
else if(url == L"http://tests/uiapp") {
|
||||
} else if(url == L"http://tests/uiapp") {
|
||||
// Show the uiapp contents
|
||||
if(LoadBinaryResource(IDS_UIPLUGIN, dwSize, pBytes)) {
|
||||
resourceStream = CefStreamReader::CreateForHandler(
|
||||
new CefByteReadHandler(pBytes, dwSize, NULL));
|
||||
mimeType = L"text/html";
|
||||
}
|
||||
} else if(url == L"http://tests/localstorage") {
|
||||
// Show the localstorage contents
|
||||
if(LoadBinaryResource(IDS_LOCALSTORAGE, dwSize, pBytes)) {
|
||||
resourceStream = CefStreamReader::CreateForHandler(
|
||||
new CefByteReadHandler(pBytes, dwSize, NULL));
|
||||
mimeType = L"text/html";
|
||||
}
|
||||
} else if(wcsstr(url.c_str(), L"/ps_logo2.png") != NULL) {
|
||||
// Any time we find "ps_logo2.png" in the URL substitute in our own image
|
||||
if(LoadBinaryResource(IDS_LOGO, dwSize, pBytes)) {
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<html>
|
||||
<body>
|
||||
<script language="JavaScript">
|
||||
var val = window.localStorage.getItem('val');
|
||||
function addLine() {
|
||||
if(val == null)
|
||||
val = '<br/>One Line.';
|
||||
else
|
||||
val += '<br/>Another Line.';
|
||||
window.localStorage.setItem('val', val);
|
||||
document.getElementById('out').innerHTML = val;
|
||||
}
|
||||
</script>
|
||||
Click the "Add Line" button to add a line or the "Clear" button to clear.<br/>
|
||||
This data will persist across sessions if a cache path was specified.<br/>
|
||||
<input type="button" value="Add Line" onClick="addLine();"/>
|
||||
<input type="button" value="Clear" onClick="window.localStorage.removeItem('val'); window.location.reload();"/>
|
||||
<div id="out"></div>
|
||||
<script language="JavaScript">
|
||||
if(val != null)
|
||||
document.getElementById('out').innerHTML = val;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -36,10 +36,12 @@
|
|||
#define ID_TESTS_REQUEST 32776
|
||||
#define ID_TESTS_SCHEME_HANDLER 32777
|
||||
#define ID_TESTS_UIAPP 32778
|
||||
#define ID_TESTS_LOCALSTORAGE 32779
|
||||
#define IDC_STATIC -1
|
||||
#define IDS_LOGO 1000
|
||||
#define IDS_UIPLUGIN 1001
|
||||
#define IDS_LOGOBALL 1002
|
||||
#define IDS_LOCALSTORAGE 1003
|
||||
|
||||
// Avoid files associated with MacOS
|
||||
#define _X86_
|
||||
|
|
Loading…
Reference in New Issue