mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-02-02 20:26:59 +01:00
- Add CefSettings.local_storage_quota and session_storage_quota options for setting localStorage and sessionStorage quota limits respectively (issue #348).
- Add Cef*Storage() functions and CefStorageVisitor interface for accessing localStorage and sessionStorage data via the native API (issue #361). - Add a "cache_path" command-line flag option to cef_unittests for running the unit tests with a cache path value (issue #368). git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@302 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
50b909a417
commit
6b134b4def
4
cef.gyp
4
cef.gyp
@ -238,7 +238,9 @@
|
||||
'tests/unittests/scheme_handler_unittest.cc',
|
||||
'tests/unittests/stream_unittest.cc',
|
||||
'tests/unittests/string_unittest.cc',
|
||||
'tests/unittests/storage_unittest.cc',
|
||||
'tests/unittests/test_handler.h',
|
||||
'tests/unittests/test_suite.cc',
|
||||
'tests/unittests/test_suite.h',
|
||||
'tests/unittests/url_unittest.cc',
|
||||
'tests/unittests/v8_unittest.cc',
|
||||
@ -390,6 +392,8 @@
|
||||
'libcef_dll/ctocpp/scheme_handler_ctocpp.h',
|
||||
'libcef_dll/ctocpp/scheme_handler_factory_ctocpp.cc',
|
||||
'libcef_dll/ctocpp/scheme_handler_factory_ctocpp.h',
|
||||
'libcef_dll/ctocpp/storage_visitor_ctocpp.cc',
|
||||
'libcef_dll/ctocpp/storage_visitor_ctocpp.h',
|
||||
'libcef_dll/ctocpp/task_ctocpp.cc',
|
||||
'libcef_dll/ctocpp/task_ctocpp.h',
|
||||
'libcef_dll/ctocpp/v8accessor_ctocpp.cc',
|
||||
|
@ -158,6 +158,8 @@
|
||||
'libcef_dll/cpptoc/scheme_handler_cpptoc.h',
|
||||
'libcef_dll/cpptoc/scheme_handler_factory_cpptoc.cc',
|
||||
'libcef_dll/cpptoc/scheme_handler_factory_cpptoc.h',
|
||||
'libcef_dll/cpptoc/storage_visitor_cpptoc.cc',
|
||||
'libcef_dll/cpptoc/storage_visitor_cpptoc.h',
|
||||
'libcef_dll/cpptoc/task_cpptoc.cc',
|
||||
'libcef_dll/cpptoc/task_cpptoc.h',
|
||||
'libcef_dll/cpptoc/v8accessor_cpptoc.cc',
|
||||
|
@ -73,6 +73,7 @@ class CefRequest;
|
||||
class CefResponse;
|
||||
class CefSchemeHandler;
|
||||
class CefSchemeHandlerFactory;
|
||||
class CefStorageVisitor;
|
||||
class CefStreamReader;
|
||||
class CefStreamWriter;
|
||||
class CefTask;
|
||||
@ -389,6 +390,40 @@ bool CefSetCookie(const CefString& url, const CefCookie& cookie);
|
||||
bool CefDeleteCookies(const CefString& url, const CefString& cookie_name);
|
||||
|
||||
|
||||
typedef cef_storage_type_t CefStorageType;
|
||||
|
||||
///
|
||||
// Visit storage of the specified type. If |origin| is non-empty only data
|
||||
// matching that origin will be visited. If |key| is non-empty only data
|
||||
// matching that key will be visited. Otherwise, all data for the storage
|
||||
// type will be visited. Returns false if the storage cannot be accessed.
|
||||
// Origin should be of the form scheme://domain.
|
||||
///
|
||||
/*--cef()--*/
|
||||
bool CefVisitStorage(CefStorageType type, const CefString& origin,
|
||||
const CefString& key,
|
||||
CefRefPtr<CefStorageVisitor> visitor);
|
||||
|
||||
///
|
||||
// Sets storage of the specified type, origin, key and value. Returns false if
|
||||
// storage cannot be accessed. This method must be called on the UI thread.
|
||||
///
|
||||
/*--cef()--*/
|
||||
bool CefSetStorage(CefStorageType type, const CefString& origin,
|
||||
const CefString& key, const CefString& value);
|
||||
|
||||
///
|
||||
// Deletes all storage of the specified type. If |origin| is non-empty only data
|
||||
// matching that origin will be cleared. If |key| is non-empty only data
|
||||
// matching that key will be cleared. Otherwise, all data for the storage type
|
||||
// will be cleared. Returns false if storage cannot be accessed. This method
|
||||
// must be called on the UI thread.
|
||||
///
|
||||
/*--cef()--*/
|
||||
bool CefDeleteStorage(CefStorageType type, const CefString& origin,
|
||||
const CefString& key);
|
||||
|
||||
|
||||
///
|
||||
// Interface defining the reference count implementation methods. All framework
|
||||
// classes must extend the CefBase class.
|
||||
@ -528,6 +563,28 @@ public:
|
||||
};
|
||||
|
||||
|
||||
///
|
||||
// Interface to implement for visiting storage. The methods of this class will
|
||||
// always be called on the UI thread.
|
||||
///
|
||||
/*--cef(source=client)--*/
|
||||
class CefStorageVisitor : public virtual CefBase
|
||||
{
|
||||
public:
|
||||
///
|
||||
// Method that will be called once for each key/value data pair in storage.
|
||||
// |count| is the 0-based index for the current pair. |total| is the total
|
||||
// number of pairs. Set |deleteData| to true to delete the pair currently
|
||||
// being visited. Return false to stop visiting pairs. This method may never
|
||||
// be called if no data is found.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual bool Visit(CefStorageType type, const CefString& origin,
|
||||
const CefString& key, const CefString& value, int count,
|
||||
int total, bool& deleteData) =0;
|
||||
};
|
||||
|
||||
|
||||
///
|
||||
// Class used to represent a browser window. The methods of this class may be
|
||||
// called on any thread unless otherwise indicated in the comments.
|
||||
|
@ -325,6 +325,35 @@ CEF_EXPORT int cef_set_cookie(const cef_string_t* url,
|
||||
CEF_EXPORT int cef_delete_cookies(const cef_string_t* url,
|
||||
const cef_string_t* cookie_name);
|
||||
|
||||
///
|
||||
// Visit storage of the specified type. If |origin| is non-NULL only data
|
||||
// matching that origin will be visited. If |key| is non-NULL only data matching
|
||||
// that key will be visited. Otherwise, all data for the storage type will be
|
||||
// visited. Returns false (0) if the storage cannot be accessed. Origin should
|
||||
// be of the form scheme://domain.
|
||||
///
|
||||
CEF_EXPORT int cef_visit_storage(enum cef_storage_type_t type,
|
||||
const cef_string_t* origin, const cef_string_t* key,
|
||||
struct _cef_storage_visitor_t* visitor);
|
||||
|
||||
///
|
||||
// Sets storage of the specified type, origin, key and value. Returns false (0)
|
||||
// if storage cannot be accessed. This function must be called on the UI thread.
|
||||
///
|
||||
CEF_EXPORT int cef_set_storage(enum cef_storage_type_t type,
|
||||
const cef_string_t* origin, const cef_string_t* key,
|
||||
const cef_string_t* value);
|
||||
|
||||
///
|
||||
// Deletes all storage of the specified type. If |origin| is non-NULL only data
|
||||
// matching that origin will be cleared. If |key| is non-NULL only data matching
|
||||
// that key will be cleared. Otherwise, all data for the storage type will be
|
||||
// cleared. Returns false (0) if storage cannot be accessed. This function must
|
||||
// be called on the UI thread.
|
||||
///
|
||||
CEF_EXPORT int cef_delete_storage(enum cef_storage_type_t type,
|
||||
const cef_string_t* origin, const cef_string_t* key);
|
||||
|
||||
typedef struct _cef_base_t
|
||||
{
|
||||
// Size of the data structure.
|
||||
@ -390,6 +419,30 @@ typedef struct _cef_cookie_visitor_t
|
||||
} cef_cookie_visitor_t;
|
||||
|
||||
|
||||
///
|
||||
// Structure to implement for visiting storage. The functions of this structure
|
||||
// will always be called on the UI thread.
|
||||
///
|
||||
typedef struct _cef_storage_visitor_t
|
||||
{
|
||||
// Base structure.
|
||||
cef_base_t base;
|
||||
|
||||
///
|
||||
// Method that will be called once for each key/value data pair in storage.
|
||||
// |count| is the 0-based index for the current pair. |total| is the total
|
||||
// number of pairs. Set |deleteData| to true (1) to delete the pair currently
|
||||
// being visited. Return false (0) to stop visiting pairs. This function may
|
||||
// never be called if no data is found.
|
||||
///
|
||||
int (CEF_CALLBACK *visit)(struct _cef_storage_visitor_t* self,
|
||||
enum cef_storage_type_t type, const cef_string_t* origin,
|
||||
const cef_string_t* key, const cef_string_t* value, int count, int total,
|
||||
int* deleteData);
|
||||
|
||||
} cef_storage_visitor_t;
|
||||
|
||||
|
||||
///
|
||||
// Structure used to represent a browser window. The functions of this structure
|
||||
// may be called on any thread unless otherwise indicated in the comments.
|
||||
|
@ -141,6 +141,16 @@ typedef struct _cef_settings_t
|
||||
// content like WebGL, accelerated layers and 3D CSS.
|
||||
///
|
||||
cef_graphics_implementation_t graphics_implementation;
|
||||
|
||||
///
|
||||
// Quota limit for localStorage data across all origins. Default size is 5MB.
|
||||
///
|
||||
unsigned int local_storage_quota;
|
||||
|
||||
///
|
||||
// Quota limit for sessionStorage data per namespace. Default size is 5MB.
|
||||
///
|
||||
unsigned int session_storage_quota;
|
||||
} cef_settings_t;
|
||||
|
||||
///
|
||||
@ -469,6 +479,15 @@ typedef struct _cef_cookie_t
|
||||
cef_time_t expires;
|
||||
} cef_cookie_t;
|
||||
|
||||
///
|
||||
// Storage types.
|
||||
///
|
||||
enum cef_storage_type_t
|
||||
{
|
||||
ST_LOCALSTORAGE = 0,
|
||||
ST_SESSIONSTORAGE,
|
||||
};
|
||||
|
||||
///
|
||||
// Mouse button types.
|
||||
///
|
||||
|
@ -175,14 +175,7 @@ WebKit::WebString BrowserWebKitInit::defaultLocale() {
|
||||
|
||||
WebKit::WebStorageNamespace* BrowserWebKitInit::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);
|
||||
return new BrowserWebStorageNamespaceImpl(DOM_STORAGE_LOCAL);
|
||||
}
|
||||
|
||||
void BrowserWebKitInit::dispatchStorageEvent(const WebKit::WebString& key,
|
||||
|
@ -18,8 +18,8 @@ using WebKit::WebView;
|
||||
|
||||
BrowserWebStorageAreaImpl::BrowserWebStorageAreaImpl(
|
||||
int64 namespace_id, const WebString& origin) {
|
||||
area_ = _Context->storage_context()->GetStorageNamespace(namespace_id, true)->
|
||||
GetStorageArea(origin);
|
||||
area_ =
|
||||
_Context->storage_context()->GetStorageArea(namespace_id, origin, true);
|
||||
DCHECK(area_ != NULL);
|
||||
}
|
||||
|
||||
|
@ -16,14 +16,12 @@ 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() {
|
||||
@ -50,8 +48,3 @@ 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);
|
||||
}
|
||||
|
@ -23,9 +23,6 @@ class BrowserWebStorageNamespaceImpl : public WebKit::WebStorageNamespace {
|
||||
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_;
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "browser_navigation_controller.h"
|
||||
#include "browser_web_worker.h"
|
||||
#include "browser_webkit_glue.h"
|
||||
#include "browser_webstoragenamespace_impl.h"
|
||||
#include "browser_zoom_map.h"
|
||||
#include "cef_context.h"
|
||||
#include "request_impl.h"
|
||||
@ -180,11 +181,9 @@ WebWidget* BrowserWebViewDelegate::createPopupMenu(WebPopupType popup_type) {
|
||||
|
||||
WebStorageNamespace* BrowserWebViewDelegate::createSessionStorageNamespace(
|
||||
unsigned quota) {
|
||||
// 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);
|
||||
// Ignore the quota parameter from WebCore as in Chrome.
|
||||
return new BrowserWebStorageNamespaceImpl(DOM_STORAGE_SESSION,
|
||||
kLocalStorageNamespaceId + 1);
|
||||
}
|
||||
|
||||
void BrowserWebViewDelegate::didAddMessageToConsole(
|
||||
|
@ -2,14 +2,15 @@
|
||||
// reserved. Use of this source code is governed by a BSD-style license that can
|
||||
// be found in the LICENSE file.
|
||||
|
||||
#include "cef_context.h"
|
||||
#include "include/cef_nplugin.h"
|
||||
#include "browser_devtools_scheme_handler.h"
|
||||
#include "browser_impl.h"
|
||||
#include "browser_webkit_glue.h"
|
||||
#include "cef_thread.h"
|
||||
#include "cef_context.h"
|
||||
#include "cef_time_util.h"
|
||||
#include "cef_process.h"
|
||||
#include "../include/cef_nplugin.h"
|
||||
#include "dom_storage_common.h"
|
||||
#include "dom_storage_namespace.h"
|
||||
#include "dom_storage_area.h"
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/file_util.h"
|
||||
@ -169,6 +170,124 @@ private:
|
||||
base::WaitableEvent *event_;
|
||||
};
|
||||
|
||||
void UIT_VisitStorage(int64 namespace_id, const CefString& origin,
|
||||
const CefString& key,
|
||||
CefRefPtr<CefStorageVisitor> visitor)
|
||||
{
|
||||
REQUIRE_UIT();
|
||||
|
||||
DOMStorageContext* context = _Context->storage_context();
|
||||
|
||||
DOMStorageNamespace* ns =
|
||||
context->GetStorageNamespace(namespace_id, false);
|
||||
if (!ns)
|
||||
return;
|
||||
|
||||
typedef std::vector<DOMStorageArea*> AreaList;
|
||||
AreaList areas;
|
||||
|
||||
if (!origin.empty()) {
|
||||
// Visit only the area with the specified origin.
|
||||
DOMStorageArea* area = ns->GetStorageArea(origin, false);
|
||||
if (area)
|
||||
areas.push_back(area);
|
||||
} else {
|
||||
// Visit all areas.
|
||||
ns->GetStorageAreas(areas, true);
|
||||
}
|
||||
|
||||
if (areas.empty())
|
||||
return;
|
||||
|
||||
// Count the total number of matching keys.
|
||||
unsigned int total = 0;
|
||||
{
|
||||
NullableString16 value;
|
||||
AreaList::iterator it = areas.begin();
|
||||
for (; it != areas.end(); ) {
|
||||
DOMStorageArea* area = (*it);
|
||||
if (!key.empty()) {
|
||||
value = area->GetItem(key);
|
||||
if (value.is_null()) {
|
||||
it = areas.erase(it);
|
||||
// Don't increment the iterator.
|
||||
continue;
|
||||
} else {
|
||||
total++;
|
||||
}
|
||||
} else {
|
||||
total += area->Length();
|
||||
}
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
if (total == 0)
|
||||
return;
|
||||
|
||||
DOMStorageArea* area;
|
||||
bool stop = false, deleteData;
|
||||
unsigned int count = 0, i, len;
|
||||
NullableString16 keyVal, valueVal;
|
||||
string16 keyStr, valueStr;
|
||||
typedef std::vector<string16> String16List;
|
||||
String16List delete_keys;
|
||||
|
||||
// Visit all matching pairs.
|
||||
AreaList::iterator it = areas.begin();
|
||||
for (; it != areas.end() && !stop; ++it) {
|
||||
// Each area.
|
||||
area = *(it);
|
||||
if (!key.empty()) {
|
||||
// Visit only the matching key.
|
||||
valueVal = area->GetItem(key);
|
||||
if (valueVal.is_null())
|
||||
valueStr.clear();
|
||||
else
|
||||
valueStr = valueVal.string();
|
||||
|
||||
deleteData = false;
|
||||
stop = !visitor->Visit(static_cast<CefStorageType>(namespace_id),
|
||||
area->origin(), key, valueStr, count, total, deleteData);
|
||||
if (deleteData)
|
||||
area->RemoveItem(key);
|
||||
count++;
|
||||
} else {
|
||||
// Visit all keys.
|
||||
len = area->Length();
|
||||
for(i = 0; i < len && !stop; ++i) {
|
||||
keyVal = area->Key(i);
|
||||
if (keyVal.is_null()) {
|
||||
keyStr.clear();
|
||||
valueStr.clear();
|
||||
} else {
|
||||
keyStr = keyVal.string();
|
||||
valueVal = area->GetItem(keyStr);
|
||||
if (valueVal.is_null())
|
||||
valueStr.clear();
|
||||
else
|
||||
valueStr = valueVal.string();
|
||||
}
|
||||
|
||||
deleteData = false;
|
||||
stop = !visitor->Visit(static_cast<CefStorageType>(namespace_id),
|
||||
area->origin(), keyStr, valueStr, count, total, deleteData);
|
||||
if (deleteData)
|
||||
delete_keys.push_back(keyStr);
|
||||
count++;
|
||||
}
|
||||
|
||||
// Delete the requested keys.
|
||||
if (!delete_keys.empty()) {
|
||||
String16List::const_iterator it = delete_keys.begin();
|
||||
for (; it != delete_keys.end(); ++it)
|
||||
area->RemoveItem(*it);
|
||||
delete_keys.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // anonymous
|
||||
|
||||
bool CefInitialize(const CefSettings& settings)
|
||||
@ -178,7 +297,7 @@ bool CefInitialize(const CefSettings& settings)
|
||||
return true;
|
||||
|
||||
if(settings.size != sizeof(cef_settings_t)) {
|
||||
NOTREACHED();
|
||||
NOTREACHED() << "invalid CefSettings structure size";
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -193,13 +312,13 @@ void CefShutdown()
|
||||
{
|
||||
// Verify that the context is in a valid state.
|
||||
if (!CONTEXT_STATE_VALID()) {
|
||||
NOTREACHED();
|
||||
NOTREACHED() << "context not valid";
|
||||
return;
|
||||
}
|
||||
|
||||
// Must always be called on the same thread as Initialize.
|
||||
if(!_Context->process()->CalledOnValidThread()) {
|
||||
NOTREACHED();
|
||||
NOTREACHED() << "called on invalid thread";
|
||||
return;
|
||||
}
|
||||
|
||||
@ -214,13 +333,13 @@ void CefDoMessageLoopWork()
|
||||
{
|
||||
// Verify that the context is in a valid state.
|
||||
if (!CONTEXT_STATE_VALID()) {
|
||||
NOTREACHED();
|
||||
NOTREACHED() << "context not valid";
|
||||
return;
|
||||
}
|
||||
|
||||
// Must always be called on the same thread as Initialize.
|
||||
if(!_Context->process()->CalledOnValidThread()) {
|
||||
NOTREACHED();
|
||||
NOTREACHED() << "called on invalid thread";
|
||||
return;
|
||||
}
|
||||
|
||||
@ -231,13 +350,13 @@ void CefRunMessageLoop()
|
||||
{
|
||||
// Verify that the context is in a valid state.
|
||||
if (!CONTEXT_STATE_VALID()) {
|
||||
NOTREACHED();
|
||||
NOTREACHED() << "context not valid";
|
||||
return;
|
||||
}
|
||||
|
||||
// Must always be called on the same thread as Initialize.
|
||||
if(!_Context->process()->CalledOnValidThread()) {
|
||||
NOTREACHED();
|
||||
NOTREACHED() << "called on invalid thread";
|
||||
return;
|
||||
}
|
||||
|
||||
@ -248,7 +367,7 @@ bool CefRegisterPlugin(const CefPluginInfo& plugin_info)
|
||||
{
|
||||
// Verify that the context is in a valid state.
|
||||
if (!CONTEXT_STATE_VALID()) {
|
||||
NOTREACHED();
|
||||
NOTREACHED() << "context not valid";
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -367,7 +486,7 @@ bool CefVisitAllCookies(CefRefPtr<CefCookieVisitor> visitor)
|
||||
{
|
||||
// Verify that the context is in a valid state.
|
||||
if (!CONTEXT_STATE_VALID()) {
|
||||
NOTREACHED();
|
||||
NOTREACHED() << "context not valid";
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -380,7 +499,7 @@ bool CefVisitUrlCookies(const CefString& url, bool includeHttpOnly,
|
||||
{
|
||||
// Verify that the context is in a valid state.
|
||||
if (!CONTEXT_STATE_VALID()) {
|
||||
NOTREACHED();
|
||||
NOTREACHED() << "context not valid";
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -397,13 +516,13 @@ bool CefSetCookie(const CefString& url, const CefCookie& cookie)
|
||||
{
|
||||
// Verify that the context is in a valid state.
|
||||
if (!CONTEXT_STATE_VALID()) {
|
||||
NOTREACHED();
|
||||
NOTREACHED() << "context not valid";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verify that this function is being called on the IO thread.
|
||||
if (!CefThread::CurrentlyOn(CefThread::IO)) {
|
||||
NOTREACHED();
|
||||
NOTREACHED() << "called on invalid thread";
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -436,13 +555,13 @@ bool CefDeleteCookies(const CefString& url, const CefString& cookie_name)
|
||||
{
|
||||
// Verify that the context is in a valid state.
|
||||
if (!CONTEXT_STATE_VALID()) {
|
||||
NOTREACHED();
|
||||
NOTREACHED() << "context not valid";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verify that this function is being called on the IO thread.
|
||||
if (!CefThread::CurrentlyOn(CefThread::IO)) {
|
||||
NOTREACHED();
|
||||
NOTREACHED() << "called on invalid thread";
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -473,6 +592,132 @@ bool CefDeleteCookies(const CefString& url, const CefString& cookie_name)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CefVisitStorage(CefStorageType type, const CefString& origin,
|
||||
const CefString& key,
|
||||
CefRefPtr<CefStorageVisitor> visitor)
|
||||
{
|
||||
// Verify that the context is in a valid state.
|
||||
if (!CONTEXT_STATE_VALID()) {
|
||||
NOTREACHED() << "context not valid";
|
||||
return false;
|
||||
}
|
||||
|
||||
int64 namespace_id;
|
||||
if (type == ST_LOCALSTORAGE) {
|
||||
namespace_id = kLocalStorageNamespaceId;
|
||||
} else if(type == ST_SESSIONSTORAGE) {
|
||||
namespace_id = kLocalStorageNamespaceId + 1;
|
||||
} else {
|
||||
NOTREACHED() << "invalid type";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (CefThread::CurrentlyOn(CefThread::UI)) {
|
||||
UIT_VisitStorage(namespace_id, origin, key, visitor);
|
||||
} else {
|
||||
CefThread::PostTask(CefThread::UI, FROM_HERE,
|
||||
base::Bind(&UIT_VisitStorage, namespace_id, origin, key, visitor));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CefSetStorage(CefStorageType type, const CefString& origin,
|
||||
const CefString& key, const CefString& value)
|
||||
{
|
||||
// Verify that the context is in a valid state.
|
||||
if (!CONTEXT_STATE_VALID()) {
|
||||
NOTREACHED() << "context not valid";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verify that this function is being called on the UI thread.
|
||||
if (!CefThread::CurrentlyOn(CefThread::UI)) {
|
||||
NOTREACHED() << "called on invalid thread";
|
||||
return false;
|
||||
}
|
||||
|
||||
int64 namespace_id;
|
||||
if (type == ST_LOCALSTORAGE) {
|
||||
namespace_id = kLocalStorageNamespaceId;
|
||||
} else if(type == ST_SESSIONSTORAGE) {
|
||||
namespace_id = kLocalStorageNamespaceId + 1;
|
||||
} else {
|
||||
NOTREACHED() << "invalid type";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (origin.empty()) {
|
||||
NOTREACHED() << "invalid origin";
|
||||
return false;
|
||||
}
|
||||
|
||||
DOMStorageArea* area =
|
||||
_Context->storage_context()->GetStorageArea(namespace_id, origin, true);
|
||||
if (!area)
|
||||
return false;
|
||||
|
||||
WebKit::WebStorageArea::Result result;
|
||||
area->SetItem(key, value, &result);
|
||||
return (result == WebKit::WebStorageArea::ResultOK);
|
||||
}
|
||||
|
||||
bool CefDeleteStorage(CefStorageType type, const CefString& origin,
|
||||
const CefString& key)
|
||||
{
|
||||
// Verify that the context is in a valid state.
|
||||
if (!CONTEXT_STATE_VALID()) {
|
||||
NOTREACHED() << "context not valid";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verify that this function is being called on the UI thread.
|
||||
if (!CefThread::CurrentlyOn(CefThread::UI)) {
|
||||
NOTREACHED() << "called on invalid thread";
|
||||
return false;
|
||||
}
|
||||
|
||||
int64 namespace_id;
|
||||
if (type == ST_LOCALSTORAGE) {
|
||||
namespace_id = kLocalStorageNamespaceId;
|
||||
} else if(type == ST_SESSIONSTORAGE) {
|
||||
namespace_id = kLocalStorageNamespaceId + 1;
|
||||
} else {
|
||||
NOTREACHED() << "invalid type";
|
||||
return false;
|
||||
}
|
||||
|
||||
DOMStorageContext* context = _Context->storage_context();
|
||||
|
||||
if (origin.empty()) {
|
||||
// Delete all storage for the namespace.
|
||||
if (namespace_id == kLocalStorageNamespaceId)
|
||||
context->DeleteAllLocalStorageFiles();
|
||||
else
|
||||
context->PurgeMemory(namespace_id);
|
||||
} else if(key.empty()) {
|
||||
// Clear the storage area for the specified origin.
|
||||
if (namespace_id == kLocalStorageNamespaceId) {
|
||||
context->DeleteLocalStorageForOrigin(origin);
|
||||
} else {
|
||||
DOMStorageArea* area =
|
||||
context->GetStorageArea(namespace_id, origin, false);
|
||||
if (area) {
|
||||
// Calling Clear() is necessary to remove the data from the namespace.
|
||||
area->Clear();
|
||||
area->PurgeMemory();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Delete the specified key.
|
||||
DOMStorageArea* area = context->GetStorageArea(namespace_id, origin, false);
|
||||
if (area)
|
||||
area->RemoveItem(key);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// CefContext
|
||||
|
||||
|
@ -5,22 +5,23 @@
|
||||
#ifndef _CEF_CONTEXT_H
|
||||
#define _CEF_CONTEXT_H
|
||||
|
||||
#include "../include/cef.h"
|
||||
#include "include/cef.h"
|
||||
#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"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/message_loop.h"
|
||||
#include <map>
|
||||
|
||||
class BrowserRequestContext;
|
||||
class CefBrowserImpl;
|
||||
class WebViewHost;
|
||||
|
||||
namespace base {
|
||||
class WaitableEvent;
|
||||
}
|
||||
|
||||
class CefContext : public CefBase
|
||||
{
|
||||
public:
|
||||
|
@ -124,10 +124,14 @@ void CefProcessUIThread::Init() {
|
||||
gfx::InitializeGLBindings(gfx::kGLImplementationDesktopGL);
|
||||
#endif
|
||||
|
||||
if (!_Context->cache_path().empty()) {
|
||||
// Create the storage context object.
|
||||
_Context->set_storage_context(new DOMStorageContext());
|
||||
}
|
||||
// Set storage quota limits.
|
||||
if (settings.local_storage_quota != 0)
|
||||
DOMStorageContext::set_local_storage_quota(settings.local_storage_quota);
|
||||
if (settings.session_storage_quota != 0)
|
||||
DOMStorageContext::set_session_storage_quota(settings.session_storage_quota);
|
||||
|
||||
// Create the storage context object.
|
||||
_Context->set_storage_context(new DOMStorageContext(_Context->cache_path()));
|
||||
|
||||
if (settings.user_agent.length > 0)
|
||||
webkit_glue::SetUserAgent(CefString(&settings.user_agent));
|
||||
|
@ -37,6 +37,7 @@ class DOMStorageArea {
|
||||
int64 id() const { return id_; }
|
||||
|
||||
DOMStorageNamespace* owner() const { return owner_; }
|
||||
const string16& origin() const { return origin_; }
|
||||
|
||||
private:
|
||||
// Creates the underlying WebStorageArea on demand.
|
||||
|
@ -3,7 +3,6 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "dom_storage_context.h"
|
||||
#include "cef_context.h"
|
||||
#include "cef_thread.h"
|
||||
#include "dom_storage_namespace.h"
|
||||
|
||||
@ -14,7 +13,9 @@
|
||||
#include "base/string_util.h"
|
||||
#include "dom_storage_area.h"
|
||||
#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
|
||||
#include "third_party/WebKit/Source/WebKit/chromium/public/WebStorageNamespace.h"
|
||||
#include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
|
||||
#include "webkit/database/database_util.h"
|
||||
#include "webkit/glue/webkit_glue.h"
|
||||
|
||||
const FilePath::CharType DOMStorageContext::kLocalStorageDirectory[] =
|
||||
@ -23,8 +24,15 @@ const FilePath::CharType DOMStorageContext::kLocalStorageDirectory[] =
|
||||
const FilePath::CharType DOMStorageContext::kLocalStorageExtension[] =
|
||||
FILE_PATH_LITERAL(".localstorage");
|
||||
|
||||
DOMStorageContext::DOMStorageContext()
|
||||
: last_storage_area_id_(0),
|
||||
// Use WebStorageNamespace quota sizes as the default.
|
||||
unsigned int DOMStorageContext::local_storage_quota_ =
|
||||
WebKit::WebStorageNamespace::m_localStorageQuota;
|
||||
unsigned int DOMStorageContext::session_storage_quota_ =
|
||||
WebKit::WebStorageNamespace::m_sessionStorageQuota;
|
||||
|
||||
DOMStorageContext::DOMStorageContext(const FilePath& local_storage_path)
|
||||
: local_storage_path_(local_storage_path),
|
||||
last_storage_area_id_(0),
|
||||
last_session_storage_namespace_id_on_ui_thread_(kLocalStorageNamespaceId),
|
||||
last_session_storage_namespace_id_on_io_thread_(kLocalStorageNamespaceId){
|
||||
}
|
||||
@ -103,15 +111,20 @@ DOMStorageNamespace* DOMStorageContext::GetStorageNamespace(
|
||||
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();
|
||||
DOMStorageArea* DOMStorageContext::GetStorageArea(int64 namespace_id,
|
||||
const string16& origin, bool allocation_allowed) {
|
||||
DCHECK(CefThread::CurrentlyOn(CefThread::UI));
|
||||
DOMStorageNamespace* ns =
|
||||
GetStorageNamespace(namespace_id, allocation_allowed);
|
||||
if (ns)
|
||||
return ns->GetStorageArea(origin, allocation_allowed);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void DOMStorageContext::PurgeMemory(int64 namespace_id) {
|
||||
DOMStorageNamespace* ns = GetStorageNamespace(namespace_id, false);
|
||||
if (ns)
|
||||
ns->PurgeMemory();
|
||||
}
|
||||
|
||||
void DOMStorageContext::DeleteDataModifiedSince(
|
||||
@ -120,11 +133,13 @@ void DOMStorageContext::DeleteDataModifiedSince(
|
||||
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();
|
||||
PurgeMemory(kLocalStorageNamespaceId);
|
||||
|
||||
if (local_storage_path_.empty())
|
||||
return;
|
||||
|
||||
FilePath data_path(_Context->cache_path());
|
||||
file_util::FileEnumerator file_enumerator(
|
||||
data_path.Append(kLocalStorageDirectory), false,
|
||||
local_storage_path_.Append(kLocalStorageDirectory), false,
|
||||
file_util::FileEnumerator::FILES);
|
||||
for (FilePath path = file_enumerator.Next(); !path.value().empty();
|
||||
path = file_enumerator.Next()) {
|
||||
@ -147,21 +162,24 @@ void DOMStorageContext::DeleteDataModifiedSince(
|
||||
}
|
||||
}
|
||||
|
||||
void DOMStorageContext::DeleteLocalStorageFile(const FilePath& file_path) {
|
||||
void DOMStorageContext::DeleteLocalStorageForOrigin(const string16& origin) {
|
||||
DCHECK(CefThread::CurrentlyOn(CefThread::UI));
|
||||
|
||||
DOMStorageArea* area =
|
||||
GetStorageArea(kLocalStorageNamespaceId, origin, false);
|
||||
if (!area)
|
||||
return;
|
||||
|
||||
// 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);
|
||||
}
|
||||
// Calling Clear() is necessary to remove the data from the namespace.
|
||||
area->Clear();
|
||||
area->PurgeMemory();
|
||||
|
||||
void DOMStorageContext::DeleteLocalStorageForOrigin(const string16& origin_id) {
|
||||
DCHECK(CefThread::CurrentlyOn(CefThread::UI));
|
||||
DeleteLocalStorageFile(GetLocalStorageFilePath(origin_id));
|
||||
if (local_storage_path_.empty())
|
||||
return;
|
||||
|
||||
FilePath file_path = GetLocalStorageFilePath(origin);
|
||||
if (!file_path.empty())
|
||||
file_util::Delete(file_path, false);
|
||||
}
|
||||
|
||||
void DOMStorageContext::DeleteAllLocalStorageFiles() {
|
||||
@ -169,11 +187,13 @@ void DOMStorageContext::DeleteAllLocalStorageFiles() {
|
||||
|
||||
// Make sure that we don't delete a database that's currently being accessed
|
||||
// by unloading all of the databases temporarily.
|
||||
PurgeMemory();
|
||||
PurgeMemory(kLocalStorageNamespaceId);
|
||||
|
||||
if (local_storage_path_.empty())
|
||||
return;
|
||||
|
||||
FilePath data_path(_Context->cache_path());
|
||||
file_util::FileEnumerator file_enumerator(
|
||||
data_path.Append(kLocalStorageDirectory), false,
|
||||
local_storage_path_.Append(kLocalStorageDirectory), false,
|
||||
file_util::FileEnumerator::FILES);
|
||||
for (FilePath file_path = file_enumerator.Next(); !file_path.empty();
|
||||
file_path = file_enumerator.Next()) {
|
||||
@ -183,11 +203,9 @@ void DOMStorageContext::DeleteAllLocalStorageFiles() {
|
||||
}
|
||||
|
||||
DOMStorageNamespace* DOMStorageContext::CreateLocalStorage() {
|
||||
FilePath data_path(_Context->cache_path());
|
||||
FilePath dir_path;
|
||||
if (!data_path.empty())
|
||||
dir_path = data_path.Append(kLocalStorageDirectory);
|
||||
|
||||
if (!local_storage_path_.empty())
|
||||
dir_path = local_storage_path_.Append(kLocalStorageDirectory);
|
||||
DOMStorageNamespace* new_namespace =
|
||||
DOMStorageNamespace::CreateLocalStorageNamespace(this, dir_path);
|
||||
RegisterStorageNamespace(new_namespace);
|
||||
@ -240,9 +258,13 @@ void DOMStorageContext::ClearLocalState(const FilePath& profile_path,
|
||||
}
|
||||
|
||||
FilePath DOMStorageContext::GetLocalStorageFilePath(
|
||||
const string16& origin_id) const {
|
||||
FilePath data_path(_Context->cache_path());
|
||||
FilePath storageDir = data_path.Append(
|
||||
const string16& origin) const {
|
||||
DCHECK(!local_storage_path_.empty());
|
||||
|
||||
string16 origin_id =
|
||||
webkit_database::DatabaseUtil::GetOriginIdentifier(GURL(origin));
|
||||
|
||||
FilePath storageDir = local_storage_path_.Append(
|
||||
DOMStorageContext::kLocalStorageDirectory);
|
||||
FilePath::StringType id =
|
||||
webkit_glue::WebStringToFilePathString(origin_id);
|
||||
|
@ -24,7 +24,7 @@ class DOMStorageNamespace;
|
||||
// NOTE: Virtual methods facilitate mocking functions for testing.
|
||||
class DOMStorageContext {
|
||||
public:
|
||||
DOMStorageContext();
|
||||
DOMStorageContext(const FilePath& local_storage_path);
|
||||
virtual ~DOMStorageContext();
|
||||
|
||||
// Allocate a new storage area id. Only call on the WebKit thread.
|
||||
@ -51,8 +51,14 @@ class DOMStorageContext {
|
||||
// namespace if it hasn't been already.
|
||||
DOMStorageNamespace* GetStorageNamespace(int64 id, bool allocation_allowed);
|
||||
|
||||
// Get a storage area with the specified namespace_id and origin. If
|
||||
// allocation_allowed is true this function will create a new namespace and/or
|
||||
// storage area if it doesn't already exist.
|
||||
DOMStorageArea* GetStorageArea(int64 namespace_id, const string16& origin,
|
||||
bool allocation_allowed);
|
||||
|
||||
// Tells storage namespaces to purge any memory they do not need.
|
||||
virtual void PurgeMemory();
|
||||
virtual void PurgeMemory(int64 namespace_id);
|
||||
|
||||
// Delete any local storage files that have been touched since the cutoff
|
||||
// date that's supplied.
|
||||
@ -60,11 +66,8 @@ class DOMStorageContext {
|
||||
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);
|
||||
void DeleteLocalStorageForOrigin(const string16& origin);
|
||||
|
||||
// Deletes all local storage files.
|
||||
void DeleteAllLocalStorageFiles();
|
||||
@ -80,7 +83,16 @@ class DOMStorageContext {
|
||||
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;
|
||||
FilePath GetLocalStorageFilePath(const string16& origin) const;
|
||||
|
||||
// Set the quota limits for localStorage and sessionStorage respectively.
|
||||
// Changes will only take affect if made before creation of the namespaces.
|
||||
static void set_local_storage_quota(unsigned int quota)
|
||||
{ local_storage_quota_ = quota; }
|
||||
static void set_session_storage_quota(unsigned int quota)
|
||||
{ session_storage_quota_ = quota; }
|
||||
static unsigned int local_storage_quota() { return local_storage_quota_; }
|
||||
static unsigned int session_storage_quota() { return session_storage_quota_; }
|
||||
|
||||
private:
|
||||
// Get the local storage instance. The object is owned by this class.
|
||||
@ -99,6 +111,10 @@ class DOMStorageContext {
|
||||
static void CompleteCloningSessionStorage(DOMStorageContext* context,
|
||||
int64 existing_id, int64 clone_id);
|
||||
|
||||
// Location where localStorage files will be stored on disk. This may be empty
|
||||
// in which case localStorage data will be stored in-memory only.
|
||||
FilePath local_storage_path_;
|
||||
|
||||
// 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
|
||||
@ -116,6 +132,10 @@ class DOMStorageContext {
|
||||
// Maps ids to StorageNamespaces. We own these objects.
|
||||
typedef std::map<int64, DOMStorageNamespace*> StorageNamespaceMap;
|
||||
StorageNamespaceMap storage_namespace_map_;
|
||||
|
||||
// Quota limits for localStorage and sessionStorage respectively.
|
||||
static unsigned int local_storage_quota_;
|
||||
static unsigned int session_storage_quota_;
|
||||
};
|
||||
|
||||
#endif // _DOM_STORAGE_CONTEXT_H
|
||||
|
@ -21,8 +21,11 @@ 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);
|
||||
WebString path;
|
||||
if (!data_dir_path.empty())
|
||||
path = webkit_glue::FilePathToWebString(data_dir_path);
|
||||
return new DOMStorageNamespace(dom_storage_context, id, path,
|
||||
DOM_STORAGE_LOCAL);
|
||||
}
|
||||
|
||||
/* static */
|
||||
@ -55,12 +58,15 @@ DOMStorageNamespace::~DOMStorageNamespace() {
|
||||
}
|
||||
|
||||
DOMStorageArea* DOMStorageNamespace::GetStorageArea(
|
||||
const string16& origin) {
|
||||
const string16& origin, bool allocation_allowed) {
|
||||
// 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;
|
||||
|
||||
if (!allocation_allowed)
|
||||
return NULL;
|
||||
|
||||
// We need to create a new one.
|
||||
int64 id = dom_storage_context_->AllocateStorageAreaId();
|
||||
DCHECK(!dom_storage_context_->GetStorageArea(id));
|
||||
@ -81,8 +87,16 @@ DOMStorageNamespace* DOMStorageNamespace::Copy(int64 id) {
|
||||
return new_storage_namespace;
|
||||
}
|
||||
|
||||
void DOMStorageNamespace::GetStorageAreas(std::vector<DOMStorageArea*>& areas,
|
||||
bool skip_empty) const {
|
||||
OriginToStorageAreaMap::const_iterator iter = origin_to_storage_area_.begin();
|
||||
for (; iter != origin_to_storage_area_.end(); ++iter) {
|
||||
if (!skip_empty || iter->second->Length() > 0)
|
||||
areas.push_back(iter->second);
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
@ -102,9 +116,9 @@ void DOMStorageNamespace::CreateWebStorageNamespaceIfNecessary() {
|
||||
if (dom_storage_type_ == DOM_STORAGE_LOCAL) {
|
||||
storage_namespace_.reset(
|
||||
WebStorageNamespace::createLocalStorageNamespace(data_dir_path_,
|
||||
WebStorageNamespace::m_localStorageQuota));
|
||||
DOMStorageContext::local_storage_quota()));
|
||||
} else {
|
||||
storage_namespace_.reset(WebStorageNamespace::createSessionStorageNamespace(
|
||||
WebStorageNamespace::m_sessionStorageQuota));
|
||||
DOMStorageContext::session_storage_quota()));
|
||||
}
|
||||
}
|
||||
|
@ -31,9 +31,13 @@ class DOMStorageNamespace {
|
||||
|
||||
~DOMStorageNamespace();
|
||||
|
||||
DOMStorageArea* GetStorageArea(const string16& origin);
|
||||
DOMStorageArea* GetStorageArea(const string16& origin,
|
||||
bool allocation_allowed);
|
||||
DOMStorageNamespace* Copy(int64 clone_namespace_id);
|
||||
|
||||
void GetStorageAreas(std::vector<DOMStorageArea*>& areas,
|
||||
bool skip_empty) const;
|
||||
|
||||
void PurgeMemory();
|
||||
|
||||
const DOMStorageContext* dom_storage_context() const {
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "include/cef.h"
|
||||
#include "cef_context.h"
|
||||
#include "cef_thread.h"
|
||||
|
||||
#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityPolicy.h"
|
||||
#include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "include/cef.h"
|
||||
#include "cef_context.h"
|
||||
#include "cef_thread.h"
|
||||
#include "request_impl.h"
|
||||
#include "response_impl.h"
|
||||
|
||||
|
51
libcef_dll/cpptoc/storage_visitor_cpptoc.cc
Normal file
51
libcef_dll/cpptoc/storage_visitor_cpptoc.cc
Normal file
@ -0,0 +1,51 @@
|
||||
// Copyright (c) 2011 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.
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// A portion of this file was generated by the CEF translator tool. When
|
||||
// making changes by hand only do so within the body of existing function
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
|
||||
#include "libcef_dll/cpptoc/storage_visitor_cpptoc.h"
|
||||
|
||||
|
||||
// MEMBER FUNCTIONS - Body may be edited by hand.
|
||||
|
||||
int CEF_CALLBACK storage_visitor_visit(struct _cef_storage_visitor_t* self,
|
||||
enum cef_storage_type_t type, const cef_string_t* origin,
|
||||
const cef_string_t* key, const cef_string_t* value, int count, int total,
|
||||
int* deleteData)
|
||||
{
|
||||
DCHECK(self);
|
||||
DCHECK(origin);
|
||||
DCHECK(deleteData);
|
||||
if (!self || !origin || !deleteData)
|
||||
return false;
|
||||
|
||||
bool delVal = (*deleteData)?true:false;
|
||||
bool retVal = CefStorageVisitorCppToC::Get(self)->Visit(type, origin, key,
|
||||
value, count, total, delVal);
|
||||
*deleteData = delVal;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
// CONSTRUCTOR - Do not edit by hand.
|
||||
|
||||
CefStorageVisitorCppToC::CefStorageVisitorCppToC(CefStorageVisitor* cls)
|
||||
: CefCppToC<CefStorageVisitorCppToC, CefStorageVisitor,
|
||||
cef_storage_visitor_t>(cls)
|
||||
{
|
||||
struct_.struct_.visit = storage_visitor_visit;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
template<> long CefCppToC<CefStorageVisitorCppToC, CefStorageVisitor,
|
||||
cef_storage_visitor_t>::DebugObjCt = 0;
|
||||
#endif
|
||||
|
35
libcef_dll/cpptoc/storage_visitor_cpptoc.h
Normal file
35
libcef_dll/cpptoc/storage_visitor_cpptoc.h
Normal file
@ -0,0 +1,35 @@
|
||||
// Copyright (c) 2011 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.
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// This file was generated by the CEF translator tool and should not edited
|
||||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
#ifndef _STORAGEVISITOR_CPPTOC_H
|
||||
#define _STORAGEVISITOR_CPPTOC_H
|
||||
|
||||
#ifndef USING_CEF_SHARED
|
||||
#pragma message("Warning: "__FILE__" may be accessed wrapper-side only")
|
||||
#else // USING_CEF_SHARED
|
||||
|
||||
#include "include/cef.h"
|
||||
#include "include/cef_capi.h"
|
||||
#include "libcef_dll/cpptoc/cpptoc.h"
|
||||
|
||||
// Wrap a C++ class with a C structure.
|
||||
// This class may be instantiated and accessed wrapper-side only.
|
||||
class CefStorageVisitorCppToC
|
||||
: public CefCppToC<CefStorageVisitorCppToC, CefStorageVisitor,
|
||||
cef_storage_visitor_t>
|
||||
{
|
||||
public:
|
||||
CefStorageVisitorCppToC(CefStorageVisitor* cls);
|
||||
virtual ~CefStorageVisitorCppToC() {}
|
||||
};
|
||||
|
||||
#endif // USING_CEF_SHARED
|
||||
#endif // _STORAGEVISITOR_CPPTOC_H
|
||||
|
39
libcef_dll/ctocpp/storage_visitor_ctocpp.cc
Normal file
39
libcef_dll/ctocpp/storage_visitor_ctocpp.cc
Normal file
@ -0,0 +1,39 @@
|
||||
// Copyright (c) 2011 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.
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// A portion of this file was generated by the CEF translator tool. When
|
||||
// making changes by hand only do so within the body of existing static and
|
||||
// virtual method implementations. See the translator.README.txt file in the
|
||||
// tools directory for more information.
|
||||
//
|
||||
|
||||
#include "libcef_dll/ctocpp/storage_visitor_ctocpp.h"
|
||||
|
||||
|
||||
// VIRTUAL METHODS - Body may be edited by hand.
|
||||
|
||||
bool CefStorageVisitorCToCpp::Visit(CefStorageType type,
|
||||
const CefString& origin, const CefString& key, const CefString& value,
|
||||
int count, int total, bool& deleteData)
|
||||
{
|
||||
if (CEF_MEMBER_MISSING(struct_, visit))
|
||||
return false;
|
||||
|
||||
int delVal = deleteData;
|
||||
bool retVal = struct_->visit(struct_, type, origin.GetStruct(),
|
||||
key.GetStruct(), value.GetStruct(), count, total, &delVal) ?
|
||||
true : false;
|
||||
deleteData = delVal?true:false;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
template<> long CefCToCpp<CefStorageVisitorCToCpp, CefStorageVisitor,
|
||||
cef_storage_visitor_t>::DebugObjCt = 0;
|
||||
#endif
|
||||
|
43
libcef_dll/ctocpp/storage_visitor_ctocpp.h
Normal file
43
libcef_dll/ctocpp/storage_visitor_ctocpp.h
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright (c) 2011 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.
|
||||
//
|
||||
// -------------------------------------------------------------------------
|
||||
//
|
||||
// This file was generated by the CEF translator tool and should not edited
|
||||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
|
||||
#ifndef _STORAGEVISITOR_CTOCPP_H
|
||||
#define _STORAGEVISITOR_CTOCPP_H
|
||||
|
||||
#ifndef BUILDING_CEF_SHARED
|
||||
#pragma message("Warning: "__FILE__" may be accessed DLL-side only")
|
||||
#else // BUILDING_CEF_SHARED
|
||||
|
||||
#include "include/cef.h"
|
||||
#include "include/cef_capi.h"
|
||||
#include "libcef_dll/ctocpp/ctocpp.h"
|
||||
|
||||
// Wrap a C structure with a C++ class.
|
||||
// This class may be instantiated and accessed DLL-side only.
|
||||
class CefStorageVisitorCToCpp
|
||||
: public CefCToCpp<CefStorageVisitorCToCpp, CefStorageVisitor,
|
||||
cef_storage_visitor_t>
|
||||
{
|
||||
public:
|
||||
CefStorageVisitorCToCpp(cef_storage_visitor_t* str)
|
||||
: CefCToCpp<CefStorageVisitorCToCpp, CefStorageVisitor,
|
||||
cef_storage_visitor_t>(str) {}
|
||||
virtual ~CefStorageVisitorCToCpp() {}
|
||||
|
||||
// CefStorageVisitor methods
|
||||
virtual bool Visit(CefStorageType type, const CefString& origin,
|
||||
const CefString& key, const CefString& value, int count, int total,
|
||||
bool& deleteData) OVERRIDE;
|
||||
};
|
||||
|
||||
#endif // BUILDING_CEF_SHARED
|
||||
#endif // _STORAGEVISITOR_CTOCPP_H
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "ctocpp/read_handler_ctocpp.h"
|
||||
#include "ctocpp/scheme_handler_ctocpp.h"
|
||||
#include "ctocpp/scheme_handler_factory_ctocpp.h"
|
||||
#include "ctocpp/storage_visitor_ctocpp.h"
|
||||
#include "ctocpp/task_ctocpp.h"
|
||||
#include "ctocpp/v8accessor_ctocpp.h"
|
||||
#include "ctocpp/v8handler_ctocpp.h"
|
||||
@ -78,6 +79,7 @@ CEF_EXPORT void cef_shutdown()
|
||||
DCHECK(CefReadHandlerCToCpp::DebugObjCt == 0);
|
||||
DCHECK(CefSchemeHandlerCToCpp::DebugObjCt == 0);
|
||||
DCHECK(CefSchemeHandlerFactoryCToCpp::DebugObjCt == 0);
|
||||
DCHECK(CefStorageVisitorCToCpp::DebugObjCt == 0);
|
||||
DCHECK(CefV8AccessorCToCpp::DebugObjCt == 0);
|
||||
DCHECK(CefV8HandlerCToCpp::DebugObjCt == 0);
|
||||
DCHECK(CefWebURLRequestClientCToCpp::DebugObjCt == 0);
|
||||
@ -288,3 +290,47 @@ CEF_EXPORT int cef_delete_cookies(const cef_string_t* url,
|
||||
|
||||
return CefDeleteCookies(urlStr, cookieNameStr);
|
||||
}
|
||||
|
||||
CEF_EXPORT int cef_visit_storage(enum cef_storage_type_t type,
|
||||
const cef_string_t* origin, const cef_string_t* key,
|
||||
struct _cef_storage_visitor_t* visitor)
|
||||
{
|
||||
CefString originStr, keyStr;
|
||||
|
||||
if (origin)
|
||||
originStr = origin;
|
||||
if (key)
|
||||
keyStr = key;
|
||||
|
||||
return CefVisitStorage(type, originStr, keyStr,
|
||||
CefStorageVisitorCToCpp::Wrap(visitor));
|
||||
}
|
||||
|
||||
CEF_EXPORT int cef_set_storage(enum cef_storage_type_t type,
|
||||
const cef_string_t* origin, const cef_string_t* key,
|
||||
const cef_string_t* value)
|
||||
{
|
||||
CefString originStr, keyStr, valueStr;
|
||||
|
||||
if (origin)
|
||||
originStr = origin;
|
||||
if (key)
|
||||
keyStr = key;
|
||||
if (value)
|
||||
valueStr = value;
|
||||
|
||||
return CefSetStorage(type, originStr, keyStr, valueStr);
|
||||
}
|
||||
|
||||
CEF_EXPORT int cef_delete_storage(enum cef_storage_type_t type,
|
||||
const cef_string_t* origin, const cef_string_t* key)
|
||||
{
|
||||
CefString originStr, keyStr;
|
||||
|
||||
if (origin)
|
||||
originStr = origin;
|
||||
if (key)
|
||||
keyStr = key;
|
||||
|
||||
return CefDeleteStorage(type, origin, key);
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "libcef_dll/cpptoc/read_handler_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/scheme_handler_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/scheme_handler_factory_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/storage_visitor_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/task_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/v8accessor_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/v8handler_cpptoc.h"
|
||||
@ -54,6 +55,7 @@ void CefShutdown()
|
||||
DCHECK(CefReadHandlerCppToC::DebugObjCt == 0);
|
||||
DCHECK(CefSchemeHandlerCppToC::DebugObjCt == 0);
|
||||
DCHECK(CefSchemeHandlerFactoryCppToC::DebugObjCt == 0);
|
||||
DCHECK(CefStorageVisitorCppToC::DebugObjCt == 0);
|
||||
DCHECK(CefV8AccessorCppToC::DebugObjCt == 0);
|
||||
DCHECK(CefV8HandlerCppToC::DebugObjCt == 0);
|
||||
DCHECK(CefWebURLRequestClientCppToC::DebugObjCt == 0);
|
||||
@ -202,3 +204,25 @@ bool CefDeleteCookies(const CefString& url, const CefString& cookie_name)
|
||||
return cef_delete_cookies(url.GetStruct(), cookie_name.GetStruct()) ?
|
||||
true : false;
|
||||
}
|
||||
|
||||
bool CefVisitStorage(CefStorageType type, const CefString& origin,
|
||||
const CefString& key,
|
||||
CefRefPtr<CefStorageVisitor> visitor)
|
||||
{
|
||||
return cef_visit_storage(type, origin.GetStruct(), key.GetStruct(),
|
||||
CefStorageVisitorCppToC::Wrap(visitor)) ? true : false;
|
||||
}
|
||||
|
||||
bool CefSetStorage(CefStorageType type, const CefString& origin,
|
||||
const CefString& key, const CefString& value)
|
||||
{
|
||||
return cef_set_storage(type, origin.GetStruct(), key.GetStruct(),
|
||||
value.GetStruct()) ? true : false;
|
||||
}
|
||||
|
||||
bool CefDeleteStorage(CefStorageType type, const CefString& origin,
|
||||
const CefString& key)
|
||||
{
|
||||
return cef_delete_storage(type, origin.GetStruct(), key.GetStruct()) ?
|
||||
true : false;
|
||||
}
|
||||
|
394
tests/unittests/storage_unittest.cc
Normal file
394
tests/unittests/storage_unittest.cc
Normal file
@ -0,0 +1,394 @@
|
||||
// Copyright (c) 2011 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 "include/cef.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "test_handler.h"
|
||||
|
||||
namespace {
|
||||
|
||||
static const char* kOrigin = "http://tests";
|
||||
static const char* kNav1 = "http://tests/nav1.html";
|
||||
static const char* kNav2 = "http://tests/nav2.html";
|
||||
|
||||
static const char* kKey1 = "foo";
|
||||
static const char* kVal1 = "bar";
|
||||
static const char* kKey2 = "choo";
|
||||
static const char* kVal2 = "whatzit";
|
||||
|
||||
class StorageTestHandler : public TestHandler
|
||||
{
|
||||
public:
|
||||
class V8Handler : public CefV8Handler
|
||||
{
|
||||
public:
|
||||
V8Handler(CefRefPtr<StorageTestHandler> tester)
|
||||
: tester_(tester) {}
|
||||
|
||||
virtual bool Execute(const CefString& name,
|
||||
CefRefPtr<CefV8Value> object,
|
||||
const CefV8ValueList& arguments,
|
||||
CefRefPtr<CefV8Value>& retval,
|
||||
CefString& exception) OVERRIDE
|
||||
{
|
||||
if (arguments.size() != 2)
|
||||
return false;
|
||||
|
||||
std::string key = arguments[0]->GetStringValue();
|
||||
std::string val = arguments[1]->GetStringValue();
|
||||
|
||||
if (key == kKey1 && val == kVal1)
|
||||
tester_->got_js_read1_.yes();
|
||||
else if (key == kKey2 && val == kVal2)
|
||||
tester_->got_js_read2_.yes();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CefRefPtr<StorageTestHandler> tester_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(V8Handler);
|
||||
};
|
||||
|
||||
class StorageVisitor : public CefStorageVisitor
|
||||
{
|
||||
public:
|
||||
enum Mode {
|
||||
VisitKey,
|
||||
DeleteKey1,
|
||||
DeleteKey2
|
||||
};
|
||||
|
||||
StorageVisitor(CefRefPtr<StorageTestHandler> tester,
|
||||
const std::string& description, Mode mode,
|
||||
TrackCallback* callback1, TrackCallback* callback2,
|
||||
int expected_total)
|
||||
: tester_(tester), description_(description), mode_(mode),
|
||||
callback1_(callback1), callback2_(callback2),
|
||||
expected_total_(expected_total), actual_total_(0)
|
||||
{
|
||||
}
|
||||
virtual ~StorageVisitor()
|
||||
{
|
||||
EXPECT_EQ(expected_total_, actual_total_) << "test = "<< description_;
|
||||
}
|
||||
|
||||
virtual bool Visit(CefStorageType type, const CefString& origin,
|
||||
const CefString& key, const CefString& value, int count,
|
||||
int total, bool& deleteData) OVERRIDE
|
||||
{
|
||||
EXPECT_EQ(type, tester_->type_);
|
||||
std::string originStr = origin;
|
||||
EXPECT_EQ(originStr, kOrigin);
|
||||
|
||||
std::string keyStr = key;
|
||||
std::string valueStr = value;
|
||||
if (keyStr == kKey1 && valueStr == kVal1)
|
||||
callback1_->yes();
|
||||
else if(keyStr == kKey2 && valueStr == kVal2)
|
||||
callback2_->yes();
|
||||
|
||||
EXPECT_EQ(expected_total_, total) << "test = "<< description_;
|
||||
|
||||
if((mode_ == DeleteKey1 && keyStr == kKey1) ||
|
||||
(mode_ == DeleteKey2 && keyStr == kKey2))
|
||||
deleteData = true;
|
||||
|
||||
actual_total_++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CefRefPtr<StorageTestHandler> tester_;
|
||||
std::string description_;
|
||||
Mode mode_;
|
||||
TrackCallback* callback1_;
|
||||
TrackCallback* callback2_;
|
||||
int expected_total_;
|
||||
int actual_total_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(StorageVisitor);
|
||||
};
|
||||
|
||||
StorageTestHandler(CefStorageType type)
|
||||
: type_(type), nav_(0) {}
|
||||
|
||||
virtual void RunTest() OVERRIDE
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
std::string func = (type_==ST_LOCALSTORAGE?"localStorage":"sessionStorage");
|
||||
|
||||
// Values will be set vis JS on page load.
|
||||
ss << "<html><head><script language=\"JavaScript\">" <<
|
||||
func << ".setItem('" << std::string(kKey1) << "', '" <<
|
||||
std::string(kVal1) << "');" <<
|
||||
func << ".setItem('" << std::string(kKey2) << "', '" <<
|
||||
std::string(kVal2) << "');"
|
||||
"</script></head><body>Nav1</body></html>";
|
||||
AddResource(kNav1, ss.str(), "text/html");
|
||||
ss.str("");
|
||||
|
||||
// Values will be verified vis JS on page load.
|
||||
ss << "<html><head><script language=\"JavaScript\">"
|
||||
"window.test.result('" << std::string(kKey1) << "', " <<
|
||||
func << ".getItem('" << std::string(kKey1) << "'));"
|
||||
"window.test.result('" << std::string(kKey2) << "', " <<
|
||||
func << ".getItem('" << std::string(kKey2) << "'));"
|
||||
"</script></head><body>Nav2</body></html>";
|
||||
AddResource(kNav2, ss.str(), "text/html");
|
||||
ss.str("");
|
||||
|
||||
// Create the browser.
|
||||
CreateBrowser(kNav1);
|
||||
}
|
||||
|
||||
virtual void OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int httpStatusCode) OVERRIDE
|
||||
{
|
||||
if (nav_ == 0) {
|
||||
// Verify read all.
|
||||
CefVisitStorage(type_, "", "",
|
||||
new StorageVisitor(this, "all_read",
|
||||
StorageVisitor::VisitKey,
|
||||
&got_cpp_all_read1_,
|
||||
&got_cpp_all_read2_, 2));
|
||||
|
||||
// Verify read origin.
|
||||
CefVisitStorage(type_, kOrigin, "",
|
||||
new StorageVisitor(this, "origin_read",
|
||||
StorageVisitor::VisitKey,
|
||||
&got_cpp_origin_read1_,
|
||||
&got_cpp_origin_read2_, 2));
|
||||
|
||||
// Verify read key1.
|
||||
CefVisitStorage(type_, kOrigin, kKey1,
|
||||
new StorageVisitor(this, "key1_read",
|
||||
StorageVisitor::VisitKey,
|
||||
&got_cpp_key_read1_,
|
||||
&got_cpp_key_read1_fail_, 1));
|
||||
|
||||
// Verify read key2.
|
||||
CefVisitStorage(type_, kOrigin, kKey2,
|
||||
new StorageVisitor(this, "key2_read",
|
||||
StorageVisitor::VisitKey,
|
||||
&got_cpp_key_read2_fail_,
|
||||
&got_cpp_key_read2_, 1));
|
||||
|
||||
// Delete key1. Verify that key2 still gets read.
|
||||
CefVisitStorage(type_, kOrigin, "",
|
||||
new StorageVisitor(this, "key1_delete",
|
||||
StorageVisitor::DeleteKey1,
|
||||
&got_cpp_key_delete1_delete_,
|
||||
&got_cpp_key_delete1_, 2));
|
||||
|
||||
// Verify that key1 was deleted.
|
||||
CefVisitStorage(type_, kOrigin, "",
|
||||
new StorageVisitor(this, "key1_delete_verify",
|
||||
StorageVisitor::VisitKey,
|
||||
&got_cpp_afterdeletevisit1_fail_,
|
||||
&got_cpp_afterdeletevisit1_, 1));
|
||||
|
||||
// Delete key2.
|
||||
CefVisitStorage(type_, kOrigin, "",
|
||||
new StorageVisitor(this, "key2_delete",
|
||||
StorageVisitor::DeleteKey2,
|
||||
&got_cpp_key_delete2_fail_,
|
||||
&got_cpp_key_delete2_delete_, 1));
|
||||
|
||||
// Verify that all keys have been deleted.
|
||||
CefVisitStorage(type_, kOrigin, "",
|
||||
new StorageVisitor(this, "key2_delete_verify",
|
||||
StorageVisitor::VisitKey,
|
||||
&got_cpp_afterdeletevisit2_fail_,
|
||||
&got_cpp_afterdeletevisit2_fail_, 0));
|
||||
|
||||
// Reset the values.
|
||||
CefSetStorage(type_, kOrigin, kKey1, kVal1);
|
||||
CefSetStorage(type_, kOrigin, kKey2, kVal2);
|
||||
|
||||
// Verify that all values have been reset.
|
||||
CefVisitStorage(type_, "", "",
|
||||
new StorageVisitor(this, "reset1a_verify",
|
||||
StorageVisitor::VisitKey,
|
||||
&got_cpp_all_reset1a_,
|
||||
&got_cpp_all_reset2a_, 2));
|
||||
|
||||
// Delete all values.
|
||||
CefDeleteStorage(type_, "", "");
|
||||
|
||||
// Verify that all values have been deleted.
|
||||
CefVisitStorage(type_, "", "",
|
||||
new StorageVisitor(this, "delete_all_verify",
|
||||
StorageVisitor::VisitKey,
|
||||
&got_cpp_afterdeleteall_fail_,
|
||||
&got_cpp_afterdeleteall_fail_, 0));
|
||||
|
||||
// Reset all values.
|
||||
CefSetStorage(type_, kOrigin, kKey1, kVal1);
|
||||
CefSetStorage(type_, kOrigin, kKey2, kVal2);
|
||||
|
||||
// Verify that all values have been reset.
|
||||
CefVisitStorage(type_, "", "",
|
||||
new StorageVisitor(this, "reset1b_verify",
|
||||
StorageVisitor::VisitKey,
|
||||
&got_cpp_all_reset1b_,
|
||||
&got_cpp_all_reset2b_, 2));
|
||||
|
||||
// Delete all values by origin.
|
||||
CefDeleteStorage(type_, kOrigin, "");
|
||||
|
||||
// Verify that all values have been deleted.
|
||||
CefVisitStorage(type_, "", "",
|
||||
new StorageVisitor(this, "delete_origin_verify",
|
||||
StorageVisitor::VisitKey,
|
||||
&got_cpp_afterdeleteorigin_fail_,
|
||||
&got_cpp_afterdeleteorigin_fail_, 0));
|
||||
|
||||
// Reset the values.
|
||||
CefSetStorage(type_, kOrigin, kKey1, kVal1);
|
||||
CefSetStorage(type_, kOrigin, kKey2, kVal2);
|
||||
|
||||
// Verify that all values have been reset.
|
||||
CefVisitStorage(type_, "", "",
|
||||
new StorageVisitor(this, "reset1c_verify",
|
||||
StorageVisitor::VisitKey,
|
||||
&got_cpp_all_reset1c_,
|
||||
&got_cpp_all_reset2c_, 2));
|
||||
|
||||
// Delete key1.
|
||||
CefDeleteStorage(type_, kOrigin, kKey1);
|
||||
|
||||
// Verify that key1 has been deleted.
|
||||
CefVisitStorage(type_, "", "",
|
||||
new StorageVisitor(this, "direct_key1_delete_verify",
|
||||
StorageVisitor::VisitKey,
|
||||
&got_cpp_afterdeletekey1_fail_,
|
||||
&got_cpp_afterdeletekey1_, 1));
|
||||
|
||||
// Delete key2.
|
||||
CefDeleteStorage(type_, kOrigin, kKey2);
|
||||
|
||||
// Verify that all values have been deleted.
|
||||
CefVisitStorage(type_, "", "",
|
||||
new StorageVisitor(this, "direct_key2_delete_verify",
|
||||
StorageVisitor::VisitKey,
|
||||
&got_cpp_afterdeletekey2_fail_,
|
||||
&got_cpp_afterdeletekey2_fail_, 0));
|
||||
|
||||
// Reset all values.
|
||||
CefSetStorage(type_, kOrigin, kKey1, kVal1);
|
||||
CefSetStorage(type_, kOrigin, kKey2, kVal2);
|
||||
|
||||
// Verify that all values have been reset.
|
||||
CefVisitStorage(type_, "", "",
|
||||
new StorageVisitor(this, "reset1d_verify",
|
||||
StorageVisitor::VisitKey,
|
||||
&got_cpp_all_reset1d_,
|
||||
&got_cpp_all_reset2d_, 2));
|
||||
|
||||
nav_++;
|
||||
// Verify JS read after navigation.
|
||||
frame->LoadURL(kNav2);
|
||||
} else {
|
||||
DestroyTest();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnJSBinding(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefV8Value> object) OVERRIDE
|
||||
{
|
||||
CefRefPtr<CefV8Handler> handler = new V8Handler(this);
|
||||
CefRefPtr<CefV8Value> testObj = CefV8Value::CreateObject(NULL, NULL);
|
||||
testObj->SetValue("result", CefV8Value::CreateFunction("result", handler));
|
||||
object->SetValue("test", testObj);
|
||||
}
|
||||
|
||||
CefStorageType type_;
|
||||
int nav_;
|
||||
|
||||
TrackCallback got_cpp_all_read1_;
|
||||
TrackCallback got_cpp_all_read2_;
|
||||
TrackCallback got_cpp_origin_read1_;
|
||||
TrackCallback got_cpp_origin_read2_;
|
||||
TrackCallback got_cpp_key_read1_;
|
||||
TrackCallback got_cpp_key_read1_fail_;
|
||||
TrackCallback got_cpp_key_read2_;
|
||||
TrackCallback got_cpp_key_read2_fail_;
|
||||
TrackCallback got_cpp_key_delete1_;
|
||||
TrackCallback got_cpp_key_delete1_delete_;
|
||||
TrackCallback got_cpp_key_delete2_delete_;
|
||||
TrackCallback got_cpp_key_delete2_fail_;
|
||||
TrackCallback got_cpp_afterdeletevisit1_;
|
||||
TrackCallback got_cpp_afterdeletevisit1_fail_;
|
||||
TrackCallback got_cpp_afterdeletevisit2_fail_;
|
||||
TrackCallback got_cpp_all_reset1a_;
|
||||
TrackCallback got_cpp_all_reset2a_;
|
||||
TrackCallback got_cpp_afterdeleteall_fail_;
|
||||
TrackCallback got_cpp_all_reset1b_;
|
||||
TrackCallback got_cpp_all_reset2b_;
|
||||
TrackCallback got_cpp_afterdeleteorigin_fail_;
|
||||
TrackCallback got_cpp_all_reset1c_;
|
||||
TrackCallback got_cpp_all_reset2c_;
|
||||
TrackCallback got_cpp_afterdeletekey1_;
|
||||
TrackCallback got_cpp_afterdeletekey1_fail_;
|
||||
TrackCallback got_cpp_afterdeletekey2_fail_;
|
||||
TrackCallback got_cpp_all_reset1d_;
|
||||
TrackCallback got_cpp_all_reset2d_;
|
||||
TrackCallback got_js_read1_;
|
||||
TrackCallback got_js_read2_;
|
||||
};
|
||||
|
||||
void StorageTest(CefStorageType type)
|
||||
{
|
||||
CefRefPtr<StorageTestHandler> handler = new StorageTestHandler(type);
|
||||
handler->ExecuteTest();
|
||||
|
||||
EXPECT_TRUE(handler->got_cpp_all_read1_);
|
||||
EXPECT_TRUE(handler->got_cpp_all_read2_);
|
||||
EXPECT_TRUE(handler->got_cpp_origin_read1_);
|
||||
EXPECT_TRUE(handler->got_cpp_origin_read2_);
|
||||
EXPECT_TRUE(handler->got_cpp_key_read1_);
|
||||
EXPECT_FALSE(handler->got_cpp_key_read1_fail_);
|
||||
EXPECT_TRUE(handler->got_cpp_key_read2_);
|
||||
EXPECT_FALSE(handler->got_cpp_key_read2_fail_);
|
||||
EXPECT_TRUE(handler->got_cpp_key_delete1_);
|
||||
EXPECT_TRUE(handler->got_cpp_key_delete1_delete_);
|
||||
EXPECT_TRUE(handler->got_cpp_key_delete2_delete_);
|
||||
EXPECT_FALSE(handler->got_cpp_key_delete2_fail_);
|
||||
EXPECT_TRUE(handler->got_cpp_afterdeletevisit1_);
|
||||
EXPECT_FALSE(handler->got_cpp_afterdeletevisit1_fail_);
|
||||
EXPECT_FALSE(handler->got_cpp_afterdeletevisit2_fail_);
|
||||
EXPECT_TRUE(handler->got_cpp_all_reset1a_);
|
||||
EXPECT_TRUE(handler->got_cpp_all_reset2a_);
|
||||
EXPECT_FALSE(handler->got_cpp_afterdeleteall_fail_);
|
||||
EXPECT_TRUE(handler->got_cpp_all_reset1b_);
|
||||
EXPECT_TRUE(handler->got_cpp_all_reset2b_);
|
||||
EXPECT_FALSE(handler->got_cpp_afterdeleteorigin_fail_);
|
||||
EXPECT_TRUE(handler->got_cpp_all_reset1c_);
|
||||
EXPECT_TRUE(handler->got_cpp_all_reset2c_);
|
||||
EXPECT_TRUE(handler->got_cpp_afterdeletekey1_);
|
||||
EXPECT_FALSE(handler->got_cpp_afterdeletekey1_fail_);
|
||||
EXPECT_FALSE(handler->got_cpp_afterdeletekey2_fail_);
|
||||
EXPECT_TRUE(handler->got_cpp_all_reset1d_);
|
||||
EXPECT_TRUE(handler->got_cpp_all_reset2d_);
|
||||
EXPECT_TRUE(handler->got_js_read1_);
|
||||
EXPECT_TRUE(handler->got_js_read2_);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// Test localStorage.
|
||||
TEST(StorageTest, Local)
|
||||
{
|
||||
StorageTest(ST_LOCALSTORAGE);
|
||||
}
|
||||
|
||||
// Test sessionStorage.
|
||||
TEST(StorageTest, Session)
|
||||
{
|
||||
StorageTest(ST_SESSIONSTORAGE);
|
||||
}
|
39
tests/unittests/test_suite.cc
Normal file
39
tests/unittests/test_suite.cc
Normal file
@ -0,0 +1,39 @@
|
||||
// Copyright (c) 2011 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 "include/cef.h"
|
||||
#include "test_suite.h"
|
||||
#include "base/command_line.h"
|
||||
#include "build/build_config.h"
|
||||
#include "base/threading/platform_thread.h"
|
||||
#include "base/test/test_suite.h"
|
||||
|
||||
CefTestSuite::CefTestSuite(int argc, char** argv) : TestSuite(argc, argv) {
|
||||
}
|
||||
|
||||
void CefTestSuite::Initialize() {
|
||||
TestSuite::Initialize();
|
||||
|
||||
CefSettings settings;
|
||||
settings.multi_threaded_message_loop = true;
|
||||
|
||||
CommandLine* command_line = CommandLine::ForCurrentProcess();
|
||||
|
||||
if (command_line->HasSwitch("cache_path")) {
|
||||
// Set the cache_path value.
|
||||
std::string cache_path = command_line->GetSwitchValueASCII("cache_path");
|
||||
CefString(&settings.cache_path).FromASCII(cache_path.c_str());
|
||||
}
|
||||
|
||||
CefInitialize(settings);
|
||||
}
|
||||
|
||||
void CefTestSuite::Shutdown() {
|
||||
// Delay a bit so that the system has a chance to finish destroying windows
|
||||
// before CefShutdown() checks for memory leaks.
|
||||
base::PlatformThread::Sleep(500);
|
||||
|
||||
CefShutdown();
|
||||
TestSuite::Shutdown();
|
||||
}
|
@ -1,38 +1,19 @@
|
||||
// Copyright (c) 2009 The Chromium Embedded Framework Authors. All rights
|
||||
// Copyright (c) 2011 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 _CEF_TEST_SUITE_H
|
||||
#define _CEF_TEST_SUITE_H
|
||||
|
||||
#include "build/build_config.h"
|
||||
#include "base/threading/platform_thread.h"
|
||||
#include "base/test/test_suite.h"
|
||||
#include "include/cef.h"
|
||||
|
||||
class CefTestSuite : public TestSuite {
|
||||
public:
|
||||
CefTestSuite(int argc, char** argv) : TestSuite(argc, argv) {
|
||||
}
|
||||
public:
|
||||
CefTestSuite(int argc, char** argv);
|
||||
|
||||
protected:
|
||||
|
||||
virtual void Initialize() {
|
||||
TestSuite::Initialize();
|
||||
|
||||
CefSettings settings;
|
||||
settings.multi_threaded_message_loop = true;
|
||||
CefInitialize(settings);
|
||||
}
|
||||
|
||||
virtual void Shutdown() {
|
||||
// Delay a bit so that the system has a chance to finish destroying windows
|
||||
// before CefShutdown() checks for memory leaks.
|
||||
base::PlatformThread::Sleep(500);
|
||||
|
||||
CefShutdown();
|
||||
TestSuite::Shutdown();
|
||||
}
|
||||
protected:
|
||||
virtual void Initialize();
|
||||
virtual void Shutdown();
|
||||
};
|
||||
|
||||
#endif // _CEF_TEST_SUITE_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user