- Update to Chromium revision 138235.

- Move to the new DOM storage backend. Persistent localStorage support will need to be re-implemented (issue #603).
- Add CefV8Value::CreateUInt method and indicate that integer types are 32bit via usage of int32 and uint32 types (issue #331).
- Add CefV8Context::Eval method for synchronous JavaScript execution that returns a value or exception (issue #444).
- Move exception handling from an ExecuteFunction argument to a CefV8Value attribute (issue #546).
- Make user data an attribute for all CefV8Value object types and not just CreateObject (issue #547).
- Un-fork SQLitePersistentCookieStore by adding stub implementations for sqlite_diagnostics and browser_thread.
- Update tools/cef_parser.py to match the CEF3 version.

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@644 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt
2012-05-23 19:01:04 +00:00
parent b5f2f5db3e
commit 801ff3ca43
87 changed files with 3574 additions and 5855 deletions

View File

@@ -0,0 +1,291 @@
// Copyright (c) 2012 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 "libcef/browser_dom_storage_system.h"
#include "base/auto_reset.h"
#include "googleurl/src/gurl.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebStorageArea.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebStorageEventDispatcher.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebStorageNamespace.h"
#include "webkit/database/database_util.h"
#include "webkit/dom_storage/dom_storage_area.h"
#include "webkit/dom_storage/dom_storage_host.h"
using dom_storage::DomStorageContext;
using dom_storage::DomStorageHost;
using dom_storage::DomStorageSession;
using webkit_database::DatabaseUtil;
using WebKit::WebStorageArea;
using WebKit::WebStorageNamespace;
using WebKit::WebStorageEventDispatcher;
using WebKit::WebString;
using WebKit::WebURL;
namespace {
const int kInvalidNamespaceId = -1;
}
class BrowserDomStorageSystem::NamespaceImpl : public WebStorageNamespace {
public:
explicit NamespaceImpl(const base::WeakPtr<BrowserDomStorageSystem>& parent);
NamespaceImpl(const base::WeakPtr<BrowserDomStorageSystem>& parent,
int session_namespace_id);
virtual ~NamespaceImpl();
virtual WebStorageArea* createStorageArea(const WebString& origin) OVERRIDE;
virtual WebStorageNamespace* copy() OVERRIDE;
virtual bool isSameNamespace(const WebStorageNamespace&) const OVERRIDE;
private:
DomStorageContext* Context() {
if (!parent_.get())
return NULL;
return parent_->context_.get();
}
base::WeakPtr<BrowserDomStorageSystem> parent_;
int namespace_id_;
};
class BrowserDomStorageSystem::AreaImpl : public WebStorageArea {
public:
AreaImpl(const base::WeakPtr<BrowserDomStorageSystem>& parent,
int namespace_id, const GURL& origin);
virtual ~AreaImpl();
virtual unsigned length() OVERRIDE;
virtual WebString key(unsigned index) OVERRIDE;
virtual WebString getItem(const WebString& key) OVERRIDE;
virtual void setItem(const WebString& key, const WebString& newValue,
const WebURL&, Result&, WebString& oldValue) OVERRIDE;
virtual void removeItem(const WebString& key, const WebURL& url,
WebString& oldValue) OVERRIDE;
virtual void clear(const WebURL& url, bool& somethingCleared) OVERRIDE;
private:
DomStorageHost* Host() {
if (!parent_.get())
return NULL;
return parent_->host_.get();
}
base::WeakPtr<BrowserDomStorageSystem> parent_;
int connection_id_;
};
// NamespaceImpl -----------------------------
BrowserDomStorageSystem::NamespaceImpl::NamespaceImpl(
const base::WeakPtr<BrowserDomStorageSystem>& parent)
: parent_(parent),
namespace_id_(dom_storage::kLocalStorageNamespaceId) {
}
BrowserDomStorageSystem::NamespaceImpl::NamespaceImpl(
const base::WeakPtr<BrowserDomStorageSystem>& parent,
int session_namespace_id)
: parent_(parent),
namespace_id_(session_namespace_id) {
}
BrowserDomStorageSystem::NamespaceImpl::~NamespaceImpl() {
if (namespace_id_ == dom_storage::kLocalStorageNamespaceId ||
namespace_id_ == kInvalidNamespaceId || !Context()) {
return;
}
Context()->DeleteSessionNamespace(namespace_id_);
}
WebStorageArea* BrowserDomStorageSystem::NamespaceImpl::createStorageArea(
const WebString& origin) {
return new AreaImpl(parent_, namespace_id_, GURL(origin));
}
WebStorageNamespace* BrowserDomStorageSystem::NamespaceImpl::copy() {
DCHECK_NE(dom_storage::kLocalStorageNamespaceId, namespace_id_);
int new_id = kInvalidNamespaceId;
if (Context()) {
new_id = Context()->AllocateSessionId();
Context()->CloneSessionNamespace(namespace_id_, new_id);
}
return new NamespaceImpl(parent_, new_id);
}
bool BrowserDomStorageSystem::NamespaceImpl::isSameNamespace(
const WebStorageNamespace& other) const {
const NamespaceImpl* other_impl = static_cast<const NamespaceImpl*>(&other);
return namespace_id_ == other_impl->namespace_id_;
}
// AreaImpl -----------------------------
BrowserDomStorageSystem::AreaImpl::AreaImpl(
const base::WeakPtr<BrowserDomStorageSystem>& parent,
int namespace_id, const GURL& origin)
: parent_(parent),
connection_id_(0) {
if (Host()) {
connection_id_ = (parent_->next_connection_id_)++;
Host()->OpenStorageArea(connection_id_, namespace_id, origin);
}
}
BrowserDomStorageSystem::AreaImpl::~AreaImpl() {
if (Host())
Host()->CloseStorageArea(connection_id_);
}
unsigned BrowserDomStorageSystem::AreaImpl::length() {
if (Host())
return Host()->GetAreaLength(connection_id_);
return 0;
}
WebString BrowserDomStorageSystem::AreaImpl::key(unsigned index) {
if (Host())
return Host()->GetAreaKey(connection_id_, index);
return NullableString16(true);
}
WebString BrowserDomStorageSystem::AreaImpl::getItem(const WebString& key) {
if (Host())
return Host()->GetAreaItem(connection_id_, key);
return NullableString16(true);
}
void BrowserDomStorageSystem::AreaImpl::setItem(
const WebString& key, const WebString& newValue,
const WebURL& pageUrl, Result& result, WebString& oldValue) {
result = ResultBlockedByQuota;
oldValue = NullableString16(true);
if (!Host())
return;
AutoReset<AreaImpl*> auto_reset(&parent_->area_being_processed_, this);
NullableString16 old_value;
if (!Host()->SetAreaItem(connection_id_, key, newValue, pageUrl,
&old_value))
return;
result = ResultOK;
oldValue = old_value;
}
void BrowserDomStorageSystem::AreaImpl::removeItem(
const WebString& key, const WebURL& pageUrl, WebString& oldValue) {
oldValue = NullableString16(true);
if (!Host())
return;
AutoReset<AreaImpl*> auto_reset(&parent_->area_being_processed_, this);
string16 old_value;
if (!Host()->RemoveAreaItem(connection_id_, key, pageUrl, &old_value))
return;
oldValue = old_value;
}
void BrowserDomStorageSystem::AreaImpl::clear(
const WebURL& pageUrl, bool& somethingCleared) {
if (Host()) {
AutoReset<AreaImpl*> auto_reset(&parent_->area_being_processed_, this);
somethingCleared = Host()->ClearArea(connection_id_, pageUrl);
return;
}
somethingCleared = false;
}
// BrowserDomStorageSystem -----------------------------
BrowserDomStorageSystem* BrowserDomStorageSystem::g_instance_;
BrowserDomStorageSystem::BrowserDomStorageSystem()
: weak_factory_(this),
context_(new DomStorageContext(FilePath(), FilePath(), NULL, NULL)),
host_(new DomStorageHost(context_)),
area_being_processed_(NULL),
next_connection_id_(1) {
DCHECK(!g_instance_);
g_instance_ = this;
context_->AddEventObserver(this);
}
BrowserDomStorageSystem::~BrowserDomStorageSystem() {
g_instance_ = NULL;
host_.reset();
context_->RemoveEventObserver(this);
}
WebStorageNamespace* BrowserDomStorageSystem::CreateLocalStorageNamespace() {
return new NamespaceImpl(weak_factory_.GetWeakPtr());
}
WebStorageNamespace* BrowserDomStorageSystem::CreateSessionStorageNamespace() {
int id = context_->AllocateSessionId();
context_->CreateSessionNamespace(id);
return new NamespaceImpl(weak_factory_.GetWeakPtr(), id);
}
void BrowserDomStorageSystem::OnDomStorageItemSet(
const dom_storage::DomStorageArea* area,
const string16& key,
const string16& new_value,
const NullableString16& old_value,
const GURL& page_url) {
DispatchDomStorageEvent(area, page_url,
NullableString16(key, false),
NullableString16(new_value, false),
old_value);
}
void BrowserDomStorageSystem::OnDomStorageItemRemoved(
const dom_storage::DomStorageArea* area,
const string16& key,
const string16& old_value,
const GURL& page_url) {
DispatchDomStorageEvent(area, page_url,
NullableString16(key, false),
NullableString16(true),
NullableString16(old_value, false));
}
void BrowserDomStorageSystem::OnDomStorageAreaCleared(
const dom_storage::DomStorageArea* area,
const GURL& page_url) {
DispatchDomStorageEvent(area, page_url,
NullableString16(true),
NullableString16(true),
NullableString16(true));
}
void BrowserDomStorageSystem::DispatchDomStorageEvent(
const dom_storage::DomStorageArea* area,
const GURL& page_url,
const NullableString16& key,
const NullableString16& new_value,
const NullableString16& old_value) {
DCHECK(area_being_processed_);
if (area->namespace_id() == dom_storage::kLocalStorageNamespaceId) {
WebStorageEventDispatcher::dispatchLocalStorageEvent(
key,
old_value,
new_value,
area->origin(),
page_url,
area_being_processed_,
true /* originatedInProcess */);
} else {
NamespaceImpl session_namespace_for_event_dispatch(
base::WeakPtr<BrowserDomStorageSystem>(), area->namespace_id());
WebStorageEventDispatcher::dispatchSessionStorageEvent(
key,
old_value,
new_value,
area->origin(),
page_url,
session_namespace_for_event_dispatch,
area_being_processed_,
true /* originatedInProcess */);
}
}

View File

@@ -0,0 +1,80 @@
// Copyright (c) 2012 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 CEF_LIBCEF_BROWSER_DOM_STORAGE_SYSTEM_H_
#define CEF_LIBCEF_BROWSER_DOM_STORAGE_SYSTEM_H_
#pragma once
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "webkit/dom_storage/dom_storage_context.h"
namespace dom_storage {
class DomStorageHost;
}
namespace WebKit {
class WebStorageNamespace;
}
// Class that composes dom_storage classes together for use
// in simple single process environments like test_shell and DRT.
class BrowserDomStorageSystem
: public dom_storage::DomStorageContext::EventObserver {
public:
static BrowserDomStorageSystem& instance() { return *g_instance_; }
BrowserDomStorageSystem();
virtual ~BrowserDomStorageSystem();
// The Create<<>> calls are bound to WebKit api that the embedder
// is responsible for implementing. These factories are called strictly
// on the 'main' webkit thread. Ditto the methods on the returned
// objects. SimplDomStorageSystem manufactures implementations of the
// WebStorageNamespace and WebStorageArea interfaces that ultimately
// plumb Get, Set, Remove, and Clear javascript calls to the dom_storage
// classes. The caller (webkit/webcore) takes ownership of the returned
// instances and will delete them when done.
WebKit::WebStorageNamespace* CreateLocalStorageNamespace();
WebKit::WebStorageNamespace* CreateSessionStorageNamespace();
private:
// Inner classes that implement the WebKit WebStorageNamespace and
// WebStorageArea interfaces in terms of dom_storage classes.
class NamespaceImpl;
class AreaImpl;
// DomStorageContext::EventObserver implementation which
// calls into webkit/webcore to dispatch events.
virtual void OnDomStorageItemSet(
const dom_storage::DomStorageArea* area,
const string16& key,
const string16& new_value,
const NullableString16& old_value,
const GURL& page_url) OVERRIDE;
virtual void OnDomStorageItemRemoved(
const dom_storage::DomStorageArea* area,
const string16& key,
const string16& old_value,
const GURL& page_url) OVERRIDE;
virtual void OnDomStorageAreaCleared(
const dom_storage::DomStorageArea* area,
const GURL& page_url) OVERRIDE;
void DispatchDomStorageEvent(
const dom_storage::DomStorageArea* area,
const GURL& page_url,
const NullableString16& key,
const NullableString16& new_value,
const NullableString16& old_value);
base::WeakPtrFactory<BrowserDomStorageSystem> weak_factory_;
scoped_refptr<dom_storage::DomStorageContext> context_;
scoped_ptr<dom_storage::DomStorageHost> host_;
AreaImpl* area_being_processed_;
int next_connection_id_;
static BrowserDomStorageSystem* g_instance_;
};
#endif // CEF_LIBCEF_BROWSER_DOM_STORAGE_SYSTEM_H_

View File

@@ -210,9 +210,7 @@ void BrowserFileSystem::CleanupOnIOThread() {
FileSystemOperationInterface* BrowserFileSystem::GetNewOperation(
const WebURL& url) {
return file_system_context_->CreateFileSystemOperation(
GURL(url),
base::MessageLoopProxy::current());
return file_system_context_->CreateFileSystemOperation(GURL(url));
}
FileSystemOperationInterface::StatusCallback

View File

@@ -37,9 +37,6 @@ class BrowserFileWriter::IOThreadProxy
main_thread_ = base::MessageLoopProxy::current();
}
virtual ~IOThreadProxy() {
}
void Truncate(const GURL& path, int64 offset) {
if (!io_thread_->BelongsToCurrentThread()) {
io_thread_->PostTask(
@@ -82,8 +79,11 @@ class BrowserFileWriter::IOThreadProxy
}
private:
friend class base::RefCountedThreadSafe<IOThreadProxy>;
virtual ~IOThreadProxy() {}
FileSystemOperationInterface* GetNewOperation(const GURL& path) {
return file_system_context_->CreateFileSystemOperation(path, io_thread_);
return file_system_context_->CreateFileSystemOperation(path);
}
void DidSucceedOnMainThread() {

View File

@@ -180,8 +180,8 @@ CefBrowserImpl::CefBrowserImpl(const CefWindowInfo& windowInfo,
popup_delegate_.reset(new BrowserWebViewDelegate(this));
nav_controller_.reset(new BrowserNavigationController(this));
request_context_proxy_ =
new BrowserRequestContextProxy(_Context->request_context(), this);
request_context_proxy_.reset(
new BrowserRequestContextProxy(_Context->request_context(), this));
if (!file_system_root_.CreateUniqueTempDir()) {
LOG(WARNING) << "Failed to create a temp dir for the filesystem."
@@ -785,7 +785,7 @@ void CefBrowserImpl::UIT_DestroyBrowser() {
UIT_ClearMainWndHandle();
main_frame_ = NULL;
request_context_proxy_ = NULL;
request_context_proxy_.reset(NULL);
// Remove the reference added in UIT_CreateBrowser().
Release();

View File

@@ -357,7 +357,7 @@ class CefBrowserImpl : public CefBrowser {
void set_popup_rect(const gfx::Rect& rect) { popup_rect_ = rect; }
net::URLRequestContext* request_context_proxy() {
return request_context_proxy_;
return request_context_proxy_.get();
}
static bool ImplementsThreadSafeReferenceCounting() { return true; }
@@ -386,7 +386,7 @@ class CefBrowserImpl : public CefBrowser {
scoped_ptr<BrowserDevToolsAgent> dev_tools_agent_;
scoped_ptr<BrowserDevToolsClient> dev_tools_client_;
scoped_refptr<BrowserRequestContextProxy> request_context_proxy_;
scoped_ptr<BrowserRequestContextProxy> request_context_proxy_;
CefString title_;

View File

@@ -80,7 +80,7 @@ bool CefBrowserImpl::UIT_CreateBrowser(const CefString& url) {
window_info_.m_ParentWidget = parentView;
}
WebPreferences prefs;
webkit_glue::WebPreferences prefs;
BrowserToWebSettings(settings_, prefs);
// Create the webview host object

View File

@@ -93,7 +93,7 @@ bool CefBrowserImpl::UIT_CreateBrowser(const CefString& url) {
paint_delegate_.reset(new PaintDelegate(this));
}
WebPreferences prefs;
webkit_glue::WebPreferences prefs;
BrowserToWebSettings(settings_, prefs);
// Create the webview host object

View File

@@ -197,7 +197,7 @@ bool CefBrowserImpl::UIT_CreateBrowser(const CefString& url) {
// Add the new browser to the list maintained by the context
_Context->AddBrowser(this);
WebPreferences prefs;
webkit_glue::WebPreferences prefs;
BrowserToWebSettings(settings_, prefs);
// Create the webview host object

View File

@@ -73,8 +73,8 @@ net::NetworkDelegate::AuthRequiredResponse
return AUTH_REQUIRED_RESPONSE_NO_ACTION;
}
bool BrowserNetworkDelegate::CanGetCookies(
const net::URLRequest* request,
bool BrowserNetworkDelegate::OnCanGetCookies(
const net::URLRequest& request,
const net::CookieList& cookie_list) {
net::StaticCookiePolicy::Type policy_type = accept_all_cookies_ ?
net::StaticCookiePolicy::ALLOW_ALL_COOKIES :
@@ -82,19 +82,25 @@ bool BrowserNetworkDelegate::CanGetCookies(
net::StaticCookiePolicy policy(policy_type);
int rv = policy.CanGetCookies(
request->url(), request->first_party_for_cookies());
request.url(), request.first_party_for_cookies());
return rv == net::OK;
}
bool BrowserNetworkDelegate::CanSetCookie(const net::URLRequest* request,
const std::string& cookie_line,
net::CookieOptions* options) {
bool BrowserNetworkDelegate::OnCanSetCookie(
const net::URLRequest& request,
const std::string& cookie_line,
net::CookieOptions* options) {
net::StaticCookiePolicy::Type policy_type = accept_all_cookies_ ?
net::StaticCookiePolicy::ALLOW_ALL_COOKIES :
net::StaticCookiePolicy::BLOCK_SETTING_THIRD_PARTY_COOKIES;
net::StaticCookiePolicy policy(policy_type);
int rv = policy.CanSetCookie(
request->url(), request->first_party_for_cookies());
request.url(), request.first_party_for_cookies());
return rv == net::OK;
}
bool BrowserNetworkDelegate::OnCanAccessFile(const net::URLRequest& request,
const FilePath& path) const {
return true;
}

View File

@@ -44,12 +44,13 @@ class BrowserNetworkDelegate : public net::NetworkDelegate {
const net::AuthChallengeInfo& auth_info,
const AuthCallback& callback,
net::AuthCredentials* credentials) OVERRIDE;
virtual bool CanGetCookies(
const net::URLRequest* request,
const net::CookieList& cookie_list) OVERRIDE;
virtual bool CanSetCookie(const net::URLRequest* request,
const std::string& cookie_line,
net::CookieOptions* options) OVERRIDE;
virtual bool OnCanGetCookies(const net::URLRequest& request,
const net::CookieList& cookie_list) OVERRIDE;
virtual bool OnCanSetCookie(const net::URLRequest& request,
const std::string& cookie_line,
net::CookieOptions* options) OVERRIDE;
virtual bool OnCanAccessFile(const net::URLRequest& request,
const FilePath& path) const OVERRIDE;
bool accept_all_cookies_;
};

View File

@@ -1,792 +0,0 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2011 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 "libcef/browser_persistent_cookie_store.h"
#include <algorithm>
#include <list>
#include <map>
#include <set>
#include <utility>
#include "libcef/cef_thread.h"
#include "base/basictypes.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram.h"
#include "base/string_util.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
#include "googleurl/src/gurl.h"
#include "net/base/registry_controlled_domain.h"
#include "sql/meta_table.h"
#include "sql/statement.h"
#include "sql/transaction.h"
using base::Time;
// This class is designed to be shared between any calling threads and the
// database thread. It batches operations and commits them on a timer.
//
// BrowserPersistentCookieStore::Load is called to load all cookies. It
// delegates to Backend::Load, which posts a Backend::LoadAndNotifyOnDBThread
// task to the DB thread. This task calls Backend::ChainLoadCookies(), which
// repeatedly posts itself to the DB thread to load each eTLD+1's cookies in
// separate tasks. When this is complete, Backend::NotifyOnIOThread is posted
// to the IO thread, which notifies the caller of BrowserPersistentCookieStore::
// Load that the load is complete.
//
// If a priority load request is invoked via BrowserPersistentCookieStore::
// LoadCookiesForKey, it is delegated to Backend::LoadCookiesForKey, which posts
// Backend::LoadKeyAndNotifyOnDBThread to the DB thread. That routine loads just
// that single domain key (eTLD+1)'s cookies, and posts a Backend::
// NotifyOnIOThread to the IO thread to notify the caller of
// BrowserPersistentCookieStore::LoadCookiesForKey that that load is complete.
//
// Subsequent to loading, mutations may be queued by any thread using
// AddCookie, UpdateCookieAccessTime, and DeleteCookie. These are flushed to
// disk on the DB thread every 30 seconds, 512 operations, or call to Flush(),
// whichever occurs first.
class BrowserPersistentCookieStore::Backend
: public base::RefCountedThreadSafe<BrowserPersistentCookieStore::Backend> {
public:
Backend(const FilePath& path, bool restore_old_session_cookies)
: path_(path),
db_(NULL),
num_pending_(0),
clear_local_state_on_exit_(false),
initialized_(false),
restore_old_session_cookies_(restore_old_session_cookies) {
}
// Creates or loads the SQLite database.
void Load(const LoadedCallback& loaded_callback);
// Loads cookies for the domain key (eTLD+1).
void LoadCookiesForKey(const std::string& domain,
const LoadedCallback& loaded_callback);
// Batch a cookie addition.
void AddCookie(const net::CookieMonster::CanonicalCookie& cc);
// Batch a cookie access time update.
void UpdateCookieAccessTime(const net::CookieMonster::CanonicalCookie& cc);
// Batch a cookie deletion.
void DeleteCookie(const net::CookieMonster::CanonicalCookie& cc);
// Commit pending operations as soon as possible.
void Flush(const base::Closure& callback);
// Commit any pending operations and close the database. This must be called
// before the object is destructed.
void Close();
void SetClearLocalStateOnExit(bool clear_local_state);
private:
friend class base::RefCountedThreadSafe<
BrowserPersistentCookieStore::Backend>;
// You should call Close() before destructing this object.
~Backend() {
DCHECK(!db_.get()) << "Close should have already been called.";
DCHECK(num_pending_ == 0 && pending_.empty());
}
// Database upgrade statements.
bool EnsureDatabaseVersion();
class PendingOperation {
public:
typedef enum {
COOKIE_ADD,
COOKIE_UPDATEACCESS,
COOKIE_DELETE,
} OperationType;
PendingOperation(OperationType op,
const net::CookieMonster::CanonicalCookie& cc)
: op_(op), cc_(cc) { }
OperationType op() const { return op_; }
const net::CookieMonster::CanonicalCookie& cc() const { return cc_; }
private:
OperationType op_;
net::CookieMonster::CanonicalCookie cc_;
};
private:
// Creates or loads the SQLite database on DB thread.
void LoadAndNotifyOnDBThread(const LoadedCallback& loaded_callback);
// Loads cookies for the domain key (eTLD+1) on DB thread.
void LoadKeyAndNotifyOnDBThread(const std::string& domains,
const LoadedCallback& loaded_callback);
// Notifies the CookieMonster when loading completes for a specific domain key
// or for all domain keys. Triggers the callback and passes it all cookies
// that have been loaded from DB since last IO notification.
void NotifyOnIOThread(
const LoadedCallback& loaded_callback,
bool load_success);
// Initialize the data base.
bool InitializeDatabase();
// Loads cookies for the next domain key from the DB, then either reschedules
// itself or schedules the provided callback to run on the IO thread (if all
// domains are loaded).
void ChainLoadCookies(const LoadedCallback& loaded_callback);
// Load all cookies for a set of domains/hosts
bool LoadCookiesForDomains(const std::set<std::string>& key);
// Batch a cookie operation (add or delete)
void BatchOperation(PendingOperation::OperationType op,
const net::CookieMonster::CanonicalCookie& cc);
// Commit our pending operations to the database.
void Commit();
// Close() executed on the background thread.
void InternalBackgroundClose();
void DeleteSessionCookies();
FilePath path_;
scoped_ptr<sql::Connection> db_;
sql::MetaTable meta_table_;
typedef std::list<PendingOperation*> PendingOperationsList;
PendingOperationsList pending_;
PendingOperationsList::size_type num_pending_;
// True if the persistent store should be deleted upon destruction.
bool clear_local_state_on_exit_;
// Guard |cookies_|, |pending_|, |num_pending_|, |clear_local_state_on_exit_|
base::Lock lock_;
// Temporary buffer for cookies loaded from DB. Accumulates cookies to reduce
// the number of messages sent to the IO thread. Sent back in response to
// individual load requests for domain keys or when all loading completes.
std::vector<net::CookieMonster::CanonicalCookie*> cookies_;
// Map of domain keys(eTLD+1) to domains/hosts that are to be loaded from DB.
std::map<std::string, std::set<std::string> > keys_to_load_;
// Indicates if DB has been initialized.
bool initialized_;
// If false, we should filter out session cookies when reading the DB.
bool restore_old_session_cookies_;
DISALLOW_COPY_AND_ASSIGN(Backend);
};
// Version number of the database.
//
// Version 5 adds the columns has_expires and is_persistent, so that the
// database can store session cookies as well as persistent cookies. Databases
// of version 5 are incompatible with older versions of code. If a database of
// version 5 is read by older code, session cookies will be treated as normal
// cookies.
//
// In version 4, we migrated the time epoch. If you open the DB with an older
// version on Mac or Linux, the times will look wonky, but the file will likely
// be usable. On Windows version 3 and 4 are the same.
//
// Version 3 updated the database to include the last access time, so we can
// expire them in decreasing order of use when we've reached the maximum
// number of cookies.
static const int kCurrentVersionNumber = 5;
static const int kCompatibleVersionNumber = 5;
namespace {
// Initializes the cookies table, returning true on success.
bool InitTable(sql::Connection* db) {
if (!db->DoesTableExist("cookies")) {
if (!db->Execute("CREATE TABLE cookies ("
"creation_utc INTEGER NOT NULL UNIQUE PRIMARY KEY,"
"host_key TEXT NOT NULL,"
"name TEXT NOT NULL,"
"value TEXT NOT NULL,"
"path TEXT NOT NULL,"
"expires_utc INTEGER NOT NULL,"
"secure INTEGER NOT NULL,"
"httponly INTEGER NOT NULL,"
"last_access_utc INTEGER NOT NULL, "
"has_expires INTEGER NOT NULL DEFAULT 1, "
"persistent INTEGER NOT NULL DEFAULT 1)"))
return false;
}
// Older code created an index on creation_utc, which is already
// primary key for the table.
if (!db->Execute("DROP INDEX IF EXISTS cookie_times"))
return false;
if (!db->Execute("CREATE INDEX IF NOT EXISTS domain ON cookies(host_key)"))
return false;
return true;
}
} // namespace
void BrowserPersistentCookieStore::Backend::Load(
const LoadedCallback& loaded_callback) {
// This function should be called only once per instance.
DCHECK(!db_.get());
CefThread::PostTask(
CefThread::FILE, FROM_HERE,
base::Bind(&Backend::LoadAndNotifyOnDBThread, this, loaded_callback));
}
void BrowserPersistentCookieStore::Backend::LoadCookiesForKey(
const std::string& key,
const LoadedCallback& loaded_callback) {
CefThread::PostTask(
CefThread::FILE, FROM_HERE,
base::Bind(&Backend::LoadKeyAndNotifyOnDBThread, this,
key,
loaded_callback));
}
void BrowserPersistentCookieStore::Backend::LoadAndNotifyOnDBThread(
const LoadedCallback& loaded_callback) {
DCHECK(CefThread::CurrentlyOn(CefThread::FILE));
if (!InitializeDatabase()) {
CefThread::PostTask(
CefThread::IO, FROM_HERE,
base::Bind(&BrowserPersistentCookieStore::Backend::NotifyOnIOThread,
this, loaded_callback, false));
} else {
ChainLoadCookies(loaded_callback);
}
}
void BrowserPersistentCookieStore::Backend::LoadKeyAndNotifyOnDBThread(
const std::string& key,
const LoadedCallback& loaded_callback) {
DCHECK(CefThread::CurrentlyOn(CefThread::FILE));
bool success = false;
if (InitializeDatabase()) {
std::map<std::string, std::set<std::string> >::iterator
it = keys_to_load_.find(key);
if (it != keys_to_load_.end()) {
success = LoadCookiesForDomains(it->second);
keys_to_load_.erase(it);
} else {
success = true;
}
}
CefThread::PostTask(
CefThread::IO, FROM_HERE,
base::Bind(&BrowserPersistentCookieStore::Backend::NotifyOnIOThread,
this, loaded_callback, success));
}
void BrowserPersistentCookieStore::Backend::NotifyOnIOThread(
const LoadedCallback& loaded_callback,
bool load_success) {
DCHECK(CefThread::CurrentlyOn(CefThread::IO));
std::vector<net::CookieMonster::CanonicalCookie*> cookies;
{
base::AutoLock locked(lock_);
cookies.swap(cookies_);
}
loaded_callback.Run(cookies);
}
bool BrowserPersistentCookieStore::Backend::InitializeDatabase() {
DCHECK(CefThread::CurrentlyOn(CefThread::FILE));
if (initialized_) {
// Return false if we were previously initialized but the DB has since been
// closed.
return db_.get() ? true : false;
}
const FilePath dir = path_.DirName();
if (!file_util::PathExists(dir) && !file_util::CreateDirectory(dir)) {
return false;
}
db_.reset(new sql::Connection);
if (!db_->Open(path_)) {
NOTREACHED() << "Unable to open cookie DB.";
db_.reset();
return false;
}
// db_->set_error_delegate(GetErrorHandlerForCookieDb());
if (!EnsureDatabaseVersion() || !InitTable(db_.get())) {
NOTREACHED() << "Unable to open cookie DB.";
db_.reset();
return false;
}
// Retrieve all the domains
sql::Statement smt(db_->GetUniqueStatement(
"SELECT DISTINCT host_key FROM cookies"));
if (!smt.is_valid()) {
smt.Clear(); // Disconnect smt_ref from db_.
db_.reset();
return false;
}
// Build a map of domain keys (always eTLD+1) to domains.
while (smt.Step()) {
std::string domain = smt.ColumnString(0);
std::string key =
net::RegistryControlledDomainService::GetDomainAndRegistry(domain);
std::map<std::string, std::set<std::string> >::iterator it =
keys_to_load_.find(key);
if (it == keys_to_load_.end())
it = keys_to_load_.insert(std::make_pair
(key, std::set<std::string>())).first;
it->second.insert(domain);
}
initialized_ = true;
return true;
}
void BrowserPersistentCookieStore::Backend::ChainLoadCookies(
const LoadedCallback& loaded_callback) {
DCHECK(CefThread::CurrentlyOn(CefThread::FILE));
bool load_success = true;
if (!db_.get()) {
// Close() has been called on this store.
load_success = false;
} else if (keys_to_load_.size() > 0) {
// Load cookies for the first domain key.
std::map<std::string, std::set<std::string> >::iterator
it = keys_to_load_.begin();
load_success = LoadCookiesForDomains(it->second);
keys_to_load_.erase(it);
}
// If load is successful and there are more domain keys to be loaded,
// then post a DB task to continue chain-load;
// Otherwise notify on IO thread.
if (load_success && keys_to_load_.size() > 0) {
CefThread::PostTask(
CefThread::FILE, FROM_HERE,
base::Bind(&Backend::ChainLoadCookies, this, loaded_callback));
} else {
CefThread::PostTask(
CefThread::IO, FROM_HERE,
base::Bind(&BrowserPersistentCookieStore::Backend::NotifyOnIOThread,
this, loaded_callback, load_success));
if (load_success && !restore_old_session_cookies_)
DeleteSessionCookies();
}
}
bool BrowserPersistentCookieStore::Backend::LoadCookiesForDomains(
const std::set<std::string>& domains) {
DCHECK(CefThread::CurrentlyOn(CefThread::FILE));
sql::Statement smt;
if (restore_old_session_cookies_) {
smt.Assign(db_->GetCachedStatement(
SQL_FROM_HERE,
"SELECT creation_utc, host_key, name, value, path, expires_utc, "
"secure, httponly, last_access_utc, has_expires, persistent "
"FROM cookies WHERE host_key = ?"));
} else {
smt.Assign(db_->GetCachedStatement(
SQL_FROM_HERE,
"SELECT creation_utc, host_key, name, value, path, expires_utc, "
"secure, httponly, last_access_utc, has_expires, persistent "
"FROM cookies WHERE host_key = ? AND persistent = 1"));
}
if (!smt.is_valid()) {
NOTREACHED() << "select statement prep failed";
smt.Clear(); // Disconnect smt_ref from db_.
db_.reset();
return false;
}
std::vector<net::CookieMonster::CanonicalCookie*> cookies;
std::set<std::string>::const_iterator it = domains.begin();
for (; it != domains.end(); ++it) {
smt.BindString(0, *it);
while (smt.Step()) {
scoped_ptr<net::CookieMonster::CanonicalCookie> cc(
new net::CookieMonster::CanonicalCookie(
// The "source" URL is not used with persisted cookies.
GURL(), // Source
smt.ColumnString(2), // name
smt.ColumnString(3), // value
smt.ColumnString(1), // domain
smt.ColumnString(4), // path
std::string(), // TODO(abarth): Persist mac_key
std::string(), // TODO(abarth): Persist mac_algorithm
Time::FromInternalValue(smt.ColumnInt64(0)), // creation_utc
Time::FromInternalValue(smt.ColumnInt64(5)), // expires_utc
Time::FromInternalValue(smt.ColumnInt64(8)), // last_access_utc
smt.ColumnInt(6) != 0, // secure
smt.ColumnInt(7) != 0, // httponly
smt.ColumnInt(9) != 0, // has_expires
smt.ColumnInt(10) != 0)); // is_persistent
DLOG_IF(WARNING,
cc->CreationDate() > Time::Now()) << L"CreationDate too recent";
cookies.push_back(cc.release());
}
smt.Reset();
}
{
base::AutoLock locked(lock_);
cookies_.insert(cookies_.end(), cookies.begin(), cookies.end());
}
return true;
}
bool BrowserPersistentCookieStore::Backend::EnsureDatabaseVersion() {
// Version check.
if (!meta_table_.Init(
db_.get(), kCurrentVersionNumber, kCompatibleVersionNumber)) {
return false;
}
if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) {
LOG(WARNING) << "Cookie database is too new.";
return false;
}
int cur_version = meta_table_.GetVersionNumber();
if (cur_version == 2) {
sql::Transaction transaction(db_.get());
if (!transaction.Begin())
return false;
if (!db_->Execute("ALTER TABLE cookies ADD COLUMN last_access_utc "
"INTEGER DEFAULT 0") ||
!db_->Execute("UPDATE cookies SET last_access_utc = creation_utc")) {
LOG(WARNING) << "Unable to update cookie database to version 3.";
return false;
}
++cur_version;
meta_table_.SetVersionNumber(cur_version);
meta_table_.SetCompatibleVersionNumber(
std::min(cur_version, kCompatibleVersionNumber));
transaction.Commit();
}
if (cur_version == 3) {
// The time epoch changed for Mac & Linux in this version to match Windows.
// This patch came after the main epoch change happened, so some
// developers have "good" times for cookies added by the more recent
// versions. So we have to be careful to only update times that are under
// the old system (which will appear to be from before 1970 in the new
// system). The magic number used below is 1970 in our time units.
sql::Transaction transaction(db_.get());
transaction.Begin();
#if !defined(OS_WIN)
ignore_result(db_->Execute(
"UPDATE cookies "
"SET creation_utc = creation_utc + 11644473600000000 "
"WHERE rowid IN "
"(SELECT rowid FROM cookies WHERE "
"creation_utc > 0 AND creation_utc < 11644473600000000)"));
ignore_result(db_->Execute(
"UPDATE cookies "
"SET expires_utc = expires_utc + 11644473600000000 "
"WHERE rowid IN "
"(SELECT rowid FROM cookies WHERE "
"expires_utc > 0 AND expires_utc < 11644473600000000)"));
ignore_result(db_->Execute(
"UPDATE cookies "
"SET last_access_utc = last_access_utc + 11644473600000000 "
"WHERE rowid IN "
"(SELECT rowid FROM cookies WHERE "
"last_access_utc > 0 AND last_access_utc < 11644473600000000)"));
#endif
++cur_version;
meta_table_.SetVersionNumber(cur_version);
transaction.Commit();
}
if (cur_version == 4) {
sql::Transaction transaction(db_.get());
if (!transaction.Begin())
return false;
if (!db_->Execute("ALTER TABLE cookies "
"ADD COLUMN has_expires INTEGER DEFAULT 1") ||
!db_->Execute("ALTER TABLE cookies "
"ADD COLUMN persistent INTEGER DEFAULT 1")) {
LOG(WARNING) << "Unable to update cookie database to version 5.";
return false;
}
++cur_version;
meta_table_.SetVersionNumber(cur_version);
meta_table_.SetCompatibleVersionNumber(
std::min(cur_version, kCompatibleVersionNumber));
transaction.Commit();
}
// Put future migration cases here.
// When the version is too old, we just try to continue anyway, there should
// not be a released product that makes a database too old for us to handle.
LOG_IF(WARNING, cur_version < kCurrentVersionNumber) <<
"Cookie database version " << cur_version << " is too old to handle.";
return true;
}
void BrowserPersistentCookieStore::Backend::AddCookie(
const net::CookieMonster::CanonicalCookie& cc) {
BatchOperation(PendingOperation::COOKIE_ADD, cc);
}
void BrowserPersistentCookieStore::Backend::UpdateCookieAccessTime(
const net::CookieMonster::CanonicalCookie& cc) {
BatchOperation(PendingOperation::COOKIE_UPDATEACCESS, cc);
}
void BrowserPersistentCookieStore::Backend::DeleteCookie(
const net::CookieMonster::CanonicalCookie& cc) {
BatchOperation(PendingOperation::COOKIE_DELETE, cc);
}
void BrowserPersistentCookieStore::Backend::BatchOperation(
PendingOperation::OperationType op,
const net::CookieMonster::CanonicalCookie& cc) {
// Commit every 30 seconds.
static const int kCommitIntervalMs = 30 * 1000;
// Commit right away if we have more than 512 outstanding operations.
static const size_t kCommitAfterBatchSize = 512;
DCHECK(!CefThread::CurrentlyOn(CefThread::FILE));
// We do a full copy of the cookie here, and hopefully just here.
scoped_ptr<PendingOperation> po(new PendingOperation(op, cc));
PendingOperationsList::size_type num_pending;
{
base::AutoLock locked(lock_);
pending_.push_back(po.release());
num_pending = ++num_pending_;
}
if (num_pending == 1) {
// We've gotten our first entry for this batch, fire off the timer.
CefThread::PostDelayedTask(
CefThread::FILE, FROM_HERE,
base::Bind(&Backend::Commit, this),
base::TimeDelta::FromMilliseconds(kCommitIntervalMs));
} else if (num_pending == kCommitAfterBatchSize) {
// We've reached a big enough batch, fire off a commit now.
CefThread::PostTask(
CefThread::FILE, FROM_HERE,
base::Bind(&Backend::Commit, this));
}
}
void BrowserPersistentCookieStore::Backend::Commit() {
DCHECK(CefThread::CurrentlyOn(CefThread::FILE));
PendingOperationsList ops;
{
base::AutoLock locked(lock_);
pending_.swap(ops);
num_pending_ = 0;
}
// Maybe an old timer fired or we are already Close()'ed.
if (!db_.get() || ops.empty())
return;
sql::Statement add_smt(db_->GetCachedStatement(SQL_FROM_HERE,
"INSERT INTO cookies (creation_utc, host_key, name, value, path, "
"expires_utc, secure, httponly, last_access_utc, has_expires, "
"persistent) "
"VALUES (?,?,?,?,?,?,?,?,?,?,?)"));
if (!add_smt.is_valid())
return;
sql::Statement update_access_smt(db_->GetCachedStatement(SQL_FROM_HERE,
"UPDATE cookies SET last_access_utc=? WHERE creation_utc=?"));
if (!update_access_smt.is_valid())
return;
sql::Statement del_smt(db_->GetCachedStatement(SQL_FROM_HERE,
"DELETE FROM cookies WHERE creation_utc=?"));
if (!del_smt.is_valid())
return;
sql::Transaction transaction(db_.get());
if (!transaction.Begin())
return;
for (PendingOperationsList::iterator it = ops.begin();
it != ops.end(); ++it) {
// Free the cookies as we commit them to the database.
scoped_ptr<PendingOperation> po(*it);
switch (po->op()) {
case PendingOperation::COOKIE_ADD:
add_smt.Reset();
add_smt.BindInt64(0, po->cc().CreationDate().ToInternalValue());
add_smt.BindString(1, po->cc().Domain());
add_smt.BindString(2, po->cc().Name());
add_smt.BindString(3, po->cc().Value());
add_smt.BindString(4, po->cc().Path());
add_smt.BindInt64(5, po->cc().ExpiryDate().ToInternalValue());
add_smt.BindInt(6, po->cc().IsSecure());
add_smt.BindInt(7, po->cc().IsHttpOnly());
add_smt.BindInt64(8, po->cc().LastAccessDate().ToInternalValue());
add_smt.BindInt(9, po->cc().DoesExpire());
add_smt.BindInt(10, po->cc().IsPersistent());
if (!add_smt.Run())
NOTREACHED() << "Could not add a cookie to the DB.";
break;
case PendingOperation::COOKIE_UPDATEACCESS:
update_access_smt.Reset();
update_access_smt.BindInt64(0,
po->cc().LastAccessDate().ToInternalValue());
update_access_smt.BindInt64(1,
po->cc().CreationDate().ToInternalValue());
if (!update_access_smt.Run())
NOTREACHED() << "Could not update cookie last access time in the DB.";
break;
case PendingOperation::COOKIE_DELETE:
del_smt.Reset();
del_smt.BindInt64(0, po->cc().CreationDate().ToInternalValue());
if (!del_smt.Run())
NOTREACHED() << "Could not delete a cookie from the DB.";
break;
default:
NOTREACHED();
break;
}
}
transaction.Commit();
}
void BrowserPersistentCookieStore::Backend::Flush(
const base::Closure& callback) {
DCHECK(!CefThread::CurrentlyOn(CefThread::FILE));
CefThread::PostTask(
CefThread::FILE, FROM_HERE, base::Bind(&Backend::Commit, this));
if (!callback.is_null()) {
// We want the completion task to run immediately after Commit() returns.
// Posting it from here means there is less chance of another task getting
// onto the message queue first, than if we posted it from Commit() itself.
CefThread::PostTask(CefThread::FILE, FROM_HERE, callback);
}
}
// Fire off a close message to the background thread. We could still have a
// pending commit timer or Load operations holding references on us, but if/when
// this fires we will already have been cleaned up and it will be ignored.
void BrowserPersistentCookieStore::Backend::Close() {
if (CefThread::CurrentlyOn(CefThread::FILE)) {
InternalBackgroundClose();
} else {
// Must close the backend on the background thread.
CefThread::PostTask(
CefThread::FILE, FROM_HERE,
base::Bind(&Backend::InternalBackgroundClose, this));
}
}
void BrowserPersistentCookieStore::Backend::InternalBackgroundClose() {
DCHECK(CefThread::CurrentlyOn(CefThread::FILE));
// Commit any pending operations
Commit();
db_.reset();
if (clear_local_state_on_exit_)
file_util::Delete(path_, false);
}
void BrowserPersistentCookieStore::Backend::SetClearLocalStateOnExit(
bool clear_local_state) {
base::AutoLock locked(lock_);
clear_local_state_on_exit_ = clear_local_state;
}
void BrowserPersistentCookieStore::Backend::DeleteSessionCookies() {
DCHECK(CefThread::CurrentlyOn(CefThread::FILE));
if (!db_->Execute("DELETE FROM cookies WHERE persistent == 0"))
LOG(WARNING) << "Unable to delete session cookies.";
}
BrowserPersistentCookieStore::BrowserPersistentCookieStore(
const FilePath& path,
bool restore_old_session_cookies)
: backend_(new Backend(path, restore_old_session_cookies)) {
}
BrowserPersistentCookieStore::~BrowserPersistentCookieStore() {
if (backend_.get()) {
backend_->Close();
// Release our reference, it will probably still have a reference if the
// background thread has not run Close() yet.
backend_ = NULL;
}
}
void BrowserPersistentCookieStore::Load(const LoadedCallback& loaded_callback) {
backend_->Load(loaded_callback);
}
void BrowserPersistentCookieStore::LoadCookiesForKey(
const std::string& key,
const LoadedCallback& loaded_callback) {
backend_->LoadCookiesForKey(key, loaded_callback);
}
void BrowserPersistentCookieStore::AddCookie(
const net::CookieMonster::CanonicalCookie& cc) {
if (backend_.get())
backend_->AddCookie(cc);
}
void BrowserPersistentCookieStore::UpdateCookieAccessTime(
const net::CookieMonster::CanonicalCookie& cc) {
if (backend_.get())
backend_->UpdateCookieAccessTime(cc);
}
void BrowserPersistentCookieStore::DeleteCookie(
const net::CookieMonster::CanonicalCookie& cc) {
if (backend_.get())
backend_->DeleteCookie(cc);
}
void BrowserPersistentCookieStore::SetClearLocalStateOnExit(
bool clear_local_state) {
if (backend_.get())
backend_->SetClearLocalStateOnExit(clear_local_state);
}
void BrowserPersistentCookieStore::Flush(const base::Closure& callback) {
if (backend_.get())
backend_->Flush(callback);
else if (!callback.is_null())
MessageLoop::current()->PostTask(FROM_HERE, callback);
}

View File

@@ -1,63 +0,0 @@
// Copyright (c) 2011 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.
// A sqlite implementation of a cookie monster persistent store.
// This class is based on src/chrome/browser/net/
// sqlite_persistent_cookie_store.h
// with the following modifications for use in the cef:
// - BrowserThread has been replaced with CefThread
// - Performance diagnostic code has been removed (UMA_HISTOGRAM_ENUMERATION)
#ifndef CEF_LIBCEF_BROWSER_PERSISTENT_COOKIE_STORE_H_
#define CEF_LIBCEF_BROWSER_PERSISTENT_COOKIE_STORE_H_
#pragma once
#include <string>
#include <vector>
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "net/cookies/cookie_monster.h"
class FilePath;
class Task;
// Implements the PersistentCookieStore interface in terms of a SQLite database.
// For documentation about the actual member functions consult the documentation
// of the parent class |net::CookieMonster::PersistentCookieStore|.
class BrowserPersistentCookieStore
: public net::CookieMonster::PersistentCookieStore {
public:
BrowserPersistentCookieStore(const FilePath& path,
bool restore_old_session_cookies);
virtual ~BrowserPersistentCookieStore();
virtual void Load(const LoadedCallback& loaded_callback) OVERRIDE;
virtual void LoadCookiesForKey(const std::string& key,
const LoadedCallback& callback) OVERRIDE;
virtual void AddCookie(
const net::CookieMonster::CanonicalCookie& cc) OVERRIDE;
virtual void UpdateCookieAccessTime(
const net::CookieMonster::CanonicalCookie& cc) OVERRIDE;
virtual void DeleteCookie(
const net::CookieMonster::CanonicalCookie& cc) OVERRIDE;
virtual void SetClearLocalStateOnExit(bool clear_local_state) OVERRIDE;
virtual void Flush(const base::Closure& callback) OVERRIDE;
private:
class Backend;
scoped_refptr<Backend> backend_;
DISALLOW_COPY_AND_ASSIGN(BrowserPersistentCookieStore);
};
#endif // CEF_LIBCEF_BROWSER_PERSISTENT_COOKIE_STORE_H_

View File

@@ -10,7 +10,6 @@
#endif
#include "libcef/browser_file_system.h"
#include "libcef/browser_persistent_cookie_store.h"
#include "libcef/browser_resource_loader_bridge.h"
#include "libcef/cef_context.h"
#include "libcef/cef_thread.h"
@@ -18,7 +17,9 @@
#include "base/compiler_specific.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/threading/worker_pool.h"
#include "build/build_config.h"
#include "chrome/browser/net/sqlite_persistent_cookie_store.h"
#include "net/base/cert_verifier.h"
#include "net/cookies/cookie_monster.h"
#include "net/base/default_server_bound_cert_store.h"
@@ -157,7 +158,8 @@ void BrowserRequestContext::Init(
SetCookieStoragePath(cache_path);
storage_.set_server_bound_cert_service(new net::ServerBoundCertService(
new net::DefaultServerBoundCertStore(NULL)));
new net::DefaultServerBoundCertStore(NULL),
base::WorkerPool::GetTaskRunner(true)));
// hard-code A-L and A-C for test shells
set_accept_language("en-us,en");
@@ -243,15 +245,16 @@ void BrowserRequestContext::Init(
new net::HttpCache(host_resolver(),
cert_verifier(),
server_bound_cert_service(),
NULL, // transport_security_state
NULL, /* transport_security_state */
proxy_service(),
"", // ssl_session_cache_shard
"", /* ssl_session_cache_shard */
ssl_config_service(),
http_auth_handler_factory(),
NULL, // network_delegate
NULL, /* network_delegate */
http_server_properties(),
NULL, // netlog
backend);
NULL, /* netlog */
backend,
"" /* trusted_spdy_proxy */ );
cache->set_mode(cache_mode);
storage_.set_http_transaction_factory(cache);
@@ -275,8 +278,7 @@ void BrowserRequestContext::Init(
job_factory->SetProtocolHandler(
"filesystem",
fileapi::CreateFileSystemProtocolHandler(
file_system->file_system_context(),
CefThread::GetMessageLoopProxyForThread(CefThread::FILE)));
file_system->file_system_context()));
}
storage_.set_job_factory(job_factory);
@@ -297,11 +299,11 @@ void BrowserRequestContext::SetCookieStoragePath(const FilePath& path) {
return;
}
scoped_refptr<BrowserPersistentCookieStore> persistent_store;
scoped_refptr<SQLitePersistentCookieStore> persistent_store;
if (!path.empty()) {
if (file_util::CreateDirectory(path)) {
const FilePath& cookie_path = path.AppendASCII("Cookies");
persistent_store = new BrowserPersistentCookieStore(cookie_path, false);
persistent_store = new SQLitePersistentCookieStore(cookie_path, false);
} else {
NOTREACHED() << "The cookie storage directory could not be created";
}

View File

@@ -73,6 +73,7 @@
#include "webkit/fileapi/file_system_dir_url_request_job.h"
#include "webkit/fileapi/file_system_url_request_job.h"
#include "webkit/glue/resource_loader_bridge.h"
#include "webkit/glue/webkit_glue.h"
#if defined(OS_MACOSX) || defined(OS_WIN)
#include "crypto/nss_util.h"
@@ -95,6 +96,7 @@ struct RequestParams {
GURL url;
GURL first_party_for_cookies;
GURL referrer;
WebKit::WebReferrerPolicy referrer_policy;
std::string headers;
int load_flags;
ResourceType::Type request_type;
@@ -562,6 +564,8 @@ class RequestProxy : public net::URLRequest::Delegate,
request_->set_method(params->method);
request_->set_first_party_for_cookies(params->first_party_for_cookies);
request_->set_referrer(params->referrer.spec());
webkit_glue::ConfigureURLRequestForReferrerPolicy(
request_.get(), params->referrer_policy);
net::HttpRequestHeaders headers;
headers.AddHeadersFromString(params->headers);
request_->SetExtraRequestHeaders(headers);
@@ -982,6 +986,7 @@ class ResourceLoaderBridgeImpl : public ResourceLoaderBridge {
params_->url = request_info.url;
params_->first_party_for_cookies = request_info.first_party_for_cookies;
params_->referrer = request_info.referrer;
params_->referrer_policy = request_info.referrer_policy;
params_->headers = request_info.headers;
params_->load_flags = request_info.load_flags;
params_->request_type = request_info.request_type;

View File

@@ -7,26 +7,40 @@
#include "base/utf_string_conversions.h"
#include "webkit/glue/webpreferences.h"
using webkit_glue::WebPreferences;
void BrowserToWebSettings(const CefBrowserSettings& cef, WebPreferences& web) {
if (cef.standard_font_family.length > 0)
web.standard_font_family = CefString(&cef.standard_font_family);
else
web.standard_font_family = ASCIIToUTF16("Times");
if (cef.standard_font_family.length > 0) {
web.standard_font_family_map[WebPreferences::kCommonScript] =
CefString(&cef.standard_font_family);
} else {
web.standard_font_family_map[WebPreferences::kCommonScript] =
ASCIIToUTF16("Times");
}
if (cef.fixed_font_family.length > 0)
web.fixed_font_family = CefString(&cef.fixed_font_family);
else
web.fixed_font_family = ASCIIToUTF16("Courier");
if (cef.fixed_font_family.length > 0) {
web.fixed_font_family_map[WebPreferences::kCommonScript] =
CefString(&cef.fixed_font_family);
} else {
web.fixed_font_family_map[WebPreferences::kCommonScript] =
ASCIIToUTF16("Courier");
}
if (cef.serif_font_family.length > 0)
web.serif_font_family = CefString(&cef.serif_font_family);
else
web.serif_font_family = ASCIIToUTF16("Times");
if (cef.serif_font_family.length > 0) {
web.serif_font_family_map[WebPreferences::kCommonScript] =
CefString(&cef.serif_font_family);
} else {
web.serif_font_family_map[WebPreferences::kCommonScript] =
ASCIIToUTF16("Times");
}
if (cef.sans_serif_font_family.length > 0)
web.sans_serif_font_family = CefString(&cef.sans_serif_font_family);
else
web.sans_serif_font_family = ASCIIToUTF16("Helvetica");
if (cef.sans_serif_font_family.length > 0) {
web.sans_serif_font_family_map[WebPreferences::kCommonScript] =
CefString(&cef.sans_serif_font_family);
} else {
web.sans_serif_font_family_map[WebPreferences::kCommonScript] =
ASCIIToUTF16("Helvetica");
}
// These two fonts below are picked from the intersection of
// Win XP font list and Vista font list :
@@ -40,22 +54,26 @@ void BrowserToWebSettings(const CefBrowserSettings& cef, WebPreferences& web) {
// as long as they're available.
if (cef.cursive_font_family.length > 0) {
web.cursive_font_family = CefString(&cef.cursive_font_family);
web.cursive_font_family_map[WebPreferences::kCommonScript] =
CefString(&cef.cursive_font_family);
} else {
web.cursive_font_family_map[WebPreferences::kCommonScript] =
#if defined(OS_MACOSX)
web.cursive_font_family = ASCIIToUTF16("Apple Chancery");
ASCIIToUTF16("Apple Chancery");
#else
web.cursive_font_family = ASCIIToUTF16("Comic Sans MS");
ASCIIToUTF16("Comic Sans MS");
#endif
}
if (cef.fantasy_font_family.length > 0) {
web.fantasy_font_family = CefString(&cef.fantasy_font_family);
web.fantasy_font_family_map[WebPreferences::kCommonScript] =
CefString(&cef.fantasy_font_family);
} else {
web.fantasy_font_family_map[WebPreferences::kCommonScript] =
#if defined(OS_MACOSX)
web.fantasy_font_family = ASCIIToUTF16("Papyrus");
ASCIIToUTF16("Papyrus");
#else
web.fantasy_font_family = ASCIIToUTF16("Impact");
ASCIIToUTF16("Impact");
#endif
}

View File

@@ -7,8 +7,12 @@
#pragma once
#include "include/internal/cef_types_wrappers.h"
struct WebPreferences;
void BrowserToWebSettings(const CefBrowserSettings& cef, WebPreferences& web);
namespace webkit_glue {
struct WebPreferences;
}
void BrowserToWebSettings(const CefBrowserSettings& cef,
webkit_glue::WebPreferences& web);
#endif // CEF_LIBCEF_BROWSER_SETTINGS_H_

View File

@@ -223,14 +223,11 @@ void WebSocketStreamHandleBridgeImpl::DoOnClose() {
void BrowserSocketStreamBridge::InitializeOnIOThread(
net::URLRequestContext* request_context) {
g_io_thread = MessageLoop::current();
if ((g_request_context = request_context))
g_request_context->AddRef();
g_request_context = request_context;
}
void BrowserSocketStreamBridge::Cleanup() {
g_io_thread = NULL;
if (g_request_context)
g_request_context->Release();
g_request_context = NULL;
}

View File

@@ -0,0 +1,68 @@
// Copyright (c) 2012 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 "content/public/browser/browser_thread.h"
#include "libcef/cef_thread.h"
// Stub implementations to convert BrowserThread calls to CefThread.
namespace content {
namespace {
int GetCefId(BrowserThread::ID browser_id) {
switch (browser_id) {
case BrowserThread::UI:
return CefThread::UI;
case BrowserThread::IO:
return CefThread::IO;
case BrowserThread::DB:
case BrowserThread::FILE:
return CefThread::FILE;
default:
break;
}
// The specified BrowserThread ID is not supported.
NOTREACHED();
return -1;
}
} // namespace
// static
bool BrowserThread::PostTask(ID identifier,
const tracked_objects::Location& from_here,
const base::Closure& task) {
int cef_id = GetCefId(identifier);
if (cef_id < 0)
return false;
return CefThread::PostTask(static_cast<CefThread::ID>(cef_id), from_here,
task);
}
// static
bool BrowserThread::PostDelayedTask(ID identifier,
const tracked_objects::Location& from_here,
const base::Closure& task,
base::TimeDelta delay) {
int cef_id = GetCefId(identifier);
if (cef_id < 0)
return false;
return CefThread::PostDelayedTask(static_cast<CefThread::ID>(cef_id),
from_here, task, delay);
}
// static
bool BrowserThread::CurrentlyOn(ID identifier) {
int cef_id = GetCefId(identifier);
if (cef_id < 0)
return false;
return CefThread::CurrentlyOn(static_cast<CefThread::ID>(cef_id));
}
} // namespace content

View File

@@ -66,6 +66,9 @@ void BrowserWebBlobRegistryImpl::unregisterBlobURL(const WebURL& url) {
thread_safe_url));
}
BrowserWebBlobRegistryImpl::~BrowserWebBlobRegistryImpl() {
}
void BrowserWebBlobRegistryImpl::AddFinishedBlob(
const GURL& url, BlobData* blob_data) {
DCHECK(g_blob_storage_controller);

View File

@@ -33,6 +33,9 @@ class BrowserWebBlobRegistryImpl
const WebKit::WebURL& src_url);
virtual void unregisterBlobURL(const WebKit::WebURL& url);
protected:
virtual ~BrowserWebBlobRegistryImpl();
private:
friend class base::RefCountedThreadSafe<BrowserWebBlobRegistryImpl>;

View File

@@ -7,7 +7,6 @@
#include "libcef/browser_resource_loader_bridge.h"
#include "libcef/browser_socket_stream_bridge.h"
#include "libcef/browser_webkit_glue.h"
#include "libcef/browser_webstoragenamespace_impl.h"
#include "libcef/cef_context.h"
#include "base/metrics/stats_counters.h"
@@ -198,22 +197,7 @@ WebKit::WebString BrowserWebKitInit::defaultLocale() {
WebKit::WebStorageNamespace* BrowserWebKitInit::createLocalStorageNamespace(
const WebKit::WebString& path, unsigned quota) {
#ifdef ENABLE_NEW_DOM_STORAGE_BACKEND
NOTREACHED();
#else
return new BrowserWebStorageNamespaceImpl(DOM_STORAGE_LOCAL);
#endif
}
void BrowserWebKitInit::dispatchStorageEvent(const WebKit::WebString& key,
const WebKit::WebString& old_value, const WebKit::WebString& new_value,
const WebKit::WebString& origin, const WebKit::WebURL& url,
bool is_local_storage) {
// All events are dispatched by the WebCore::StorageAreaProxy in the
// simple single process case.
#ifdef ENABLE_NEW_DOM_STORAGE_BACKEND
NOTREACHED();
#endif
return dom_storage_system_.CreateLocalStorageNamespace();
}
WebKit::WebIDBFactory* BrowserWebKitInit::idbFactory() {
@@ -222,13 +206,11 @@ WebKit::WebIDBFactory* BrowserWebKitInit::idbFactory() {
void BrowserWebKitInit::createIDBKeysFromSerializedValuesAndKeyPath(
const WebKit::WebVector<WebKit::WebSerializedScriptValue>& values,
const WebKit::WebString& keyPath,
const WebKit::WebIDBKeyPath& keyPath,
WebKit::WebVector<WebKit::WebIDBKey>& keys_out) {
WebKit::WebVector<WebKit::WebIDBKey> keys(values.size());
for (size_t i = 0; i < values.size(); ++i) {
keys[i] = WebKit::WebIDBKey::createFromValueAndKeyPath(
values[i], WebKit::WebIDBKeyPath::create(keyPath));
}
for (size_t i = 0; i < values.size(); ++i)
keys[i] = WebKit::WebIDBKey::createFromValueAndKeyPath(values[i], keyPath);
keys_out.swap(keys);
}
@@ -236,9 +218,9 @@ WebKit::WebSerializedScriptValue
BrowserWebKitInit::injectIDBKeyIntoSerializedValue(
const WebKit::WebIDBKey& key,
const WebKit::WebSerializedScriptValue& value,
const WebKit::WebString& keyPath) {
const WebKit::WebIDBKeyPath& keyPath) {
return WebKit::WebIDBKey::injectIDBKeyIntoSerializedValue(
key, value, WebKit::WebIDBKeyPath::create(keyPath));
key, value, keyPath);
}
WebKit::WebGraphicsContext3D*
@@ -264,6 +246,11 @@ base::StringPiece BrowserWebKitInit::GetDataResource(int resource_id) {
return _Context->GetDataResource(resource_id);
}
base::StringPiece BrowserWebKitInit::GetImageResource(int resource_id,
float scale_factor) {
return GetDataResource(resource_id);
}
webkit_glue::ResourceLoaderBridge* BrowserWebKitInit::CreateResourceLoader(
const webkit_glue::ResourceLoaderBridge::RequestInfo& request_info) {
return BrowserResourceLoaderBridge::Create(request_info);

View File

@@ -11,6 +11,7 @@
#include "libcef/browser_appcache_system.h"
#include "libcef/browser_database_system.h"
#include "libcef/browser_dom_storage_system.h"
#include "libcef/browser_file_system.h"
#include "libcef/browser_webblobregistry_impl.h"
#include "libcef/browser_webcookiejar_impl.h"
@@ -63,23 +64,21 @@ class BrowserWebKitInit : public webkit_glue::WebKitPlatformSupportImpl {
virtual WebKit::WebString defaultLocale() OVERRIDE;
virtual WebKit::WebStorageNamespace* createLocalStorageNamespace(
const WebKit::WebString& path, unsigned quota) OVERRIDE;
void dispatchStorageEvent(const WebKit::WebString& key,
const WebKit::WebString& old_value, const WebKit::WebString& new_value,
const WebKit::WebString& origin, const WebKit::WebURL& url,
bool is_local_storage) OVERRIDE;
virtual WebKit::WebIDBFactory* idbFactory() OVERRIDE;
virtual void createIDBKeysFromSerializedValuesAndKeyPath(
const WebKit::WebVector<WebKit::WebSerializedScriptValue>& values,
const WebKit::WebString& keyPath,
const WebKit::WebIDBKeyPath& keyPath,
WebKit::WebVector<WebKit::WebIDBKey>& keys_out) OVERRIDE;
virtual WebKit::WebSerializedScriptValue injectIDBKeyIntoSerializedValue(
const WebKit::WebIDBKey& key,
const WebKit::WebSerializedScriptValue& value,
const WebKit::WebString& keyPath) OVERRIDE;
const WebKit::WebIDBKeyPath& keyPath) OVERRIDE;
virtual WebKit::WebGraphicsContext3D* createOffscreenGraphicsContext3D(
const WebKit::WebGraphicsContext3D::Attributes& attributes) OVERRIDE;
virtual string16 GetLocalizedString(int message_id) OVERRIDE;
virtual base::StringPiece GetDataResource(int resource_id) OVERRIDE;
virtual base::StringPiece GetImageResource(int resource_id,
float scale_factor) OVERRIDE;
virtual void GetPlugins(bool refresh,
std::vector<webkit::WebPluginInfo>* plugins) OVERRIDE;
virtual webkit_glue::ResourceLoaderBridge* CreateResourceLoader(
@@ -106,6 +105,7 @@ class BrowserWebKitInit : public webkit_glue::WebKitPlatformSupportImpl {
ScopedTempDir appcache_dir_;
BrowserAppCacheSystem appcache_system_;
BrowserDatabaseSystem database_system_;
BrowserDomStorageSystem dom_storage_system_;
BrowserWebCookieJarImpl cookie_jar_;
scoped_refptr<BrowserWebBlobRegistryImpl> blob_registry_;
};

View File

@@ -1,55 +0,0 @@
// 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 "libcef/browser_webstoragearea_impl.h"
#include "libcef/cef_context.h"
#include "libcef/dom_storage_area.h"
#include "libcef/dom_storage_namespace.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h"
#include "third_party/WebKit/Source/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()->GetStorageArea(namespace_id, origin, true);
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) {
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();
}

View File

@@ -1,39 +0,0 @@
// 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 CEF_LIBCEF_BROWSER_WEBSTORAGEAREA_IMPL_H_
#define CEF_LIBCEF_BROWSER_WEBSTORAGEAREA_IMPL_H_
#pragma once
#include "base/basictypes.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebStorageArea.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/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);
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 // CEF_LIBCEF_BROWSER_WEBSTORAGEAREA_IMPL_H_

View File

@@ -1,50 +0,0 @@
// 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 "libcef/browser_webstoragenamespace_impl.h"
#include "libcef/browser_webstoragearea_impl.h"
#include "libcef/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) {
}
BrowserWebStorageNamespaceImpl::BrowserWebStorageNamespaceImpl(
DOMStorageType storage_type, int64 namespace_id)
: storage_type_(storage_type),
namespace_id_(namespace_id) {
}
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.
}

View File

@@ -1,35 +0,0 @@
// 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 CEF_LIBCEF_BROWSER_WEBSTORAGENAMESPACE_IMPL_H_
#define CEF_LIBCEF_BROWSER_WEBSTORAGENAMESPACE_IMPL_H_
#pragma once
#include "libcef/dom_storage_common.h"
#include "base/basictypes.h"
#include "third_party/WebKit/Source/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();
private:
// Used during lazy initialization of namespace_id_.
const DOMStorageType storage_type_;
// Our namespace ID.
int64 namespace_id_;
};
#endif // CEF_LIBCEF_BROWSER_WEBSTORAGENAMESPACE_IMPL_H_

View File

@@ -12,11 +12,11 @@
#include <algorithm>
#include "libcef/browser_appcache_system.h"
#include "libcef/browser_dom_storage_system.h"
#include "libcef/browser_file_system.h"
#include "libcef/browser_impl.h"
#include "libcef/browser_navigation_controller.h"
#include "libcef/browser_webkit_glue.h"
#include "libcef/browser_webstoragenamespace_impl.h"
#include "libcef/browser_zoom_map.h"
#include "libcef/cef_context.h"
#include "libcef/cef_process_ui_thread.h"
@@ -188,13 +188,7 @@ WebWidget* BrowserWebViewDelegate::createPopupMenu(WebPopupType popup_type) {
WebStorageNamespace* BrowserWebViewDelegate::createSessionStorageNamespace(
unsigned quota) {
#ifdef ENABLE_NEW_DOM_STORAGE_BACKEND
NOTREACHED();
#else
// Ignore the quota parameter from WebCore as in Chrome.
return new BrowserWebStorageNamespaceImpl(DOM_STORAGE_SESSION,
kLocalStorageNamespaceId + 1);
#endif
return BrowserDomStorageSystem::instance().CreateSessionStorageNamespace();
}
WebKit::WebGraphicsContext3D* BrowserWebViewDelegate::createGraphicsContext3D(
@@ -517,6 +511,11 @@ bool BrowserWebViewDelegate::allowScriptExtension(
// WebPluginPageDelegate -----------------------------------------------------
WebKit::WebPlugin* BrowserWebViewDelegate::CreatePluginReplacement(
const FilePath& file_path) {
return NULL;
}
WebCookieJar* BrowserWebViewDelegate::GetCookieJar() {
return &cookie_jar_;
}

View File

@@ -119,8 +119,9 @@ class BrowserWebViewDelegate : public WebKit::WebViewClient,
virtual void setToolTipText(
const WebKit::WebString& text, WebKit::WebTextDirection hint) OVERRIDE;
virtual void startDragging(
WebKit::WebFrame* frame,
const WebKit::WebDragData& data,
WebKit::WebDragOperationsMask mask,
WebKit::WebDragOperationsMask mask,
const WebKit::WebImage& image,
const WebKit::WebPoint& image_offset) OVERRIDE;
virtual bool acceptsLoadDrops() OVERRIDE;
@@ -221,6 +222,8 @@ class BrowserWebViewDelegate : public WebKit::WebViewClient,
virtual webkit::npapi::WebPluginDelegate* CreatePluginDelegate(
const FilePath& file_path,
const std::string& mime_type) OVERRIDE;
virtual WebKit::WebPlugin* CreatePluginReplacement(
const FilePath& file_path) OVERRIDE;
virtual void CreatedPluginWindow(
gfx::PluginWindowHandle handle) OVERRIDE;
virtual void WillDestroyPluginWindow(

View File

@@ -291,11 +291,11 @@ WebRect BrowserWebViewDelegate::windowResizerRect() {
}
void BrowserWebViewDelegate::startDragging(
WebFrame* frame,
const WebDragData& data,
WebDragOperationsMask mask,
const WebImage& image,
const WebPoint& image_offset) {
if (browser_->settings().drag_drop_disabled) {
browser_->UIT_GetWebView()->dragSourceSystemDragEnded();
return;

View File

@@ -348,10 +348,12 @@ WebRect BrowserWebViewDelegate::windowResizerRect() {
return gfx::Rect(NSRectToCGRect(resize_rect));
}
void BrowserWebViewDelegate::startDragging(const WebDragData& data,
WebDragOperationsMask mask,
const WebImage& image,
const WebPoint& image_offset) {
void BrowserWebViewDelegate::startDragging(
WebFrame* frame,
const WebDragData& data,
WebDragOperationsMask mask,
const WebImage& image,
const WebPoint& image_offset) {
if (browser_->settings().drag_drop_disabled ||
browser_->IsWindowRenderingDisabled()) {
browser_->UIT_GetWebView()->dragSourceSystemDragEnded();

View File

@@ -224,6 +224,7 @@ WebRect BrowserWebViewDelegate::windowResizerRect() {
}
void BrowserWebViewDelegate::startDragging(
WebFrame* frame,
const WebDragData& data,
WebDragOperationsMask mask,
const WebImage& image,

View File

@@ -12,6 +12,7 @@
#include "base/path_service.h"
#include "base/synchronization/waitable_event.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/resource/resource_handle.h"
#include "ui/base/ui_base_paths.h"
#if defined(OS_MACOSX) || defined(OS_WIN)
@@ -19,6 +20,7 @@
#endif
#if defined(OS_MACOSX)
#include "base/mac/foundation_util.h"
#include "base/mac/mac_util.h"
#include "grit/webkit_resources.h"
#endif
@@ -27,15 +29,33 @@
#include "base/win/resource_util.h"
#endif
// Both the CefContext constuctor and the CefContext::RemoveBrowser method need
// to initialize or reset to the same value.
const int kNextBrowserIdReset = 1;
// Global CefContext pointer
CefRefPtr<CefContext> _Context;
namespace {
// Both the CefContext constuctor and the CefContext::RemoveBrowser method need
// to initialize or reset to the same value.
const int kNextBrowserIdReset = 1;
#if defined(OS_MACOSX)
FilePath GetDefaultPackPath() {
FilePath bundlePath = base::mac::GetAppBundlePath(execPath);
return bundlePath.Append(FILE_PATH_LITERAL("Contents"))
.Append(FILE_PATH_LITERAL("Resources"));
}
#else // !defined(OS_MACOSX)
FilePath GetDefaultPackPath() {
FilePath pak_dir;
PathService::Get(base::DIR_MODULE, &pak_dir);
return pak_dir;
}
#endif // !defined(OS_MACOSX)
// Used in multi-threaded message loop mode to observe shutdown of the UI
// thread.
class DestructionObserver : public MessageLoop::DestructionObserver {
@@ -66,6 +86,69 @@ base::StringPiece GetRawDataResource(HMODULE module, int resource_id) {
} // namespace
class CefResourceBundleDelegate : public ui::ResourceBundle::Delegate {
public:
CefResourceBundleDelegate(CefContext* context)
: context_(context),
allow_pack_file_load_(false) {
}
void set_allow_pack_file_load(bool val) { allow_pack_file_load_ = val; }
private:
virtual FilePath GetPathForResourcePack(const FilePath& pack_path,
float scale_factor) OVERRIDE {
// Only allow the cef pack file to load.
if (!context_->settings().pack_loading_disabled && allow_pack_file_load_)
return pack_path;
return FilePath();
}
virtual FilePath GetPathForLocalePack(const FilePath& pack_path,
const std::string& locale) OVERRIDE {
if (!context_->settings().pack_loading_disabled)
return pack_path;
return FilePath();
}
virtual gfx::Image GetImageNamed(int resource_id) OVERRIDE {
return gfx::Image();
}
virtual gfx::Image GetNativeImageNamed(
int resource_id,
ui::ResourceBundle::ImageRTL rtl) OVERRIDE {
return gfx::Image();
}
virtual base::RefCountedStaticMemory* LoadDataResourceBytes(
int resource_id) OVERRIDE {
return NULL;
}
virtual bool GetRawDataResource(int resource_id,
base::StringPiece* value) OVERRIDE {
return false;
}
virtual bool GetLocalizedString(int message_id, string16* value) OVERRIDE {
return false;
}
virtual scoped_ptr<gfx::Font> GetFont(
ui::ResourceBundle::FontStyle style) OVERRIDE {
return scoped_ptr<gfx::Font>();
}
// CefContext pointer is guaranteed to outlive this object.
CefContext* context_;
bool allow_pack_file_load_;
DISALLOW_COPY_AND_ASSIGN(CefResourceBundleDelegate);
};
bool CefInitialize(const CefSettings& settings, CefRefPtr<CefApp> application) {
// Return true if the global context already exists.
if (_Context.get())
@@ -157,6 +240,7 @@ void CefQuitMessageLoop() {
CefContext::CefContext()
: initialized_(false),
shutting_down_(false),
request_context_(NULL),
next_browser_id_(kNextBrowserIdReset),
current_webviewhost_(NULL) {
}
@@ -293,47 +377,48 @@ CefRefPtr<CefBrowserImpl> CefContext::GetBrowserByID(int id) {
}
void CefContext::InitializeResourceBundle() {
if (settings_.pack_loading_disabled)
return;
FilePath pak_file, locales_dir;
if (settings_.pack_file_path.length > 0)
pak_file = FilePath(CefString(&settings_.pack_file_path));
if (!settings_.pack_loading_disabled) {
if (settings_.pack_file_path.length > 0)
pak_file = FilePath(CefString(&settings_.pack_file_path));
if (pak_file.empty()) {
FilePath pak_dir;
PathService::Get(base::DIR_MODULE, &pak_dir);
pak_file = pak_dir.Append(FILE_PATH_LITERAL("chrome.pak"));
if (pak_file.empty())
pak_file = GetDefaultPackPath().Append(FILE_PATH_LITERAL("chrome.pak"));
if (settings_.locales_dir_path.length > 0)
locales_dir = FilePath(CefString(&settings_.locales_dir_path));
if (!locales_dir.empty())
PathService::Override(ui::DIR_LOCALES, locales_dir);
}
if (!pak_file.empty())
PathService::Override(ui::FILE_RESOURCES_PAK, pak_file);
if (settings_.locales_dir_path.length > 0)
locales_dir = FilePath(CefString(&settings_.locales_dir_path));
if (!locales_dir.empty())
PathService::Override(ui::DIR_LOCALES, locales_dir);
std::string locale_str = locale();
const std::string loaded_locale =
ui::ResourceBundle::InitSharedInstanceWithLocale(locale_str);
CHECK(!loaded_locale.empty()) << "Locale could not be found for " <<
locale_str;
if (locale_str.empty())
locale_str = "en-US";
#if defined(OS_WIN)
// Explicitly load chrome.pak on Windows.
if (file_util::PathExists(pak_file))
ResourceBundle::AddDataPackToSharedInstance(pak_file);
else
NOTREACHED() << "Could not load chrome.pak";
#endif
resource_bundle_delegate_.reset(new CefResourceBundleDelegate(this));
const std::string loaded_locale =
ui::ResourceBundle::InitSharedInstanceWithLocale(
locale_str, resource_bundle_delegate_.get());
if (!settings_.pack_loading_disabled) {
CHECK(!loaded_locale.empty()) << "Locale could not be found for "
<< locale_str;
if (file_util::PathExists(pak_file)) {
resource_bundle_delegate_->set_allow_pack_file_load(true);
ResourceBundle::GetSharedInstance().AddDataPack(
pak_file, ui::ResourceHandle::kScaleFactor100x);
resource_bundle_delegate_->set_allow_pack_file_load(false);
} else {
NOTREACHED() << "Could not load chrome.pak";
}
}
}
void CefContext::CleanupResourceBundle() {
if (!settings_.pack_loading_disabled)
ResourceBundle::CleanupSharedInstance();
ResourceBundle::CleanupSharedInstance();
resource_bundle_delegate_.reset(NULL);
}
string16 CefContext::GetLocalizedString(int message_id) const {
@@ -382,7 +467,7 @@ base::StringPiece CefContext::GetDataResource(int resource_id) const {
hModule = ::GetModuleHandle(file_path.value().c_str());
if (!hModule)
hModule = ::GetModuleHandle(NULL);
value = GetRawDataResource(hModule, resource_id);
value = ::GetRawDataResource(hModule, resource_id);
}
#elif defined(OS_MACOSX)
if (value.empty()) {

View File

@@ -15,13 +15,13 @@
#include "libcef/browser_file_system.h"
#include "libcef/browser_request_context.h"
#include "libcef/cef_process.h"
#include "libcef/dom_storage_context.h"
#include "base/at_exit.h"
#include "base/file_path.h"
#include "base/memory/ref_counted.h"
class CefBrowserImpl;
class CefResourceBundleDelegate;
class WebViewHost;
namespace base {
@@ -78,12 +78,6 @@ class CefContext : public CefBase {
}
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(); }
BrowserFileSystem* file_system() { return &file_system_; }
// Used to keep track of the web view host we're dragging over. WARNING:
@@ -116,9 +110,9 @@ class CefContext : public CefBase {
CefSettings settings_;
CefRefPtr<CefApp> application_;
FilePath cache_path_;
scoped_refptr<BrowserRequestContext> request_context_;
scoped_ptr<DOMStorageContext> storage_context_;
BrowserRequestContext* request_context_;
BrowserFileSystem file_system_;
scoped_ptr<CefResourceBundleDelegate> resource_bundle_delegate_;
// Map of browsers that currently exist.
BrowserList browserlist_;

View File

@@ -37,18 +37,18 @@ void CefProcessIOThread::Init() {
CefThread::Init();
FilePath cache_path(_Context->cache_path());
request_context_ = new BrowserRequestContext(cache_path,
net::HttpCache::NORMAL, false);
_Context->set_request_context(request_context_);
request_context_.reset(new BrowserRequestContext(cache_path,
net::HttpCache::NORMAL, false));
_Context->set_request_context(request_context_.get());
network_delegate_.reset(new BrowserNetworkDelegate());
request_context_->set_network_delegate(network_delegate_.get());
BrowserAppCacheSystem::InitializeOnIOThread(request_context_);
BrowserFileWriter::InitializeOnIOThread(request_context_);
BrowserAppCacheSystem::InitializeOnIOThread(request_context_.get());
BrowserFileWriter::InitializeOnIOThread(request_context_.get());
BrowserFileSystem::InitializeOnIOThread(
request_context_->blob_storage_controller());
BrowserSocketStreamBridge::InitializeOnIOThread(request_context_);
BrowserSocketStreamBridge::InitializeOnIOThread(request_context_.get());
BrowserWebBlobRegistryImpl::InitializeOnIOThread(
request_context_->blob_storage_controller());
}
@@ -71,7 +71,8 @@ void CefProcessIOThread::CleanUp() {
request_context_->set_network_delegate(NULL);
network_delegate_.reset(NULL);
request_context_ = NULL;
_Context->set_request_context(NULL);
request_context_.reset(NULL);
CefThread::Cleanup();
}

View File

@@ -31,15 +31,13 @@ class CefProcessIOThread : public CefThread {
explicit CefProcessIOThread(MessageLoop* message_loop);
virtual ~CefProcessIOThread();
scoped_refptr<BrowserRequestContext> request_context() {
return request_context_;
}
BrowserRequestContext* request_context() { return request_context_.get(); }
protected:
virtual void Init();
virtual void CleanUp();
scoped_refptr<BrowserRequestContext> request_context_;
scoped_ptr<BrowserRequestContext> request_context_;
scoped_ptr<net::NetworkDelegate> network_delegate_;
DISALLOW_COPY_AND_ASSIGN(CefProcessIOThread);

View File

@@ -24,7 +24,7 @@
#include "third_party/WebKit/Source/WebKit/chromium/public/WebNetworkStateNotifier.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebScriptController.h"
#include "ui/base/ui_base_paths.h"
#include "ui/gfx/gl/gl_implementation.h"
#include "ui/gl/gl_implementation.h"
#include "webkit/glue/user_agent.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/plugins/npapi/plugin_list.h"
@@ -133,17 +133,6 @@ void CefProcessUIThread::Init() {
gfx::InitializeGLBindings(gfx::kGLImplementationDesktopGL);
#endif
// 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), false);
} else {
@@ -192,9 +181,6 @@ 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_;

View File

@@ -6,13 +6,13 @@
#include <string>
#include "libcef/browser_persistent_cookie_store.h"
#include "libcef/cef_context.h"
#include "libcef/cef_thread.h"
#include "libcef/cef_time_util.h"
#include "base/bind.h"
#include "base/logging.h"
#include "chrome/browser/net/sqlite_persistent_cookie_store.h"
namespace {
@@ -225,11 +225,11 @@ bool CefCookieManagerImpl::SetStoragePath(const CefString& path) {
return true;
}
scoped_refptr<BrowserPersistentCookieStore> persistent_store;
scoped_refptr<SQLitePersistentCookieStore> persistent_store;
if (!new_path.empty()) {
if (file_util::CreateDirectory(new_path)) {
const FilePath& cookie_path = new_path.AppendASCII("Cookies");
persistent_store = new BrowserPersistentCookieStore(cookie_path, false);
persistent_store = new SQLitePersistentCookieStore(cookie_path, false);
} else {
NOTREACHED() << "The cookie storage directory could not be created";
storage_path_.clear();

View File

@@ -59,6 +59,12 @@ void CefCookieStoreProxy::DeleteAllCreatedBetweenAsync(
callback);
}
void CefCookieStoreProxy::DeleteSessionCookiesAsync(
const DeleteCallback& callback) {
scoped_refptr<net::CookieStore> cookie_store = GetCookieStore();
cookie_store->DeleteSessionCookiesAsync(callback);
}
net::CookieMonster* CefCookieStoreProxy::GetCookieMonster() {
scoped_refptr<net::CookieStore> cookie_store = GetCookieStore();
return cookie_store->GetCookieMonster();

View File

@@ -35,6 +35,8 @@ class CefCookieStoreProxy : public net::CookieStore {
const base::Time& delete_end,
const DeleteCallback& callback)
OVERRIDE;
virtual void DeleteSessionCookiesAsync(const DeleteCallback& callback)
OVERRIDE;
virtual net::CookieMonster* GetCookieMonster() OVERRIDE;
private:

View File

@@ -12,7 +12,6 @@
#include "base/logging.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebAttribute.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDOMEvent.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDOMEventListener.h"
@@ -20,12 +19,10 @@
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFormControlElement.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputElement.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebNamedNodeMap.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebSelectElement.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
using WebKit::WebAttribute;
using WebKit::WebDocument;
using WebKit::WebDOMEvent;
using WebKit::WebDOMEventListener;
@@ -33,7 +30,6 @@ using WebKit::WebElement;
using WebKit::WebFrame;
using WebKit::WebFormControlElement;
using WebKit::WebInputElement;
using WebKit::WebNamedNodeMap;
using WebKit::WebNode;
using WebKit::WebSelectElement;
using WebKit::WebString;
@@ -356,7 +352,7 @@ bool CefDOMNodeImpl::HasElementAttributes() {
}
const WebElement& element = node_.toConst<WebKit::WebElement>();
return (element.attributes().length() > 0);
return (element.attributeCount() > 0);
}
bool CefDOMNodeImpl::HasElementAttribute(const CefString& attrName) {
@@ -400,24 +396,14 @@ void CefDOMNodeImpl::GetElementAttributes(AttributeMap& attrMap) {
}
const WebElement& element = node_.toConst<WebKit::WebElement>();
const WebNamedNodeMap& map = element.attributes();
unsigned int len = map.length();
unsigned int len = element.attributeCount();
if (len == 0)
return;
string16 nameStr, valueStr;
for (unsigned int i = 0; i < len; ++i) {
const WebAttribute& attrib = map.attributeItem(i);
string16 nameStr, valueStr;
const WebString& name = attrib.localName();
if (!name.isNull())
nameStr = name;
const WebString& value = attrib.value();
if (!value.isNull())
valueStr = value;
attrMap.insert(std::make_pair(nameStr, valueStr));
string16 name = element.attributeLocalName(i);
string16 value = element.attributeValue(i);
attrMap.insert(std::make_pair(name, value));
}
}

View File

@@ -1,80 +0,0 @@
// Copyright (c) 2011 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 "libcef/dom_storage_area.h"
#include "libcef/dom_storage_context.h"
#include "libcef/dom_storage_namespace.h"
#include "base/logging.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebStorageArea.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/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) {
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_));
}

View File

@@ -1,80 +0,0 @@
// Copyright (c) 2011 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 CEF_LIBCEF_DOM_STORAGE_AREA_H_
#define CEF_LIBCEF_DOM_STORAGE_AREA_H_
#pragma once
#include "base/hash_tables.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/nullable_string16.h"
#include "base/string16.h"
#include "googleurl/src/gurl.h"
#include "third_party/WebKit/Source/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_; }
const string16& origin() const { return origin_; }
private:
// Creates the underlying WebStorageArea on demand.
void CreateWebStorageAreaIfNecessary();
// 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)
#if defined(OS_ANDROID)
// Android stlport uses std namespace
namespace std {
#else
namespace __gnu_cxx {
#endif
template<>
struct hash<DOMStorageArea*> {
std::size_t operator()(DOMStorageArea* const& p) const {
return reinterpret_cast<std::size_t>(p);
}
};
} // namespace __gnu_cxx
#endif
#endif // CEF_LIBCEF_DOM_STORAGE_AREA_H_

View File

@@ -1,19 +0,0 @@
// 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 CEF_LIBCEF_DOM_STORAGE_COMMON_H_
#define CEF_LIBCEF_DOM_STORAGE_COMMON_H_
#pragma once
#include "base/basictypes.h"
const int64 kLocalStorageNamespaceId = 0;
const int64 kInvalidSessionStorageNamespaceId = kLocalStorageNamespaceId;
enum DOMStorageType {
DOM_STORAGE_LOCAL = 0,
DOM_STORAGE_SESSION
};
#endif // CEF_LIBCEF_DOM_STORAGE_COMMON_H_

View File

@@ -1,305 +0,0 @@
// 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 "libcef/dom_storage_context.h"
#include <algorithm>
#include "libcef/cef_thread.h"
#include "libcef/dom_storage_area.h"
#include "libcef/dom_storage_namespace.h"
#include "base/bind.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/string_util.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/platform/WebString.h"
#include "webkit/database/database_util.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");
// 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) {
}
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,
base::Bind(&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);
}
void DOMStorageContext::DeleteLocalStorageNamespace() {
DCHECK(CefThread::CurrentlyOn(CefThread::UI));
StorageNamespaceMap::iterator iter =
storage_namespace_map_.find(kLocalStorageNamespaceId);
if (iter == storage_namespace_map_.end())
return;
DCHECK(iter->second->dom_storage_type() == DOM_STORAGE_LOCAL);
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);
}
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(
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(kLocalStorageNamespaceId);
if (local_storage_path_.empty())
return;
file_util::FileEnumerator file_enumerator(
local_storage_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::DeleteLocalStorageForOrigin(const string16& origin) {
DCHECK(CefThread::CurrentlyOn(CefThread::UI));
DOMStorageArea* area =
GetStorageArea(kLocalStorageNamespaceId, origin, false);
if (!area)
return;
// Calling Clear() is necessary to remove the data from the namespace.
area->Clear();
area->PurgeMemory();
if (local_storage_path_.empty())
return;
FilePath file_path = GetLocalStorageFilePath(origin);
if (!file_path.empty())
file_util::Delete(file_path, false);
}
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(kLocalStorageNamespaceId);
if (local_storage_path_.empty())
return;
file_util::FileEnumerator file_enumerator(
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()) {
if (file_path.Extension() == kLocalStorageExtension)
file_util::Delete(file_path, false);
}
}
void DOMStorageContext::SetLocalStoragePath(
const FilePath& local_storage_path) {
DCHECK(CefThread::CurrentlyOn(CefThread::UI));
if ((local_storage_path.empty() && local_storage_path_.empty()) ||
local_storage_path == local_storage_path_)
return;
// Make sure that we don't swap out a database that's currently being accessed
// by unloading all of the databases temporarily.
PurgeMemory(kLocalStorageNamespaceId);
// Delete the current namespace, if any. It will be recreated using the new
// path when needed.
DeleteLocalStorageNamespace();
local_storage_path_ = local_storage_path;
}
DOMStorageNamespace* DOMStorageContext::CreateLocalStorage() {
FilePath dir_path;
if (!local_storage_path_.empty())
dir_path = local_storage_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) 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);
return storageDir.Append(id.append(kLocalStorageExtension));
}

View File

@@ -1,150 +0,0 @@
// 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 CEF_LIBCEF_DOM_STORAGE_CONTEXT_H_
#define CEF_LIBCEF_DOM_STORAGE_CONTEXT_H_
#pragma once
#include <map>
#include <set>
#include <vector>
#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:
explicit DOMStorageContext(const FilePath& local_storage_path);
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);
// Called on WebKit thread when the local storage namespace can be deleted.
void DeleteLocalStorageNamespace();
// 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);
// 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(int64 namespace_id);
// 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 the local storage file for the given origin.
void DeleteLocalStorageForOrigin(const string16& origin);
// Deletes all local storage files.
void DeleteAllLocalStorageFiles();
// Sets the path that will be used for local storage. If |local_storage_path|
// is empty in-memory storage will be used.
void SetLocalStoragePath(const FilePath& local_storage_path);
// 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) 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.
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);
// 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
// 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_;
// Quota limits for localStorage and sessionStorage respectively.
static unsigned int local_storage_quota_;
static unsigned int session_storage_quota_;
};
#endif // CEF_LIBCEF_DOM_STORAGE_CONTEXT_H_

View File

@@ -1,124 +0,0 @@
// 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 "libcef/dom_storage_namespace.h"
#include "libcef/dom_storage_area.h"
#include "libcef/dom_storage_context.h"
#include "base/file_path.h"
#include "base/logging.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebStorageArea.h"
#include "third_party/WebKit/Source/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));
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 */
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, 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));
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::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() {
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_,
DOMStorageContext::local_storage_quota()));
} else {
storage_namespace_.reset(WebStorageNamespace::createSessionStorageNamespace(
DOMStorageContext::session_storage_quota()));
}
}

View File

@@ -1,91 +0,0 @@
// 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 CEF_LIBCEF_DOM_STORAGE_NAMESPACE_H_
#define CEF_LIBCEF_DOM_STORAGE_NAMESPACE_H_
#pragma once
#include "libcef/dom_storage_common.h"
#include <vector>
#include "base/hash_tables.h"
#include "base/memory/scoped_ptr.h"
#include "base/string16.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/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,
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 {
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, // NOLINT(build/include_what_you_use)
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 // CEF_LIBCEF_DOM_STORAGE_NAMESPACE_H_

View File

@@ -54,9 +54,10 @@ bool CefDragDataImpl::GetFileNames(std::vector<CefString>& names) {
if (data_.filenames.empty())
return false;
std::vector<string16>::const_iterator it = data_.filenames.begin();
std::vector<WebDropData::FileInfo>::const_iterator it =
data_.filenames.begin();
for (; it != data_.filenames.end(); ++it)
names.push_back(*it);
names.push_back(it->path);
return true;
}

View File

@@ -0,0 +1,10 @@
// Copyright (c) 2012 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 "chrome/browser/diagnostics/sqlite_diagnostics.h"
// Used by SQLitePersistentCookieStore
sql::ErrorDelegate* GetErrorHandlerForCookieDb() {
return NULL;
}

View File

@@ -1,304 +0,0 @@
// 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_storage.h"
#include "libcef/cef_context.h"
#include "libcef/cef_thread.h"
#include "libcef/dom_storage_common.h"
#include "libcef/dom_storage_namespace.h"
#include "libcef/dom_storage_area.h"
namespace {
void UIT_VisitStorage(int64 namespace_id, const CefString& origin,
const CefString& key,
CefRefPtr<CefStorageVisitor> visitor) {
REQUIRE_UIT();
DOMStorageContext* context = _Context->storage_context();
// Allow storage to be allocated for localStorage so that on-disk data, if
// any, will be available.
bool allocation_allowed = (namespace_id == kLocalStorageNamespaceId);
DOMStorageNamespace* ns =
context->GetStorageNamespace(namespace_id, allocation_allowed);
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, allocation_allowed);
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();
}
}
}
}
void UIT_SetStoragePath(int64 namespace_id, const CefString& path) {
REQUIRE_UIT();
if (namespace_id != kLocalStorageNamespaceId)
return;
FilePath file_path;
if (!path.empty())
file_path = FilePath(path);
DOMStorageContext* context = _Context->storage_context();
DCHECK(context);
if (context)
context->SetLocalStoragePath(file_path);
}
} // namespace
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();
// Allow storage to be allocated for localStorage so that on-disk data, if
// any, will be available.
bool allocation_allowed = (namespace_id == kLocalStorageNamespaceId);
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, allocation_allowed);
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, allocation_allowed);
if (area)
area->RemoveItem(key);
}
return true;
}
bool CefSetStoragePath(CefStorageType type, const CefString& path) {
// 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 {
NOTREACHED() << "invalid type";
return false;
}
if (CefThread::CurrentlyOn(CefThread::UI)) {
UIT_SetStoragePath(namespace_id, path);
} else {
CefThread::PostTask(CefThread::UI, FROM_HERE,
base::Bind(&UIT_SetStoragePath, namespace_id, path));
}
return true;
}

View File

@@ -2,10 +2,19 @@
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "libcef/v8_impl.h"
#include <string>
#include "base/compiler_specific.h"
#include "third_party/WebKit/Source/WebCore/config.h"
MSVC_PUSH_WARNING_LEVEL(0);
#include "V8Proxy.h" // NOLINT(build/include)
#include "V8RecursionScope.h" // NOLINT(build/include)
MSVC_POP_WARNING();
#undef LOG
#include "libcef/v8_impl.h"
#include "libcef/browser_impl.h"
#include "libcef/cef_context.h"
#include "libcef/tracker.h"
@@ -30,10 +39,7 @@
namespace {
static const char kCefAccessor[] = "Cef::Accessor";
static const char kCefHandler[] = "Cef::Handler";
static const char kCefUserData[] = "Cef::UserData";
static const char kCefExternalMemory[] = "Cef::ExternalMemory";
static const char kCefTrackObject[] = "Cef::TrackObject";
// Memory manager.
@@ -41,20 +47,78 @@ base::LazyInstance<CefTrackManager> g_v8_tracker = LAZY_INSTANCE_INITIALIZER;
class V8TrackObject : public CefTrackNode {
public:
V8TrackObject(CefBase* object = NULL, CefBase* user_data = NULL)
: object_(object),
user_data_(user_data),
external_memory_counter_(0) {
V8TrackObject()
: external_memory_(0) {
}
~V8TrackObject() {
if (external_memory_ != 0)
v8::V8::AdjustAmountOfExternalAllocatedMemory(-external_memory_);
}
int* GetMemoryCounter() {
return &external_memory_counter_;
inline int GetExternallyAllocatedMemory() {
return external_memory_;
}
int AdjustExternallyAllocatedMemory(int change_in_bytes) {
int new_value = external_memory_ + change_in_bytes;
if (new_value < 0) {
NOTREACHED() << "External memory usage cannot be less than 0 bytes";
change_in_bytes = -(external_memory_);
new_value = 0;
}
if (change_in_bytes != 0)
v8::V8::AdjustAmountOfExternalAllocatedMemory(change_in_bytes);
external_memory_ = new_value;
return new_value;
}
inline void SetAccessor(CefRefPtr<CefV8Accessor> accessor) {
accessor_ = accessor;
}
inline CefRefPtr<CefV8Accessor> GetAccessor() {
return accessor_;
}
inline void SetHandler(CefRefPtr<CefV8Handler> handler) {
handler_ = handler;
}
inline CefRefPtr<CefV8Handler> GetHandler() {
return handler_;
}
inline void SetUserData(CefRefPtr<CefBase> user_data) {
user_data_ = user_data;
}
inline CefRefPtr<CefBase> GetUserData() {
return user_data_;
}
// Attach this track object to the specified V8 object.
void AttachTo(v8::Handle<v8::Object> object) {
object->SetHiddenValue(v8::String::New(kCefTrackObject),
v8::External::Wrap(this));
}
// Retrieve the track object for the specified V8 object.
static V8TrackObject* Unwrap(v8::Handle<v8::Object> object) {
v8::Local<v8::Value> value =
object->GetHiddenValue(v8::String::New(kCefTrackObject));
if (!value.IsEmpty())
return static_cast<V8TrackObject*>(v8::External::Unwrap(value));
return NULL;
}
private:
CefRefPtr<CefBase> object_;
CefRefPtr<CefV8Accessor> accessor_;
CefRefPtr<CefV8Handler> handler_;
CefRefPtr<CefBase> user_data_;
int external_memory_counter_;
int external_memory_;
};
class V8TrackString : public CefTrackNode {
@@ -76,16 +140,9 @@ void TrackDelete(CefTrackNode* object) {
// Callback for weak persistent reference destruction.
void TrackDestructor(v8::Persistent<v8::Value> object, void* parameter) {
if (parameter) {
if (object->IsObject()) {
V8TrackObject* tracker = static_cast<V8TrackObject*>(parameter);
DCHECK(tracker);
int adjustment = -(*tracker->GetMemoryCounter());
if (adjustment != 0)
v8::V8::AdjustAmountOfExternalAllocatedMemory(adjustment);
}
if (parameter)
TrackDelete(static_cast<CefTrackNode*>(parameter));
}
object.Dispose();
object.Clear();
}
@@ -213,8 +270,13 @@ v8::Handle<v8::Value> AccessorGetterCallbackImpl(v8::Local<v8::String> property,
v8::Handle<v8::Object> obj = info.This();
CefV8Accessor* accessorPtr = CefV8ValueImpl::GetAccessor(obj);
if (accessorPtr) {
CefRefPtr<CefV8Accessor> accessorPtr;
V8TrackObject* tracker = V8TrackObject::Unwrap(obj);
if (tracker)
accessorPtr = tracker->GetAccessor();
if (accessorPtr.get()) {
CefRefPtr<CefV8Value> retval;
CefRefPtr<CefV8Value> object = new CefV8ValueImpl(obj);
CefString name, exception;
@@ -241,8 +303,13 @@ void AccessorSetterCallbackImpl(v8::Local<v8::String> property,
v8::Handle<v8::Object> obj = info.This();
CefV8Accessor* accessorPtr = CefV8ValueImpl::GetAccessor(obj);
if (accessorPtr) {
CefRefPtr<CefV8Accessor> accessorPtr;
V8TrackObject* tracker = V8TrackObject::Unwrap(obj);
if (tracker)
accessorPtr = tracker->GetAccessor();
if (accessorPtr.get()) {
CefRefPtr<CefV8Value> object = new CefV8ValueImpl(obj);
CefRefPtr<CefV8Value> cefValue = new CefV8ValueImpl(value);
CefString name, exception;
@@ -264,8 +331,10 @@ class ExtensionWrapper : public v8::Extension {
CefV8Handler* handler)
: v8::Extension(extension_name, javascript_code), handler_(handler) {
if (handler) {
// The reference will be released when the application exits.
TrackAdd(new V8TrackObject(handler));
// The reference will be released when the process exits.
V8TrackObject* object = new V8TrackObject;
object->SetHandler(handler);
TrackAdd(object);
}
}
@@ -339,6 +408,9 @@ class CefV8ExceptionImpl : public CefV8Exception {
} // namespace
// Global functions.
bool CefRegisterExtension(const CefString& extension_name,
const CefString& javascript_code,
CefRefPtr<CefV8Handler> handler) {
@@ -359,7 +431,7 @@ bool CefRegisterExtension(const CefString& extension_name,
}
// CefV8Context
// CefV8Context implementation.
// static
CefRefPtr<CefV8Context> CefV8Context::GetCurrentContext() {
@@ -393,7 +465,25 @@ bool CefV8Context::InContext() {
}
// CefV8ContextImpl
// CefV8ContextImpl implementation.
#define CEF_V8_REQUIRE_OBJECT_RETURN(ret) \
if (!GetHandle()->IsObject()) { \
NOTREACHED() << "V8 value is not an object"; \
return ret; \
}
#define CEF_V8_REQUIRE_ARRAY_RETURN(ret) \
if (!GetHandle()->IsArray()) { \
NOTREACHED() << "V8 value is not an array"; \
return ret; \
}
#define CEF_V8_REQUIRE_FUNCTION_RETURN(ret) \
if (!GetHandle()->IsFunction()) { \
NOTREACHED() << "V8 value is not a function"; \
return ret; \
}
CefV8ContextImpl::CefV8ContextImpl(v8::Handle<v8::Context> context)
#ifndef NDEBUG
@@ -475,6 +565,51 @@ bool CefV8ContextImpl::IsSame(CefRefPtr<CefV8Context> that) {
return (thisHandle == thatHandle);
}
bool CefV8ContextImpl::Eval(const CefString& code,
CefRefPtr<CefV8Value>& retval,
CefRefPtr<CefV8Exception>& exception) {
CEF_REQUIRE_UI_THREAD(NULL);
if (code.empty()) {
NOTREACHED() << "invalid input parameter";
return false;
}
v8::HandleScope handle_scope;
v8::Context::Scope context_scope(v8_context_->GetHandle());
v8::Local<v8::Object> obj = v8_context_->GetHandle()->Global();
// Retrieve the eval function.
v8::Local<v8::Value> val = obj->Get(v8::String::New("eval"));
if (val.IsEmpty() || !val->IsFunction())
return false;
v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(val);
v8::Handle<v8::Value> code_val = GetV8String(code);
v8::TryCatch try_catch;
try_catch.SetVerbose(true);
v8::Local<v8::Value> func_rv;
retval = NULL;
exception = NULL;
// Execute the function call using the V8Proxy so that inspector
// instrumentation works.
WebCore::V8Proxy* proxy = WebCore::V8Proxy::retrieve();
DCHECK(proxy);
if (proxy)
func_rv = proxy->callFunction(func, obj, 1, &code_val);
if (try_catch.HasCaught()) {
exception = new CefV8ExceptionImpl(try_catch.Message());
return false;
} else if (!func_rv.IsEmpty()) {
retval = new CefV8ValueImpl(func_rv);
}
return true;
}
v8::Local<v8::Context> CefV8ContextImpl::GetContext() {
return v8::Local<v8::Context>::New(v8_context_->GetHandle());
}
@@ -530,13 +665,21 @@ CefRefPtr<CefV8Value> CefV8Value::CreateBool(bool value) {
}
// static
CefRefPtr<CefV8Value> CefV8Value::CreateInt(int value) {
CefRefPtr<CefV8Value> CefV8Value::CreateInt(int32 value) {
CEF_REQUIRE_VALID_CONTEXT(NULL);
CEF_REQUIRE_UI_THREAD(NULL);
v8::HandleScope handle_scope;
return new CefV8ValueImpl(v8::Int32::New(value));
}
// static
CefRefPtr<CefV8Value> CefV8Value::CreateUInt(uint32 value) {
CEF_REQUIRE_VALID_CONTEXT(NULL);
CEF_REQUIRE_UI_THREAD(NULL);
v8::HandleScope handle_scope;
return new CefV8ValueImpl(v8::Int32::NewFromUnsigned(value));
}
// static
CefRefPtr<CefV8Value> CefV8Value::CreateDouble(double value) {
CEF_REQUIRE_VALID_CONTEXT(NULL);
@@ -564,7 +707,7 @@ CefRefPtr<CefV8Value> CefV8Value::CreateString(const CefString& value) {
// static
CefRefPtr<CefV8Value> CefV8Value::CreateObject(
CefRefPtr<CefBase> user_data, CefRefPtr<CefV8Accessor> accessor) {
CefRefPtr<CefV8Accessor> accessor) {
CEF_REQUIRE_VALID_CONTEXT(NULL);
CEF_REQUIRE_UI_THREAD(NULL);
@@ -579,39 +722,19 @@ CefRefPtr<CefV8Value> CefV8Value::CreateObject(
// Create the new V8 object.
v8::Local<v8::Object> obj = v8::Object::New();
// Provide a tracker object that will cause the user data and/or accessor
// Create a tracker object that will cause the user data and/or accessor
// reference to be released when the V8 object is destroyed.
V8TrackObject* tracker = NULL;
if (user_data.get() && accessor.get()) {
tracker = new V8TrackObject(accessor, user_data);
} else if (user_data.get() || accessor.get()) {
CefBase* object = user_data.get() ? user_data.get() : accessor.get();
tracker = new V8TrackObject(object);
} else {
tracker = new V8TrackObject();
}
V8TrackObject* tracker = new V8TrackObject;
tracker->SetAccessor(accessor);
// Attach the memory counter.
obj->SetHiddenValue(v8::String::New(kCefExternalMemory),
v8::External::Wrap(tracker->GetMemoryCounter()));
// Attach the user data to the V8 object.
if (user_data.get()) {
v8::Local<v8::Value> data = v8::External::Wrap(user_data.get());
obj->SetHiddenValue(v8::String::New(kCefUserData), data);
}
// Attach the accessor to the V8 object.
if (accessor.get()) {
v8::Local<v8::Value> data = v8::External::Wrap(accessor.get());
obj->SetHiddenValue(v8::String::New(kCefAccessor), data);
}
// Attach the tracker object.
tracker->AttachTo(obj);
return new CefV8ValueImpl(obj, tracker);
}
// static
CefRefPtr<CefV8Value> CefV8Value::CreateArray() {
CefRefPtr<CefV8Value> CefV8Value::CreateArray(int length) {
CEF_REQUIRE_VALID_CONTEXT(NULL);
CEF_REQUIRE_UI_THREAD(NULL);
@@ -623,12 +746,23 @@ CefRefPtr<CefV8Value> CefV8Value::CreateArray() {
return NULL;
}
return new CefV8ValueImpl(v8::Array::New());
// Create a tracker object that will cause the user data reference to be
// released when the V8 object is destroyed.
V8TrackObject* tracker = new V8TrackObject;
// Create the new V8 array.
v8::Local<v8::Array> arr = v8::Array::New(length);
// Attach the tracker object.
tracker->AttachTo(arr);
return new CefV8ValueImpl(arr, tracker);
}
// static
CefRefPtr<CefV8Value> CefV8Value::CreateFunction(
const CefString& name, CefRefPtr<CefV8Handler> handler) {
const CefString& name,
CefRefPtr<CefV8Handler> handler) {
CEF_REQUIRE_VALID_CONTEXT(NULL);
CEF_REQUIRE_UI_THREAD(NULL);
@@ -645,7 +779,7 @@ CefRefPtr<CefV8Value> CefV8Value::CreateFunction(
return NULL;
}
// Create a new V8 function template with one internal field.
// Create a new V8 function template.
v8::Local<v8::FunctionTemplate> tmpl = v8::FunctionTemplate::New();
v8::Local<v8::Value> data = v8::External::Wrap(handler.get());
@@ -662,14 +796,13 @@ CefRefPtr<CefV8Value> CefV8Value::CreateFunction(
func->SetName(GetV8String(name));
V8TrackObject* tracker = new V8TrackObject(handler.get());
// Create a tracker object that will cause the user data and/or handler
// reference to be released when the V8 object is destroyed.
V8TrackObject* tracker = new V8TrackObject;
tracker->SetHandler(handler);
// Attach the memory counter.
func->SetHiddenValue(v8::String::New(kCefExternalMemory),
v8::External::Wrap(tracker->GetMemoryCounter()));
// Attach the handler instance to the V8 object.
func->SetHiddenValue(v8::String::New(kCefHandler), data);
// Attach the tracker object.
tracker->AttachTo(func);
// Create the CefV8ValueImpl and provide a tracker object that will cause
// the handler reference to be released when the V8 object is destroyed.
@@ -680,7 +813,8 @@ CefRefPtr<CefV8Value> CefV8Value::CreateFunction(
// CefV8ValueImpl
CefV8ValueImpl::CefV8ValueImpl(v8::Handle<v8::Value> value,
CefTrackNode* tracker) {
CefTrackNode* tracker)
: rethrow_exceptions_(false) {
v8_value_ = new CefV8ValueHandle(value, tracker);
}
@@ -708,6 +842,11 @@ bool CefV8ValueImpl::IsInt() {
return GetHandle()->IsInt32();
}
bool CefV8ValueImpl::IsUInt() {
CEF_REQUIRE_UI_THREAD(false);
return GetHandle()->IsUint32();
}
bool CefV8ValueImpl::IsDouble() {
CEF_REQUIRE_UI_THREAD(false);
return GetHandle()->IsNumber();
@@ -766,13 +905,20 @@ bool CefV8ValueImpl::GetBoolValue() {
}
}
int CefV8ValueImpl::GetIntValue() {
int32 CefV8ValueImpl::GetIntValue() {
CEF_REQUIRE_UI_THREAD(0);
v8::HandleScope handle_scope;
v8::Local<v8::Int32> val = GetHandle()->ToInt32();
return val->Value();
}
uint32 CefV8ValueImpl::GetUIntValue() {
CEF_REQUIRE_UI_THREAD(0);
v8::HandleScope handle_scope;
v8::Local<v8::Uint32> val = GetHandle()->ToUint32();
return val->Value();
}
double CefV8ValueImpl::GetDoubleValue() {
CEF_REQUIRE_UI_THREAD(0.);
v8::HandleScope handle_scope;
@@ -796,12 +942,57 @@ CefString CefV8ValueImpl::GetStringValue() {
return rv;
}
bool CefV8ValueImpl::IsUserCreated() {
CEF_REQUIRE_UI_THREAD(false);
CEF_V8_REQUIRE_OBJECT_RETURN(false);
v8::HandleScope handle_scope;
v8::Local<v8::Object> obj = GetHandle()->ToObject();
V8TrackObject* tracker = V8TrackObject::Unwrap(obj);
return (tracker != NULL);
}
bool CefV8ValueImpl::HasException() {
CEF_REQUIRE_UI_THREAD(false);
CEF_V8_REQUIRE_OBJECT_RETURN(false);
return (last_exception_.get() != NULL);
}
CefRefPtr<CefV8Exception> CefV8ValueImpl::GetException() {
CEF_REQUIRE_UI_THREAD(NULL);
CEF_V8_REQUIRE_OBJECT_RETURN(NULL);
return last_exception_;
}
bool CefV8ValueImpl::ClearException() {
CEF_REQUIRE_UI_THREAD(NULL);
CEF_V8_REQUIRE_OBJECT_RETURN(NULL);
last_exception_ = NULL;
return true;
}
bool CefV8ValueImpl::WillRethrowExceptions() {
CEF_REQUIRE_UI_THREAD(false);
CEF_V8_REQUIRE_OBJECT_RETURN(false);
return rethrow_exceptions_;
}
bool CefV8ValueImpl::SetRethrowExceptions(bool rethrow) {
CEF_REQUIRE_UI_THREAD(false);
CEF_V8_REQUIRE_OBJECT_RETURN(false);
rethrow_exceptions_ = rethrow;
return true;
}
bool CefV8ValueImpl::HasValue(const CefString& key) {
CEF_REQUIRE_UI_THREAD(false);
if (!GetHandle()->IsObject()) {
NOTREACHED() << "V8 value is not an object";
return false;
}
CEF_V8_REQUIRE_OBJECT_RETURN(false);
if (key.empty()) {
NOTREACHED() << "invalid input parameter";
@@ -815,10 +1006,8 @@ bool CefV8ValueImpl::HasValue(const CefString& key) {
bool CefV8ValueImpl::HasValue(int index) {
CEF_REQUIRE_UI_THREAD(false);
if (!GetHandle()->IsObject()) {
NOTREACHED() << "V8 value is not an object";
return false;
}
CEF_V8_REQUIRE_OBJECT_RETURN(false);
if (index < 0) {
NOTREACHED() << "invalid input parameter";
return false;
@@ -831,10 +1020,7 @@ bool CefV8ValueImpl::HasValue(int index) {
bool CefV8ValueImpl::DeleteValue(const CefString& key) {
CEF_REQUIRE_UI_THREAD(false);
if (!GetHandle()->IsObject()) {
NOTREACHED() << "V8 value is not an object";
return false;
}
CEF_V8_REQUIRE_OBJECT_RETURN(false);
if (key.empty()) {
NOTREACHED() << "invalid input parameter";
@@ -843,15 +1029,17 @@ bool CefV8ValueImpl::DeleteValue(const CefString& key) {
v8::HandleScope handle_scope;
v8::Local<v8::Object> obj = GetHandle()->ToObject();
return obj->Delete(GetV8String(key));
v8::TryCatch try_catch;
try_catch.SetVerbose(true);
bool del = obj->Delete(GetV8String(key));
return (!HasCaught(try_catch) && del);
}
bool CefV8ValueImpl::DeleteValue(int index) {
CEF_REQUIRE_UI_THREAD(false);
if (!GetHandle()->IsObject()) {
NOTREACHED() << "V8 value is not an object";
return false;
}
CEF_V8_REQUIRE_OBJECT_RETURN(false);
if (index < 0) {
NOTREACHED() << "invalid input parameter";
return false;
@@ -859,15 +1047,16 @@ bool CefV8ValueImpl::DeleteValue(int index) {
v8::HandleScope handle_scope;
v8::Local<v8::Object> obj = GetHandle()->ToObject();
return obj->Delete(index);
v8::TryCatch try_catch;
try_catch.SetVerbose(true);
bool del = obj->Delete(index);
return (!HasCaught(try_catch) && del);
}
CefRefPtr<CefV8Value> CefV8ValueImpl::GetValue(const CefString& key) {
CEF_REQUIRE_UI_THREAD(NULL);
if (!GetHandle()->IsObject()) {
NOTREACHED() << "V8 value is not an object";
return NULL;
}
CEF_V8_REQUIRE_OBJECT_RETURN(NULL);
if (key.empty()) {
NOTREACHED() << "invalid input parameter";
@@ -876,15 +1065,19 @@ CefRefPtr<CefV8Value> CefV8ValueImpl::GetValue(const CefString& key) {
v8::HandleScope handle_scope;
v8::Local<v8::Object> obj = GetHandle()->ToObject();
return new CefV8ValueImpl(obj->Get(GetV8String(key)));
v8::TryCatch try_catch;
try_catch.SetVerbose(true);
v8::Local<v8::Value> value = obj->Get(GetV8String(key));
if (!HasCaught(try_catch) && !value.IsEmpty())
return new CefV8ValueImpl(value);
return NULL;
}
CefRefPtr<CefV8Value> CefV8ValueImpl::GetValue(int index) {
CEF_REQUIRE_UI_THREAD(NULL);
if (!GetHandle()->IsObject()) {
NOTREACHED() << "V8 value is not an object";
return NULL;
}
CEF_V8_REQUIRE_OBJECT_RETURN(NULL);
if (index < 0) {
NOTREACHED() << "invalid input parameter";
return NULL;
@@ -892,24 +1085,31 @@ CefRefPtr<CefV8Value> CefV8ValueImpl::GetValue(int index) {
v8::HandleScope handle_scope;
v8::Local<v8::Object> obj = GetHandle()->ToObject();
return new CefV8ValueImpl(obj->Get(v8::Number::New(index)));
v8::TryCatch try_catch;
try_catch.SetVerbose(true);
v8::Local<v8::Value> value = obj->Get(v8::Number::New(index));
if (!HasCaught(try_catch) && !value.IsEmpty())
return new CefV8ValueImpl(value);
return NULL;
}
bool CefV8ValueImpl::SetValue(const CefString& key,
CefRefPtr<CefV8Value> value,
PropertyAttribute attribute) {
CEF_REQUIRE_UI_THREAD(false);
if (!GetHandle()->IsObject()) {
NOTREACHED() << "V8 value is not an object";
return false;
}
CEF_V8_REQUIRE_OBJECT_RETURN(false);
CefV8ValueImpl* impl = static_cast<CefV8ValueImpl*>(value.get());
if (impl && !key.empty()) {
v8::HandleScope handle_scope;
v8::Local<v8::Object> obj = GetHandle()->ToObject();
return obj->Set(GetV8String(key), impl->GetHandle(),
static_cast<v8::PropertyAttribute>(attribute));
v8::TryCatch try_catch;
try_catch.SetVerbose(true);
bool set = obj->Set(GetV8String(key), impl->GetHandle(),
static_cast<v8::PropertyAttribute>(attribute));
return (!HasCaught(try_catch) && set);
} else {
NOTREACHED() << "invalid input parameter";
return false;
@@ -918,11 +1118,8 @@ bool CefV8ValueImpl::SetValue(const CefString& key,
bool CefV8ValueImpl::SetValue(int index, CefRefPtr<CefV8Value> value) {
CEF_REQUIRE_UI_THREAD(false);
CEF_V8_REQUIRE_OBJECT_RETURN(false);
if (!GetHandle()->IsObject()) {
NOTREACHED() << "V8 value is not an object";
return false;
}
if (index < 0) {
NOTREACHED() << "invalid input parameter";
return false;
@@ -932,7 +1129,11 @@ bool CefV8ValueImpl::SetValue(int index, CefRefPtr<CefV8Value> value) {
if (impl) {
v8::HandleScope handle_scope;
v8::Local<v8::Object> obj = GetHandle()->ToObject();
return obj->Set(index, impl->GetHandle());
v8::TryCatch try_catch;
try_catch.SetVerbose(true);
bool set = obj->Set(index, impl->GetHandle());
return (!HasCaught(try_catch) && set);
} else {
NOTREACHED() << "invalid input parameter";
return false;
@@ -942,10 +1143,7 @@ bool CefV8ValueImpl::SetValue(int index, CefRefPtr<CefV8Value> value) {
bool CefV8ValueImpl::SetValue(const CefString& key, AccessControl settings,
PropertyAttribute attribute) {
CEF_REQUIRE_UI_THREAD(false);
if (!GetHandle()->IsObject()) {
NOTREACHED() << "V8 value is not an object";
return false;
}
CEF_V8_REQUIRE_OBJECT_RETURN(false);
if (key.empty()) {
NOTREACHED() << "invalid input parameter";
@@ -955,26 +1153,31 @@ bool CefV8ValueImpl::SetValue(const CefString& key, AccessControl settings,
v8::HandleScope handle_scope;
v8::Local<v8::Object> obj = GetHandle()->ToObject();
CefRefPtr<CefV8Accessor> accessorPtr;
V8TrackObject* tracker = V8TrackObject::Unwrap(obj);
if (tracker)
accessorPtr = tracker->GetAccessor();
// Verify that an accessor exists for this object.
if (!GetAccessor(obj))
if (!accessorPtr.get())
return false;
v8::AccessorGetter getter = AccessorGetterCallbackImpl;
v8::AccessorSetter setter = (attribute & V8_PROPERTY_ATTRIBUTE_READONLY) ?
NULL : AccessorSetterCallbackImpl;
bool rv = obj->SetAccessor(GetV8String(key), getter, setter, obj,
static_cast<v8::AccessControl>(settings),
static_cast<v8::PropertyAttribute>(attribute));
return rv;
v8::TryCatch try_catch;
try_catch.SetVerbose(true);
bool set = obj->SetAccessor(GetV8String(key), getter, setter, obj,
static_cast<v8::AccessControl>(settings),
static_cast<v8::PropertyAttribute>(attribute));
return (!HasCaught(try_catch) && set);
}
bool CefV8ValueImpl::GetKeys(std::vector<CefString>& keys) {
CEF_REQUIRE_UI_THREAD(false);
if (!GetHandle()->IsObject()) {
NOTREACHED() << "V8 value is not an object";
return false;
}
CEF_V8_REQUIRE_OBJECT_RETURN(false);
v8::HandleScope handle_scope;
v8::Local<v8::Object> obj = GetHandle()->ToObject();
@@ -989,66 +1192,67 @@ bool CefV8ValueImpl::GetKeys(std::vector<CefString>& keys) {
return true;
}
CefRefPtr<CefBase> CefV8ValueImpl::GetUserData() {
CEF_REQUIRE_UI_THREAD(NULL);
if (!GetHandle()->IsObject()) {
NOTREACHED() << "V8 value is not an object";
return NULL;
}
bool CefV8ValueImpl::SetUserData(CefRefPtr<CefBase> user_data) {
CEF_REQUIRE_UI_THREAD(false);
CEF_V8_REQUIRE_OBJECT_RETURN(false);
v8::HandleScope handle_scope;
v8::Local<v8::Object> obj = GetHandle()->ToObject();
v8::Local<v8::Value> value =
obj->GetHiddenValue(v8::String::New(kCefUserData));
if (!value.IsEmpty())
return static_cast<CefBase*>(v8::External::Unwrap(value));
V8TrackObject* tracker = V8TrackObject::Unwrap(obj);
if (tracker) {
tracker->SetUserData(user_data);
return true;
}
return false;
}
CefRefPtr<CefBase> CefV8ValueImpl::GetUserData() {
CEF_REQUIRE_UI_THREAD(NULL);
CEF_V8_REQUIRE_OBJECT_RETURN(NULL);
v8::HandleScope handle_scope;
v8::Local<v8::Object> obj = GetHandle()->ToObject();
V8TrackObject* tracker = V8TrackObject::Unwrap(obj);
if (tracker)
return tracker->GetUserData();
return NULL;
}
int CefV8ValueImpl::GetExternallyAllocatedMemory() {
CEF_REQUIRE_UI_THREAD(0);
if (!GetHandle()->IsObject()) {
NOTREACHED() << "V8 value is not an object";
return 0;
}
CEF_V8_REQUIRE_OBJECT_RETURN(0);
int* counter = GetExternallyAllocatedMemoryCounter();
return counter != NULL ? *counter : 0;
v8::HandleScope handle_scope;
v8::Local<v8::Object> obj = GetHandle()->ToObject();
V8TrackObject* tracker = V8TrackObject::Unwrap(obj);
if (tracker)
return tracker->GetExternallyAllocatedMemory();
return 0;
}
int CefV8ValueImpl::AdjustExternallyAllocatedMemory(int change_in_bytes) {
CEF_REQUIRE_UI_THREAD(0);
if (!GetHandle()->IsObject()) {
NOTREACHED() << "V8 value is not an object";
return 0;
}
CEF_V8_REQUIRE_OBJECT_RETURN(0);
int* counter = GetExternallyAllocatedMemoryCounter();
if (counter == NULL)
return 0;
v8::HandleScope handle_scope;
v8::Local<v8::Object> obj = GetHandle()->ToObject();
int new_value = *counter + change_in_bytes;
if (new_value < 0) {
NOTREACHED() << "External memory usage cannot be less than 0 bytes";
change_in_bytes = -(*counter);
new_value = 0;
}
V8TrackObject* tracker = V8TrackObject::Unwrap(obj);
if (tracker)
return tracker->AdjustExternallyAllocatedMemory(change_in_bytes);
if (change_in_bytes != 0)
v8::V8::AdjustAmountOfExternalAllocatedMemory(change_in_bytes);
*counter = new_value;
return new_value;
return 0;
}
int CefV8ValueImpl::GetArrayLength() {
CEF_REQUIRE_UI_THREAD(0);
if (!GetHandle()->IsArray()) {
NOTREACHED() << "V8 value is not an array";
return 0;
}
CEF_V8_REQUIRE_ARRAY_RETURN(0);
v8::HandleScope handle_scope;
v8::Local<v8::Object> obj = GetHandle()->ToObject();
@@ -1059,10 +1263,7 @@ int CefV8ValueImpl::GetArrayLength() {
CefString CefV8ValueImpl::GetFunctionName() {
CefString rv;
CEF_REQUIRE_UI_THREAD(rv);
if (!GetHandle()->IsFunction()) {
NOTREACHED() << "V8 value is not a function";
return rv;
}
CEF_V8_REQUIRE_FUNCTION_RETURN(rv);
v8::HandleScope handle_scope;
v8::Local<v8::Object> obj = GetHandle()->ToObject();
@@ -1073,45 +1274,32 @@ CefString CefV8ValueImpl::GetFunctionName() {
CefRefPtr<CefV8Handler> CefV8ValueImpl::GetFunctionHandler() {
CEF_REQUIRE_UI_THREAD(NULL);
if (!GetHandle()->IsFunction()) {
NOTREACHED() << "V8 value is not a function";
return NULL;
}
CEF_V8_REQUIRE_FUNCTION_RETURN(NULL);
v8::HandleScope handle_scope;
v8::Local<v8::Object> obj = GetHandle()->ToObject();
v8::Local<v8::Value> value =
obj->GetHiddenValue(v8::String::New(kCefHandler));
if (!value.IsEmpty())
return static_cast<CefV8Handler*>(v8::External::Unwrap(value));
V8TrackObject* tracker = V8TrackObject::Unwrap(obj);
if (tracker)
return tracker->GetHandler();
return NULL;
}
bool CefV8ValueImpl::ExecuteFunction(CefRefPtr<CefV8Value> object,
const CefV8ValueList& arguments,
CefRefPtr<CefV8Value>& retval,
CefRefPtr<CefV8Exception>& exception,
bool rethrow_exception) {
CefRefPtr<CefV8Value> CefV8ValueImpl::ExecuteFunction(
CefRefPtr<CefV8Value> object,
const CefV8ValueList& arguments) {
// An empty context value defaults to the current context.
CefRefPtr<CefV8Context> context;
return ExecuteFunctionWithContext(context, object, arguments, retval,
exception, rethrow_exception);
return ExecuteFunctionWithContext(context, object, arguments);
}
bool CefV8ValueImpl::ExecuteFunctionWithContext(
CefRefPtr<CefV8Context> context,
CefRefPtr<CefV8Value> object,
const CefV8ValueList& arguments,
CefRefPtr<CefV8Value>& retval,
CefRefPtr<CefV8Exception>& exception,
bool rethrow_exception) {
CEF_REQUIRE_UI_THREAD(false);
if (!GetHandle()->IsFunction()) {
NOTREACHED() << "V8 value is not a function";
return false;
}
CefRefPtr<CefV8Value> CefV8ValueImpl::ExecuteFunctionWithContext(
CefRefPtr<CefV8Context> context,
CefRefPtr<CefV8Value> object,
const CefV8ValueList& arguments) {
CEF_REQUIRE_UI_THREAD(NULL);
CEF_V8_REQUIRE_FUNCTION_RETURN(NULL);
v8::HandleScope handle_scope;
@@ -1146,38 +1334,39 @@ bool CefV8ValueImpl::ExecuteFunctionWithContext(
argv[i] = static_cast<CefV8ValueImpl*>(arguments[i].get())->GetHandle();
}
v8::TryCatch try_catch;
v8::Local<v8::Value> func_rv = func->Call(recv, argc, argv);
if (try_catch.HasCaught()) {
exception = new CefV8ExceptionImpl(try_catch.Message());
if (rethrow_exception)
try_catch.ReThrow();
} else {
retval = new CefV8ValueImpl(func_rv);
CefRefPtr<CefV8Value> retval;
{
v8::TryCatch try_catch;
try_catch.SetVerbose(true);
v8::Local<v8::Value> func_rv;
// Execute the function call using the V8Proxy so that inspector
// instrumentation works.
WebCore::V8Proxy* proxy = WebCore::V8Proxy::retrieve();
DCHECK(proxy);
if (proxy)
func_rv = proxy->callFunction(func, recv, argc, argv);
if (!HasCaught(try_catch) && !func_rv.IsEmpty())
retval = new CefV8ValueImpl(func_rv);
}
if (argv)
delete [] argv;
return true;
return retval;
}
// static
CefV8Accessor* CefV8ValueImpl::GetAccessor(v8::Handle<v8::Object> object) {
v8::Local<v8::Value> value =
object->GetHiddenValue(v8::String::New(kCefAccessor));
if (!value.IsEmpty())
return static_cast<CefV8Accessor*>(v8::External::Unwrap(value));
return NULL;
}
int* CefV8ValueImpl::GetExternallyAllocatedMemoryCounter() {
v8::HandleScope handle_scope;
v8::Local<v8::Object> obj = GetHandle()->ToObject();
v8::Local<v8::Value> value =
obj->GetHiddenValue(v8::String::New(kCefExternalMemory));
return value.IsEmpty() ? NULL : static_cast<int*>(
v8::External::Unwrap(value));
bool CefV8ValueImpl::HasCaught(v8::TryCatch& try_catch) {
if (try_catch.HasCaught()) {
last_exception_ = new CefV8ExceptionImpl(try_catch.Message());
if (rethrow_exceptions_)
try_catch.ReThrow();
return true;
} else {
if (last_exception_.get())
last_exception_ = NULL;
return false;
}
}

View File

@@ -7,6 +7,7 @@
#pragma once
#include <vector>
#include "include/cef_v8.h"
#include "v8/include/v8.h"
#include "libcef/cef_thread.h"
@@ -68,6 +69,9 @@ class CefV8ContextImpl : public CefV8Context {
virtual bool Enter() OVERRIDE;
virtual bool Exit() OVERRIDE;
virtual bool IsSame(CefRefPtr<CefV8Context> that) OVERRIDE;
virtual bool Eval(const CefString& code,
CefRefPtr<CefV8Value>& retval,
CefRefPtr<CefV8Exception>& exception) OVERRIDE;
v8::Local<v8::Context> GetContext();
WebKit::WebFrame* GetWebFrame();
@@ -115,6 +119,7 @@ class CefV8ValueImpl : public CefV8Value {
virtual bool IsNull() OVERRIDE;
virtual bool IsBool() OVERRIDE;
virtual bool IsInt() OVERRIDE;
virtual bool IsUInt() OVERRIDE;
virtual bool IsDouble() OVERRIDE;
virtual bool IsDate() OVERRIDE;
virtual bool IsString() OVERRIDE;
@@ -123,10 +128,17 @@ class CefV8ValueImpl : public CefV8Value {
virtual bool IsFunction() OVERRIDE;
virtual bool IsSame(CefRefPtr<CefV8Value> value) OVERRIDE;
virtual bool GetBoolValue() OVERRIDE;
virtual int GetIntValue() OVERRIDE;
virtual int32 GetIntValue() OVERRIDE;
virtual uint32 GetUIntValue() OVERRIDE;
virtual double GetDoubleValue() OVERRIDE;
virtual CefTime GetDateValue() OVERRIDE;
virtual CefString GetStringValue() OVERRIDE;
virtual bool IsUserCreated() OVERRIDE;
virtual bool HasException() OVERRIDE;
virtual CefRefPtr<CefV8Exception> GetException() OVERRIDE;
virtual bool ClearException() OVERRIDE;
virtual bool WillRethrowExceptions() OVERRIDE;
virtual bool SetRethrowExceptions(bool rethrow) OVERRIDE;
virtual bool HasValue(const CefString& key) OVERRIDE;
virtual bool HasValue(int index) OVERRIDE;
virtual bool DeleteValue(const CefString& key) OVERRIDE;
@@ -139,38 +151,33 @@ class CefV8ValueImpl : public CefV8Value {
virtual bool SetValue(const CefString& key, AccessControl settings,
PropertyAttribute attribute) OVERRIDE;
virtual bool GetKeys(std::vector<CefString>& keys) OVERRIDE;
virtual bool SetUserData(CefRefPtr<CefBase> user_data) OVERRIDE;
virtual CefRefPtr<CefBase> GetUserData() OVERRIDE;
virtual int GetExternallyAllocatedMemory() OVERRIDE;
virtual int AdjustExternallyAllocatedMemory(int change_in_bytes) OVERRIDE;
virtual int GetArrayLength() OVERRIDE;
virtual CefString GetFunctionName() OVERRIDE;
virtual CefRefPtr<CefV8Handler> GetFunctionHandler() OVERRIDE;
virtual bool ExecuteFunction(CefRefPtr<CefV8Value> object,
const CefV8ValueList& arguments,
CefRefPtr<CefV8Value>& retval,
CefRefPtr<CefV8Exception>& exception,
bool rethrow_exception) OVERRIDE;
virtual bool ExecuteFunctionWithContext(
CefRefPtr<CefV8Context> context,
CefRefPtr<CefV8Value> object,
const CefV8ValueList& arguments,
CefRefPtr<CefV8Value>& retval,
CefRefPtr<CefV8Exception>& exception,
bool rethrow_exception) OVERRIDE;
virtual CefRefPtr<CefV8Value> ExecuteFunction(
CefRefPtr<CefV8Value> object,
const CefV8ValueList& arguments) OVERRIDE;
virtual CefRefPtr<CefV8Value> ExecuteFunctionWithContext(
CefRefPtr<CefV8Context> context,
CefRefPtr<CefV8Value> object,
const CefV8ValueList& arguments) OVERRIDE;
inline v8::Handle<v8::Value> GetHandle() {
DCHECK(v8_value_.get());
return v8_value_->GetHandle();
}
// Returns the accessor assigned for the specified object, if any.
static CefV8Accessor* GetAccessor(v8::Handle<v8::Object> object);
private:
int* GetExternallyAllocatedMemoryCounter();
protected:
// Test for and record any exception.
bool HasCaught(v8::TryCatch& try_catch);
scoped_refptr<CefV8ValueHandle> v8_value_;
CefRefPtr<CefV8Exception> last_exception_;
bool rethrow_exceptions_;
IMPLEMENT_REFCOUNTING(CefV8ValueImpl);
DISALLOW_COPY_AND_ASSIGN(CefV8ValueImpl);

View File

@@ -14,9 +14,12 @@
#include "webkit/plugins/npapi/gtk_plugin_container_manager.h"
#endif
struct WebPreferences;
class BrowserWebViewDelegate;
namespace webkit_glue {
struct WebPreferences;
}
namespace WebKit {
class WebDevToolsAgentClient;
class WebView;
@@ -33,7 +36,7 @@ class WebViewHost : public WebWidgetHost {
BrowserWebViewDelegate* delegate,
PaintDelegate* paint_delegate,
WebKit::WebDevToolsAgentClient* devtools_client,
const WebPreferences& prefs);
const webkit_glue::WebPreferences& prefs);
virtual ~WebViewHost();

View File

@@ -28,7 +28,7 @@ WebViewHost* WebViewHost::Create(GtkWidget* parent_view,
BrowserWebViewDelegate* delegate,
PaintDelegate* paint_delegate,
WebDevToolsAgentClient* dev_tools_client,
const WebPreferences& prefs) {
const webkit_glue::WebPreferences& prefs) {
WebViewHost* host = new WebViewHost(delegate);
host->view_ = WebWidgetHost::CreateWidget(parent_view, host);

View File

@@ -31,7 +31,7 @@ WebViewHost* WebViewHost::Create(NSView* parent_view,
BrowserWebViewDelegate* delegate,
PaintDelegate* paint_delegate,
WebDevToolsAgentClient* dev_tools_client,
const WebPreferences& prefs) {
const webkit_glue::WebPreferences& prefs) {
WebViewHost* host = new WebViewHost(delegate);
NSRect content_rect = {{rect.x(), rect.y()}, {rect.width(), rect.height()}};

View File

@@ -28,7 +28,7 @@ WebViewHost* WebViewHost::Create(HWND parent_view,
BrowserWebViewDelegate* delegate,
PaintDelegate* paint_delegate,
WebDevToolsAgentClient* dev_tools_client,
const WebPreferences& prefs) {
const webkit_glue::WebPreferences& prefs) {
WebViewHost* host = new WebViewHost(delegate);
if (!paint_delegate) {