summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/webkit/WebCore/storage
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2009-07-13 20:00:20 (GMT)
committerSimon Hausmann <simon.hausmann@nokia.com>2009-07-13 20:00:20 (GMT)
commitf23fa541a04abd1ddc36815a285ec824d5b5c5e0 (patch)
tree3d1002cb8367e8635bc0a0f78724661cbf75a8cb /src/3rdparty/webkit/WebCore/storage
parentfd302ab05face6c592944187fb594c1f55d62c5d (diff)
downloadQt-f23fa541a04abd1ddc36815a285ec824d5b5c5e0.zip
Qt-f23fa541a04abd1ddc36815a285ec824d5b5c5e0.tar.gz
Qt-f23fa541a04abd1ddc36815a285ec824d5b5c5e0.tar.bz2
Updated WebKit from /home/shausman/src/webkit/trunk to qtwebkit-4.6-snapshot-13072009 ( b2abc0c271880b8135507861056af497f895adf5 )
Changes in WebKit/qt since the last update: ++ b/WebKit/qt/ChangeLog 2009-07-13 Simon Hausmann <simon.hausmann@nokia.com> Reviewed by Ariya Hidayat. Fix qdoc warnings for QWebPage::shouldInterruptJavaScript() and mention how to re-implement it. * Api/qwebpage.cpp: 2009-07-13 Simon Hausmann <hausmann@webkit.org> Reviewed by Ariya Hidayat. Fix crash with plugins when the plugin stream is cancelled. Similar to r26667 handle the case where didReceiveResponse on the plugin view results in failure to set up the stream and setMainDocumentError being called instead. This will set the m_pluginView back to 0 and we need check for it before calling didReceiveData. This was triggered by consecutive execution of LayoutTests/plugins/return-error-from-new-stream-callback-in-full-frame-plugin.html followed by LayoutTests/scrollbars/scrollbar-crash-on-refresh.html * WebCoreSupport/FrameLoaderClientQt.cpp: (WebCore::FrameLoaderClientQt::committedLoad): 2009-07-13 Simon Hausmann <hausmann@webkit.org> Reviewed by Ariya Hidayat. Added QWebDatabase::removeAllDatabases, as a way to delete all databases from the offline storage path. Used by the Qt DRT. * Api/qwebdatabase.cpp: (QWebDatabase::removeAllDatabases): * Api/qwebdatabase.h: 2009-07-13 Simon Hausmann <hausmann@webkit.org> Reviewed by Ariya Hidayat. Added loadStarted() and loadFinished() signals to QWebFrame, to allow load tracking of individual frames, as opposed to QWebPage's loadStarted/loadFinished signals that are emitted whenever _any_ child frame loads/finishes. * Api/qwebframe.cpp: Document new signals. * Api/qwebframe.h: Add new signals. * WebCoreSupport/FrameLoaderClientQt.cpp: (WebCore::FrameLoaderClientQt::setFrame): Connect new signals. 2009-07-13 Simon Hausmann <hausmann@webkit.org> Reviewed by Ariya Hidayat. Add hooks for the GCController JavaScript interface needed by the Qt DRT. Fixed sort order of includes in qwebframe.cpp. * Api/qwebframe.cpp: (qt_drt_javaScriptObjectsCount): (qt_drt_garbageCollector_collect): (qt_drt_garbageCollector_collectOnAlternateThread): 2009-07-13 Simon Hausmann <hausmann@webkit.org> Reviewed by Ariya Hidayat. Add hooks for the GCController JavaScript interface needed by the Qt DRT. Fixed sort order of includes in qwebframe.cpp. * Api/qwebframe.cpp: (qt_drt_javaScriptObjectsCount): (qt_drt_garbageCollector_collect): (qt_drt_garbageCollector_collectOnAlternateThread): 2009-07-12 Brent Fulgham <bfulgham@gmail.com> Speculative build fix after http://trac.webkit.org/changeset/45786. * WebCoreSupport/ChromeClientQt.cpp: (WebCore::ChromeClientQt::addMessageToConsole): * WebCoreSupport/ChromeClientQt.h: 2009-07-10 Yael Aharon <yael.aharon@nokia.com> Reviewed by Holger Freyther. https://bugs.webkit.org/show_bug.cgi?id=27136 Fix a bug where webkit hangs when executing infinite JavaScript loop. * Api/qwebpage.cpp: (QWebPage::shouldInterruptJavaScript): * Api/qwebpage.h: * WebCoreSupport/ChromeClientQt.cpp: (WebCore::ChromeClientQt::shouldInterruptJavaScript): * tests/qwebpage/tst_qwebpage.cpp: (JSTestPage::JSTestPage): (JSTestPage::shouldInterruptJavaScript): (tst_QWebPage::infiniteLoopJS): 2009-07-10 Simon Hausmann <simon.hausmann@nokia.com> Reviewed by Holger Freyther. https://bugs.webkit.org/show_bug.cgi?id=27108 Fix crash when in frame tree of a new frame before the new frame has been installed in the frame tree, similar to r35088. After calling Frame::init() the frame it may have been removed from the frame tree again through JavaScript. Detect this by checking the page() afterwards. To make this check safe the Frame::init() code was moved into QWebFrameData's constructor, where a RefPtr holds a reference to the frame. After the check back in FrameLoaderClientQt we would hold the single reference left and after release() the frame, its frame loader, its client as well as the QWebFrame should have disappeared then. * Api/qwebframe.cpp: (QWebFramePrivate::init): Only call Frame::init here, the rest is done in QWebFrameData's constructor. (QWebFrame::QWebFrame): * Api/qwebframe_p.h: Adjust declaration. (QWebFrameData::QWebFrameData): Create the Frame here. * Api/qwebpage.cpp: (QWebPagePrivate::createMainFrame): Adjust and simplify to new QWebFrame constructor. * WebCoreSupport/FrameLoaderClientQt.cpp: (WebCore::FrameLoaderClientQt::createFrame): Adjust to new QWebFrame construction using QWebFrameData and add the check like in r35088. 2009-07-09 Beth Dakin <bdakin@apple.com> Reviewed by Dave Hyatt. Make Widget RefCounted to fix: <rdar://problem/7038831> REGRESSION (TOT): In Mail, a crash occurs at WebCore::Widget::afterMouseDown() after clicking To Do's close box <rdar://problem/6978804> WER #16: Repro Access Violation in WebCore::PluginView::bindingInstance (1310178023) -and- <rdar://problem/6991251> WER #13: Crash in WebKit! WebCore::PluginView::performRequest+203 (1311461169) * WebCoreSupport/FrameLoaderClientQt.cpp: (WebCore::FrameLoaderClientQt::createPlugin): (WebCore::FrameLoaderClientQt::createJavaAppletWidget): * WebCoreSupport/FrameLoaderClientQt.h: 2009-07-08 Pradeepto Bhattacharya <pradeepto@kde.org> Reviewed by Ariya Hidayat. Build fix. * WebCoreSupport/FrameLoaderClientQt.h: Removed the slot slotCallPolicyFunction(). 2009-07-08 Simon Hausmann <hausmann@webkit.org> Reviewed by Tor Arne Vestbø. https://bugs.webkit.org/show_bug.cgi?id=27080 Fix DRT instability issues with fast/loader/submit-form-while-parsing-2.html When the form is submitted we call the policy function in the frame loader delayed with a queued connection. That queued connection sometimes interferes with the javascript timeout set in the testcase. Eliminate the entire delayed policy function mechanism and instead always call back directly, like in the other ports. In most other places we called the slot directly anyway. * WebCoreSupport/FrameLoaderClientQt.cpp: (WebCore::FrameLoaderClientQt::FrameLoaderClientQt): Remove m_policyFunction. (WebCore::FrameLoaderClientQt::callPolicyFunction): Call the policy function directly instead of emitting the queued signal. (WebCore::FrameLoaderClientQt::cancelPolicyCheck): Call callPolicyFunction directly. (WebCore::FrameLoaderClientQt::dispatchWillSubmitForm): Ditto. (WebCore::FrameLoaderClientQt::dispatchDecidePolicyForMIMEType): Ditto. (WebCore::FrameLoaderClientQt::dispatchDecidePolicyForNewWindowAction): Ditto. (WebCore::FrameLoaderClientQt::dispatchDecidePolicyForNavigationAction): Ditto. * WebCoreSupport/FrameLoaderClientQt.h: Remove m_policyFunction as well as the associated signal. 2009-07-07 Simon Hausmann <hausmann@webkit.org> Reviewed by Holger Freyther. Add Qt DRT hook for clearing the frame name. * Api/qwebframe.cpp: (qt_drt_clearFrameName): 2009-07-05 Simon Hausmann <hausmann@webkit.org> Reviewed by Holger Freyther. Fix two qdoc warnings. Added missing \property for QWebFrame::hasFocus and added \a tag for pos of QWebPage::frameAt. * Api/qwebframe.cpp: * Api/qwebpage.cpp: 2009-07-04 Holger Hans Peter Freyther <zecke@selfish.org> Reviewed by Simon Hausmann. Use the recently introduced FocusController::setFocused Use the recently introduced FocusController::setFocused in the Qt platform. The SelectionController will be updated from within the FocusController now. * Api/qwebpage.cpp: (QWebPagePrivate::focusInEvent): (QWebPagePrivate::focusOutEvent): 2009-07-02 Simon Hausmann <simon.hausmann@nokia.com> Reviewed by Ariya Hidayat. Improve documentation of QWebFrame::setFocus and hasFocus() Added missing Q_PROPERTY for QWebFrame::hasFocus. * Api/qwebframe.cpp: Clarify the docs. * Api/qwebframe.h: add Q_PROPERTY(focus). 2009-07-02 Joe Ligman <joseph.ligman@nokia.com> Reviewed by Simon Hausmann. Bug 26855: [Qt] New methods for QWebFrame to check and set focus. Added new public methods QWebFrame::hasFocus() and QWebFrame::setFocus() Added auto test. * Api/qwebframe.cpp: (QWebFrame::hasFocus): (QWebFrame::setFocus): * Api/qwebframe.h: * tests/qwebframe/tst_qwebframe.cpp: 2009-07-01 Robert Hogan <robert@roberthogan.net> Reviewed by NOBODY. Fix Qt segfault when javascript disabled. If clients call addToJavaScriptWindowObject even though JavascriptEnabled is false webkit will segfault on the assert: ASSERTION FAILED: _rootObject (../../../WebCore/bridge/runtime.cpp:52 JSC::Bindings::Instance::Instance(WTF::PassRefPtr<JSC::Bindings::RootObject>)) Fix is to ensure JavaScript is enabled when client calls addToJavaScriptWindowObject. https://bugs.webkit.org/show_bug.cgi?id=26906 * Api/qwebframe.cpp: (QWebFrame::addToJavaScriptWindowObject): 2009-07-01 Jakub Wieczorek <faw217@gmail.com> Reviewed by Simon Hausmann. [Qt] Move some API headers from WebCore.pro to headers.pri so that they get installed when running make install from the build directory. * Api/headers.pri: 2009-07-01 Balazs Kelemen <kelemen.balazs.3@stud.u-szeged.hu> Reviewed by Simon Hausmann. Fixed robotized QtLauncher to work when there is no index.html in the user's home. * QtLauncher/main.cpp: (main): 2009-06-30 Brian Weinstein <bweinstein@apple.com> Reviewed by Adam Roben. Renamed scrollbarUnderPoint to scrollbarAtPoint to follow conventions. * Api/qwebpage.cpp: (QWebPage::swallowContextMenuEvent): 2009-06-30 Joe Ligman <joseph.ligman@nokia.com> Reviewed by Adam Treat. Bug 26422: [Qt] QWebPagePrivate::frameAt calculates wrong frame Added a public method QWebPage::frameAt Removed QWebPagePrivate::frameAt, which calcuated the wrong frame Modified QWebPage::swallowContextMenuEvent to use the new frameAt method New test case for frameAt added to tst_qwebpage.cpp * Api/qwebpage.cpp: (QWebPage::frameAt): (QWebPage::swallowContextMenuEvent): * Api/qwebpage.h: * Api/qwebpage_p.h: * tests/qwebpage/frametest/iframe.html: Added. * tests/qwebpage/frametest/iframe2.html: Added. * tests/qwebpage/frametest/iframe3.html: Added. * tests/qwebpage/tst_qwebpage.cpp: (frameAtHelper): (tst_QWebPage::frameAt): * tests/qwebpage/tst_qwebpage.qrc: 2009-06-30 Jakub Wieczorek <faw217@gmail.com> Reviewed by Simon Hausmann. Add QWebFrame::baseUrl() function that exposes the base URL of a frame. Autotests included. * Api/qwebframe.cpp: (QWebFrame::baseUrl): * Api/qwebframe.h: * tests/qwebframe/tst_qwebframe.cpp:
Diffstat (limited to 'src/3rdparty/webkit/WebCore/storage')
-rw-r--r--src/3rdparty/webkit/WebCore/storage/Database.cpp24
-rw-r--r--src/3rdparty/webkit/WebCore/storage/Database.h3
-rw-r--r--src/3rdparty/webkit/WebCore/storage/DatabaseTask.h15
-rw-r--r--src/3rdparty/webkit/WebCore/storage/DatabaseThread.cpp27
-rw-r--r--src/3rdparty/webkit/WebCore/storage/DatabaseThread.h8
-rw-r--r--src/3rdparty/webkit/WebCore/storage/DatabaseTracker.cpp55
-rw-r--r--src/3rdparty/webkit/WebCore/storage/OriginUsageRecord.cpp12
-rw-r--r--src/3rdparty/webkit/WebCore/storage/StorageArea.cpp221
-rw-r--r--src/3rdparty/webkit/WebCore/storage/StorageArea.h44
-rw-r--r--src/3rdparty/webkit/WebCore/storage/StorageAreaImpl.cpp266
-rw-r--r--src/3rdparty/webkit/WebCore/storage/StorageAreaImpl.h80
-rw-r--r--src/3rdparty/webkit/WebCore/storage/StorageAreaSync.h3
-rw-r--r--src/3rdparty/webkit/WebCore/storage/StorageNamespace.cpp96
-rw-r--r--src/3rdparty/webkit/WebCore/storage/StorageNamespace.h26
-rw-r--r--src/3rdparty/webkit/WebCore/storage/StorageNamespaceImpl.cpp129
-rw-r--r--src/3rdparty/webkit/WebCore/storage/StorageNamespaceImpl.h66
16 files changed, 657 insertions, 418 deletions
diff --git a/src/3rdparty/webkit/WebCore/storage/Database.cpp b/src/3rdparty/webkit/WebCore/storage/Database.cpp
index 53bccbe..2292a0a 100644
--- a/src/3rdparty/webkit/WebCore/storage/Database.cpp
+++ b/src/3rdparty/webkit/WebCore/storage/Database.cpp
@@ -40,7 +40,6 @@
#include "DatabaseTracker.h"
#include "Document.h"
#include "ExceptionCode.h"
-#include "FileSystem.h"
#include "Frame.h"
#include "InspectorController.h"
#include "Logging.h"
@@ -48,6 +47,7 @@
#include "Page.h"
#include "OriginQuotaManager.h"
#include "SQLiteDatabase.h"
+#include "SQLiteFileSystem.h"
#include "SQLiteStatement.h"
#include "SQLResultSet.h"
#include <wtf/MainThread.h>
@@ -60,6 +60,9 @@
namespace WebCore {
+// If we sleep for more the 30 seconds while blocked on SQLITE_BUSY, give up.
+static const int maxSqliteBusyWaitTime = 30000;
+
const String& Database::databaseInfoTableName()
{
DEFINE_STATIC_LOCAL(String, name, ("__WebKitDatabaseInfoTable__"));
@@ -132,6 +135,7 @@ Database::Database(Document* document, const String& name, const String& expecte
, m_expectedVersion(expectedVersion)
, m_deleted(false)
, m_stopped(false)
+ , m_opened(false)
{
ASSERT(document);
m_securityOrigin = document->securityOrigin();
@@ -316,7 +320,13 @@ void Database::markAsDeletedAndClose()
void Database::close()
{
- m_sqliteDatabase.close();
+ if (m_opened) {
+ ASSERT(m_document->databaseThread());
+ ASSERT(currentThread() == document()->databaseThread()->getThreadID());
+ m_sqliteDatabase.close();
+ m_document->databaseThread()->recordDatabaseClosed(this);
+ m_opened = false;
+ }
}
void Database::stop()
@@ -338,10 +348,7 @@ void Database::stop()
unsigned long long Database::databaseSize() const
{
- long long size;
- if (!getFileSize(m_filename, size))
- size = 0;
- return size;
+ return SQLiteFileSystem::getDatabaseFileSize(m_filename);
}
unsigned long long Database::maximumSize() const
@@ -426,8 +433,13 @@ bool Database::performOpenAndVerify(ExceptionCode& e)
return false;
}
+ m_opened = true;
+ if (m_document->databaseThread())
+ m_document->databaseThread()->recordDatabaseOpen(this);
+
ASSERT(m_databaseAuthorizer);
m_sqliteDatabase.setAuthorizer(m_databaseAuthorizer);
+ m_sqliteDatabase.setBusyTimeout(maxSqliteBusyWaitTime);
if (!m_sqliteDatabase.tableExists(databaseInfoTableName())) {
if (!m_sqliteDatabase.executeCommand("CREATE TABLE " + databaseInfoTableName() + " (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE,value TEXT NOT NULL ON CONFLICT FAIL);")) {
diff --git a/src/3rdparty/webkit/WebCore/storage/Database.h b/src/3rdparty/webkit/WebCore/storage/Database.h
index 385485a..0bdb37b 100644
--- a/src/3rdparty/webkit/WebCore/storage/Database.h
+++ b/src/3rdparty/webkit/WebCore/storage/Database.h
@@ -100,6 +100,7 @@ public:
bool deleted() const { return m_deleted; }
void close();
+ bool opened() const { return m_opened; }
void stop();
bool stopped() const { return m_stopped; }
@@ -141,6 +142,8 @@ private:
bool m_stopped;
+ bool m_opened;
+
SQLiteDatabase m_sqliteDatabase;
RefPtr<DatabaseAuthorizer> m_databaseAuthorizer;
diff --git a/src/3rdparty/webkit/WebCore/storage/DatabaseTask.h b/src/3rdparty/webkit/WebCore/storage/DatabaseTask.h
index a3814d7..4aef892 100644
--- a/src/3rdparty/webkit/WebCore/storage/DatabaseTask.h
+++ b/src/3rdparty/webkit/WebCore/storage/DatabaseTask.h
@@ -45,8 +45,7 @@ class SQLCallback;
class SQLTransaction;
class VersionChangeCallback;
-class DatabaseTask : public ThreadSafeShared<DatabaseTask>
-{
+class DatabaseTask : public ThreadSafeShared<DatabaseTask> {
friend class Database;
public:
virtual ~DatabaseTask();
@@ -76,8 +75,7 @@ private:
OwnPtr<ThreadCondition> m_synchronousCondition;
};
-class DatabaseOpenTask : public DatabaseTask
-{
+class DatabaseOpenTask : public DatabaseTask {
public:
static PassRefPtr<DatabaseOpenTask> create(Database* db) { return adoptRef(new DatabaseOpenTask(db)); }
@@ -96,8 +94,7 @@ private:
bool m_success;
};
-class DatabaseCloseTask : public DatabaseTask
-{
+class DatabaseCloseTask : public DatabaseTask {
public:
static PassRefPtr<DatabaseCloseTask> create(Database* db) { return adoptRef(new DatabaseCloseTask(db)); }
@@ -110,8 +107,7 @@ private:
#endif
};
-class DatabaseTransactionTask : public DatabaseTask
-{
+class DatabaseTransactionTask : public DatabaseTask {
public:
static PassRefPtr<DatabaseTransactionTask> create(PassRefPtr<SQLTransaction> transaction) { return adoptRef(new DatabaseTransactionTask(transaction)); }
@@ -129,8 +125,7 @@ private:
RefPtr<SQLTransaction> m_transaction;
};
-class DatabaseTableNamesTask : public DatabaseTask
-{
+class DatabaseTableNamesTask : public DatabaseTask {
public:
static PassRefPtr<DatabaseTableNamesTask> create(Database* db) { return adoptRef(new DatabaseTableNamesTask(db)); }
diff --git a/src/3rdparty/webkit/WebCore/storage/DatabaseThread.cpp b/src/3rdparty/webkit/WebCore/storage/DatabaseThread.cpp
index fab02a2..b6c9b5d 100644
--- a/src/3rdparty/webkit/WebCore/storage/DatabaseThread.cpp
+++ b/src/3rdparty/webkit/WebCore/storage/DatabaseThread.cpp
@@ -99,6 +99,17 @@ void* DatabaseThread::databaseThread()
LOG(StorageAPI, "About to detach thread %i and clear the ref to DatabaseThread %p, which currently has %i ref(s)", m_threadID, this, refCount());
+ // Close the databases that we ran transactions on. This ensures that if any transactions are still open, they are rolled back and we don't leave the database in an
+ // inconsistent or locked state.
+ if (m_openDatabaseSet.size() > 0) {
+ // As the call to close will modify the original set, we must take a copy to iterate over.
+ DatabaseSet openSetCopy;
+ openSetCopy.swap(m_openDatabaseSet);
+ DatabaseSet::iterator end = openSetCopy.end();
+ for (DatabaseSet::iterator it = openSetCopy.begin(); it != end; ++it)
+ (*it)->close();
+ }
+
// Detach the thread so its resources are no longer of any concern to anyone else
detachThread(m_threadID);
@@ -108,6 +119,22 @@ void* DatabaseThread::databaseThread()
return 0;
}
+void DatabaseThread::recordDatabaseOpen(Database* database)
+{
+ ASSERT(currentThread() == m_threadID);
+ ASSERT(database);
+ ASSERT(!m_openDatabaseSet.contains(database));
+ m_openDatabaseSet.add(database);
+}
+
+void DatabaseThread::recordDatabaseClosed(Database* database)
+{
+ ASSERT(currentThread() == m_threadID);
+ ASSERT(database);
+ ASSERT(m_queue.killed() || m_openDatabaseSet.contains(database));
+ m_openDatabaseSet.remove(database);
+}
+
void DatabaseThread::scheduleTask(PassRefPtr<DatabaseTask> task)
{
m_queue.append(task);
diff --git a/src/3rdparty/webkit/WebCore/storage/DatabaseThread.h b/src/3rdparty/webkit/WebCore/storage/DatabaseThread.h
index 9f13c33..5aab5fd 100644
--- a/src/3rdparty/webkit/WebCore/storage/DatabaseThread.h
+++ b/src/3rdparty/webkit/WebCore/storage/DatabaseThread.h
@@ -56,6 +56,10 @@ public:
void scheduleImmediateTask(PassRefPtr<DatabaseTask>); // This just adds the task to the front of the queue - the caller needs to be extremely careful not to create deadlocks when waiting for completion.
void unscheduleDatabaseTasks(Database*);
+ void recordDatabaseOpen(Database*);
+ void recordDatabaseClosed(Database*);
+ ThreadIdentifier getThreadID() { return m_threadID; }
+
private:
DatabaseThread();
@@ -67,6 +71,10 @@ private:
RefPtr<DatabaseThread> m_selfRef;
MessageQueue<RefPtr<DatabaseTask> > m_queue;
+
+ // This set keeps track of the open databases that have been used on this thread.
+ typedef HashSet<RefPtr<Database> > DatabaseSet;
+ DatabaseSet m_openDatabaseSet;
};
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/storage/DatabaseTracker.cpp b/src/3rdparty/webkit/WebCore/storage/DatabaseTracker.cpp
index 9311bc6..4a64fe6 100644
--- a/src/3rdparty/webkit/WebCore/storage/DatabaseTracker.cpp
+++ b/src/3rdparty/webkit/WebCore/storage/DatabaseTracker.cpp
@@ -35,12 +35,12 @@
#include "Database.h"
#include "DatabaseTrackerClient.h"
#include "Document.h"
-#include "FileSystem.h"
#include "Logging.h"
#include "OriginQuotaManager.h"
#include "Page.h"
#include "SecurityOrigin.h"
#include "SecurityOriginHash.h"
+#include "SQLiteFileSystem.h"
#include "SQLiteStatement.h"
#include <wtf/MainThread.h>
#include <wtf/StdLibExtras.h>
@@ -69,6 +69,7 @@ DatabaseTracker::DatabaseTracker()
, m_thread(currentThread())
#endif
{
+ SQLiteFileSystem::registerSQLiteVFS();
}
void DatabaseTracker::setDatabaseDirectoryPath(const String& path)
@@ -87,9 +88,7 @@ const String& DatabaseTracker::databaseDirectoryPath() const
String DatabaseTracker::trackerDatabasePath() const
{
ASSERT(currentThread() == m_thread);
- if (m_databaseDirectoryPath.isEmpty())
- return String();
- return pathByAppendingComponent(m_databaseDirectoryPath, "Databases.db");
+ return SQLiteFileSystem::appendDatabaseFileNameToPath(m_databaseDirectoryPath, "Databases.db");
}
void DatabaseTracker::openTrackerDatabase(bool createIfDoesNotExist)
@@ -100,13 +99,9 @@ void DatabaseTracker::openTrackerDatabase(bool createIfDoesNotExist)
return;
String databasePath = trackerDatabasePath();
- if (databasePath.isEmpty())
- return;
-
- if (!createIfDoesNotExist && !fileExists(databasePath))
+ if (!SQLiteFileSystem::ensureDatabaseFileExists(databasePath, createIfDoesNotExist))
return;
- makeAllDirectories(m_databaseDirectoryPath);
if (!m_database.open(databasePath)) {
// FIXME: What do do here?
return;
@@ -190,9 +185,7 @@ bool DatabaseTracker::hasEntryForDatabase(SecurityOrigin* origin, const String&
String DatabaseTracker::originPath(SecurityOrigin* origin) const
{
ASSERT(currentThread() == m_thread);
- if (m_databaseDirectoryPath.isEmpty())
- return String();
- return pathByAppendingComponent(m_databaseDirectoryPath, origin->databaseIdentifier());
+ return SQLiteFileSystem::appendDatabaseFileNameToPath(m_databaseDirectoryPath, origin->databaseIdentifier());
}
String DatabaseTracker::fullPathForDatabase(SecurityOrigin* origin, const String& name, bool createIfNotExists)
@@ -206,7 +199,7 @@ String DatabaseTracker::fullPathForDatabase(SecurityOrigin* origin, const String
String originPath = this->originPath(origin);
// Make sure the path for this SecurityOrigin exists
- if (createIfNotExists && !makeAllDirectories(originPath))
+ if (createIfNotExists && !SQLiteFileSystem::ensureDatabaseDirectoryExists(originPath))
return String();
// See if we have a path for this database yet
@@ -224,7 +217,7 @@ String DatabaseTracker::fullPathForDatabase(SecurityOrigin* origin, const String
int result = statement.step();
if (result == SQLResultRow)
- return pathByAppendingComponent(originPath, statement.getColumnText(0));
+ return SQLiteFileSystem::appendDatabaseFileNameToPath(originPath, statement.getColumnText(0));
if (!createIfNotExists)
return String();
@@ -241,33 +234,20 @@ String DatabaseTracker::fullPathForDatabase(SecurityOrigin* origin, const String
return String();
result = sequenceStatement.step();
- // This has a range of 2^63 and starts at 0 for every time a user resets Safari -
- // I can't imagine it'd over overflow
- int64_t seq = 0;
- if (result == SQLResultRow) {
- seq = sequenceStatement.getColumnInt64(0);
- } else if (result != SQLResultDone)
- return String();
- sequenceStatement.finalize();
-
- String filename;
- do {
- ++seq;
- filename = pathByAppendingComponent(originPath, String::format("%016llx.db", seq));
- } while (fileExists(filename));
-
- if (!addDatabase(origin, name, String::format("%016llx.db", seq)))
+ String fileName = SQLiteFileSystem::getFileNameForNewDatabase(originPath, origin->databaseIdentifier(), name, &m_database);
+ if (!addDatabase(origin, name, fileName))
return String();
// If this origin's quota is being tracked (open handle to a database in this origin), add this new database
// to the quota manager now
+ String fullFilePath = SQLiteFileSystem::appendDatabaseFileNameToPath(originPath, fileName);
{
Locker<OriginQuotaManager> locker(originQuotaManager());
if (originQuotaManager().tracksOrigin(origin))
- originQuotaManager().addDatabase(origin, name, filename);
+ originQuotaManager().addDatabase(origin, name, fullFilePath);
}
- return filename;
+ return fullFilePath;
}
void DatabaseTracker::populateOrigins()
@@ -423,8 +403,7 @@ unsigned long long DatabaseTracker::usageForDatabase(const String& name, Securit
if (path.isEmpty())
return 0;
- long long size;
- return getFileSize(path, size) ? size : 0;
+ return SQLiteFileSystem::getDatabaseFileSize(path);
}
void DatabaseTracker::addOpenDatabase(Database* database)
@@ -665,7 +644,7 @@ void DatabaseTracker::deleteOrigin(SecurityOrigin* origin)
return;
}
- deleteEmptyDirectory(originPath(origin));
+ SQLiteFileSystem::deleteEmptyDatabaseDirectory(originPath(origin));
RefPtr<SecurityOrigin> originPossiblyLastReference = origin;
{
@@ -679,8 +658,8 @@ void DatabaseTracker::deleteOrigin(SecurityOrigin* origin)
if (m_quotaMap->isEmpty()) {
if (m_database.isOpen())
m_database.close();
- deleteFile(trackerDatabasePath());
- deleteEmptyDirectory(m_databaseDirectoryPath);
+ SQLiteFileSystem::deleteDatabaseFile(trackerDatabasePath());
+ SQLiteFileSystem::deleteEmptyDatabaseDirectory(m_databaseDirectoryPath);
}
}
@@ -763,7 +742,7 @@ bool DatabaseTracker::deleteDatabaseFile(SecurityOrigin* origin, const String& n
for (unsigned i = 0; i < deletedDatabases.size(); ++i)
deletedDatabases[i]->markAsDeletedAndClose();
- return deleteFile(fullPath);
+ return SQLiteFileSystem::deleteDatabaseFile(fullPath);
}
void DatabaseTracker::setClient(DatabaseTrackerClient* client)
diff --git a/src/3rdparty/webkit/WebCore/storage/OriginUsageRecord.cpp b/src/3rdparty/webkit/WebCore/storage/OriginUsageRecord.cpp
index 211ba69..5f4957f 100644
--- a/src/3rdparty/webkit/WebCore/storage/OriginUsageRecord.cpp
+++ b/src/3rdparty/webkit/WebCore/storage/OriginUsageRecord.cpp
@@ -30,7 +30,7 @@
#if ENABLE(DATABASE)
-#include "FileSystem.h"
+#include "SQLiteFileSystem.h"
namespace WebCore {
@@ -82,13 +82,9 @@ unsigned long long OriginUsageRecord::diskUsage()
const String& path = m_databaseMap.get(*iUnknown).filename;
ASSERT(!path.isEmpty());
- long long size;
- if (getFileSize(path, size))
- m_databaseMap.set(*iUnknown, DatabaseEntry(path, size));
- else {
- // When we can't determine the file size, we'll just have to assume the file is missing/inaccessible.
- m_databaseMap.set(*iUnknown, DatabaseEntry(path, 0));
- }
+ // When we can't determine the file size, we'll just have to assume the file is missing/inaccessible.
+ long long size = SQLiteFileSystem::getDatabaseFileSize(path);
+ m_databaseMap.set(*iUnknown, DatabaseEntry(path, size));
}
m_unknownSet.clear();
diff --git a/src/3rdparty/webkit/WebCore/storage/StorageArea.cpp b/src/3rdparty/webkit/WebCore/storage/StorageArea.cpp
index ac41447..11b3517 100644
--- a/src/3rdparty/webkit/WebCore/storage/StorageArea.cpp
+++ b/src/3rdparty/webkit/WebCore/storage/StorageArea.cpp
@@ -26,228 +26,19 @@
#include "config.h"
#include "StorageArea.h"
+#if PLATFORM(CHROMIUM)
+#error "Chromium should not compile this file and instead define its own version of these factories that navigate the multi-process boundry."
+#endif
+
#if ENABLE(DOM_STORAGE)
-#include "EventNames.h"
-#include "ExceptionCode.h"
-#include "Frame.h"
-#include "Page.h"
-#include "PageGroup.h"
-#include "SecurityOrigin.h"
-#include "Settings.h"
-#include "StorageEvent.h"
-#include "StorageAreaSync.h"
-#include "StorageMap.h"
-#include "StorageSyncManager.h"
+#include "StorageAreaImpl.h"
namespace WebCore {
PassRefPtr<StorageArea> StorageArea::create(StorageType storageType, SecurityOrigin* origin, PassRefPtr<StorageSyncManager> syncManager)
{
- return adoptRef(new StorageArea(storageType, origin, syncManager));
-}
-
-StorageArea::StorageArea(StorageType storageType, SecurityOrigin* origin, PassRefPtr<StorageSyncManager> syncManager)
- : m_storageType(storageType)
- , m_securityOrigin(origin)
- , m_storageMap(StorageMap::create())
- , m_storageSyncManager(syncManager)
-#ifndef NDEBUG
- , m_isShutdown(false)
-#endif
-{
- ASSERT(m_securityOrigin);
- ASSERT(m_storageMap);
-
- // FIXME: If there's no backing storage for LocalStorage, the default WebKit behavior should be that of private browsing,
- // not silently ignoring it. https://bugs.webkit.org/show_bug.cgi?id=25894
- if (m_storageSyncManager) {
- m_storageAreaSync = StorageAreaSync::create(m_storageSyncManager, this);
- ASSERT(m_storageAreaSync);
- }
-}
-
-PassRefPtr<StorageArea> StorageArea::copy(SecurityOrigin* origin)
-{
- ASSERT(!m_isShutdown);
- return adoptRef(new StorageArea(origin, this));
-}
-
-StorageArea::StorageArea(SecurityOrigin* origin, StorageArea* area)
- : m_storageType(area->m_storageType)
- , m_securityOrigin(origin)
- , m_storageMap(area->m_storageMap)
- , m_storageSyncManager(area->m_storageSyncManager)
-#ifndef NDEBUG
- , m_isShutdown(area->m_isShutdown)
-#endif
-{
- ASSERT(m_securityOrigin);
- ASSERT(m_storageMap);
- ASSERT(!m_isShutdown);
-}
-
-unsigned StorageArea::length() const
-{
- ASSERT(!m_isShutdown);
- return m_storageMap->length();
-}
-
-String StorageArea::key(unsigned index, ExceptionCode& ec) const
-{
- ASSERT(!m_isShutdown);
- blockUntilImportComplete();
-
- String key;
-
- if (!m_storageMap->key(index, key)) {
- ec = INDEX_SIZE_ERR;
- return String();
- }
-
- return key;
-}
-
-String StorageArea::getItem(const String& key) const
-{
- ASSERT(!m_isShutdown);
- blockUntilImportComplete();
-
- return m_storageMap->getItem(key);
-}
-
-void StorageArea::setItem(const String& key, const String& value, ExceptionCode& ec, Frame* frame)
-{
- ASSERT(!m_isShutdown);
- ASSERT(!value.isNull());
- blockUntilImportComplete();
-
- if (frame->page()->settings()->privateBrowsingEnabled()) {
- ec = QUOTA_EXCEEDED_ERR;
- return;
- }
-
- // FIXME: For LocalStorage where a disk quota will be enforced, here is where we need to do quota checking.
- // If we decide to enforce a memory quota for SessionStorage, this is where we'd do that, also.
- // if (<over quota>) {
- // ec = QUOTA_EXCEEDED_ERR;
- // return;
- // }
-
- String oldValue;
- RefPtr<StorageMap> newMap = m_storageMap->setItem(key, value, oldValue);
-
- if (newMap)
- m_storageMap = newMap.release();
-
- // Only notify the client if an item was actually changed
- if (oldValue != value) {
- if (m_storageAreaSync)
- m_storageAreaSync->scheduleItemForSync(key, value);
- dispatchStorageEvent(key, oldValue, value, frame);
- }
-}
-
-void StorageArea::removeItem(const String& key, Frame* frame)
-{
- ASSERT(!m_isShutdown);
- blockUntilImportComplete();
-
- if (frame->page()->settings()->privateBrowsingEnabled())
- return;
-
- String oldValue;
- RefPtr<StorageMap> newMap = m_storageMap->removeItem(key, oldValue);
- if (newMap)
- m_storageMap = newMap.release();
-
- // Only notify the client if an item was actually removed
- if (!oldValue.isNull()) {
- if (m_storageAreaSync)
- m_storageAreaSync->scheduleItemForSync(key, String());
- dispatchStorageEvent(key, oldValue, String(), frame);
- }
-}
-
-void StorageArea::clear(Frame* frame)
-{
- ASSERT(!m_isShutdown);
- blockUntilImportComplete();
-
- if (frame->page()->settings()->privateBrowsingEnabled())
- return;
-
- m_storageMap = StorageMap::create();
-
- if (m_storageAreaSync)
- m_storageAreaSync->scheduleClear();
- dispatchStorageEvent(String(), String(), String(), frame);
-}
-
-bool StorageArea::contains(const String& key) const
-{
- ASSERT(!m_isShutdown);
- blockUntilImportComplete();
-
- return m_storageMap->contains(key);
-}
-
-void StorageArea::importItem(const String& key, const String& value)
-{
- ASSERT(!m_isShutdown);
- m_storageMap->importItem(key, value);
-}
-
-void StorageArea::close()
-{
- if (m_storageAreaSync)
- m_storageAreaSync->scheduleFinalSync();
-
-#ifndef NDEBUG
- m_isShutdown = true;
-#endif
-}
-
-void StorageArea::blockUntilImportComplete() const
-{
- if (m_storageAreaSync)
- m_storageAreaSync->blockUntilImportComplete();
-}
-
-void StorageArea::dispatchStorageEvent(const String& key, const String& oldValue, const String& newValue, Frame* sourceFrame)
-{
- // We need to copy all relevant frames from every page to a vector since sending the event to one frame might mutate the frame tree
- // of any given page in the group or mutate the page group itself.
- Vector<RefPtr<Frame> > frames;
-
- // FIXME: When can this occur?
- Page* page = sourceFrame->page();
- if (!page)
- return;
-
- if (m_storageType == SessionStorage) {
- // Send events only to our page.
- for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
- if (frame->document()->securityOrigin()->equal(securityOrigin()))
- frames.append(frame);
- }
-
- for (unsigned i = 0; i < frames.size(); ++i)
- frames[i]->document()->dispatchWindowEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->documentURI(), sourceFrame->domWindow(), frames[i]->domWindow()->sessionStorage()));
- } else {
- // Send events to every page.
- const HashSet<Page*>& pages = page->group().pages();
- HashSet<Page*>::const_iterator end = pages.end();
- for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) {
- for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
- if (frame->document()->securityOrigin()->equal(securityOrigin()))
- frames.append(frame);
- }
- }
-
- for (unsigned i = 0; i < frames.size(); ++i)
- frames[i]->document()->dispatchWindowEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->documentURI(), sourceFrame->domWindow(), frames[i]->domWindow()->localStorage()));
- }
+ return StorageAreaImpl::create(storageType, origin, syncManager);
}
}
diff --git a/src/3rdparty/webkit/WebCore/storage/StorageArea.h b/src/3rdparty/webkit/WebCore/storage/StorageArea.h
index 69e7882..31f716a 100644
--- a/src/3rdparty/webkit/WebCore/storage/StorageArea.h
+++ b/src/3rdparty/webkit/WebCore/storage/StorageArea.h
@@ -50,45 +50,27 @@ namespace WebCore {
typedef int ExceptionCode;
enum StorageType { LocalStorage, SessionStorage };
+ // This interface is required for Chromium since these actions need to be proxied between processes.
class StorageArea : public ThreadSafeShared<StorageArea> {
public:
static PassRefPtr<StorageArea> create(StorageType, SecurityOrigin*, PassRefPtr<StorageSyncManager>);
- PassRefPtr<StorageArea> copy(SecurityOrigin*);
+ virtual ~StorageArea() { }
+ virtual PassRefPtr<StorageArea> copy(SecurityOrigin*) = 0;
// The HTML5 DOM Storage API
- unsigned length() const;
- String key(unsigned index, ExceptionCode& ec) const;
- String getItem(const String& key) const;
- void setItem(const String& key, const String& value, ExceptionCode& ec, Frame* sourceFrame);
- void removeItem(const String& key, Frame* sourceFrame);
- void clear(Frame* sourceFrame);
+ virtual unsigned length() const = 0;
+ virtual String key(unsigned index, ExceptionCode& ec) const = 0;
+ virtual String getItem(const String& key) const = 0;
+ virtual void setItem(const String& key, const String& value, ExceptionCode& ec, Frame* sourceFrame) = 0;
+ virtual void removeItem(const String& key, Frame* sourceFrame) = 0;
+ virtual void clear(Frame* sourceFrame) = 0;
- bool contains(const String& key) const;
- void close();
+ virtual bool contains(const String& key) const = 0;
+ virtual void close() = 0;
// Could be called from a background thread.
- void importItem(const String& key, const String& value);
- SecurityOrigin* securityOrigin() { return m_securityOrigin.get(); }
-
- protected:
- StorageArea(StorageType, SecurityOrigin*, PassRefPtr<StorageSyncManager>);
- StorageArea(SecurityOrigin*, StorageArea*);
-
- private:
- void blockUntilImportComplete() const;
-
- void dispatchStorageEvent(const String& key, const String& oldValue, const String& newValue, Frame* sourceFrame);
-
- StorageType m_storageType;
- RefPtr<SecurityOrigin> m_securityOrigin;
- RefPtr<StorageMap> m_storageMap;
-
- RefPtr<StorageAreaSync> m_storageAreaSync;
- RefPtr<StorageSyncManager> m_storageSyncManager;
-
-#ifndef NDEBUG
- bool m_isShutdown;
-#endif
+ virtual void importItem(const String& key, const String& value) = 0;
+ virtual SecurityOrigin* securityOrigin() = 0;
};
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/storage/StorageAreaImpl.cpp b/src/3rdparty/webkit/WebCore/storage/StorageAreaImpl.cpp
new file mode 100644
index 0000000..ba31658
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/storage/StorageAreaImpl.cpp
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "StorageAreaImpl.h"
+
+#if ENABLE(DOM_STORAGE)
+
+#include "DOMWindow.h"
+#include "EventNames.h"
+#include "ExceptionCode.h"
+#include "Frame.h"
+#include "Page.h"
+#include "PageGroup.h"
+#include "SecurityOrigin.h"
+#include "Settings.h"
+#include "StorageEvent.h"
+#include "StorageAreaSync.h"
+#include "StorageMap.h"
+#include "StorageSyncManager.h"
+
+namespace WebCore {
+
+PassRefPtr<StorageArea> StorageAreaImpl::create(StorageType storageType, SecurityOrigin* origin, PassRefPtr<StorageSyncManager> syncManager)
+{
+ return adoptRef(new StorageAreaImpl(storageType, origin, syncManager));
+}
+
+StorageAreaImpl::~StorageAreaImpl()
+{
+}
+
+StorageAreaImpl::StorageAreaImpl(StorageType storageType, SecurityOrigin* origin, PassRefPtr<StorageSyncManager> syncManager)
+ : m_storageType(storageType)
+ , m_securityOrigin(origin)
+ , m_storageMap(StorageMap::create())
+ , m_storageSyncManager(syncManager)
+#ifndef NDEBUG
+ , m_isShutdown(false)
+#endif
+{
+ ASSERT(m_securityOrigin);
+ ASSERT(m_storageMap);
+
+ // FIXME: If there's no backing storage for LocalStorage, the default WebKit behavior should be that of private browsing,
+ // not silently ignoring it. https://bugs.webkit.org/show_bug.cgi?id=25894
+ if (m_storageSyncManager) {
+ m_storageAreaSync = StorageAreaSync::create(m_storageSyncManager, this);
+ ASSERT(m_storageAreaSync);
+ }
+}
+
+PassRefPtr<StorageArea> StorageAreaImpl::copy(SecurityOrigin* origin)
+{
+ ASSERT(!m_isShutdown);
+ return adoptRef(new StorageAreaImpl(origin, this));
+}
+
+StorageAreaImpl::StorageAreaImpl(SecurityOrigin* origin, StorageAreaImpl* area)
+ : m_storageType(area->m_storageType)
+ , m_securityOrigin(origin)
+ , m_storageMap(area->m_storageMap)
+ , m_storageSyncManager(area->m_storageSyncManager)
+#ifndef NDEBUG
+ , m_isShutdown(area->m_isShutdown)
+#endif
+{
+ ASSERT(m_securityOrigin);
+ ASSERT(m_storageMap);
+ ASSERT(!m_isShutdown);
+}
+
+unsigned StorageAreaImpl::length() const
+{
+ ASSERT(!m_isShutdown);
+ return m_storageMap->length();
+}
+
+String StorageAreaImpl::key(unsigned index, ExceptionCode& ec) const
+{
+ ASSERT(!m_isShutdown);
+ blockUntilImportComplete();
+
+ String key;
+
+ if (!m_storageMap->key(index, key)) {
+ ec = INDEX_SIZE_ERR;
+ return String();
+ }
+
+ return key;
+}
+
+String StorageAreaImpl::getItem(const String& key) const
+{
+ ASSERT(!m_isShutdown);
+ blockUntilImportComplete();
+
+ return m_storageMap->getItem(key);
+}
+
+void StorageAreaImpl::setItem(const String& key, const String& value, ExceptionCode& ec, Frame* frame)
+{
+ ASSERT(!m_isShutdown);
+ ASSERT(!value.isNull());
+ blockUntilImportComplete();
+
+ if (frame->page()->settings()->privateBrowsingEnabled()) {
+ ec = QUOTA_EXCEEDED_ERR;
+ return;
+ }
+
+ // FIXME: For LocalStorage where a disk quota will be enforced, here is where we need to do quota checking.
+ // If we decide to enforce a memory quota for SessionStorage, this is where we'd do that, also.
+ // if (<over quota>) {
+ // ec = QUOTA_EXCEEDED_ERR;
+ // return;
+ // }
+
+ String oldValue;
+ RefPtr<StorageMap> newMap = m_storageMap->setItem(key, value, oldValue);
+
+ if (newMap)
+ m_storageMap = newMap.release();
+
+ // Only notify the client if an item was actually changed
+ if (oldValue != value) {
+ if (m_storageAreaSync)
+ m_storageAreaSync->scheduleItemForSync(key, value);
+ dispatchStorageEvent(key, oldValue, value, frame);
+ }
+}
+
+void StorageAreaImpl::removeItem(const String& key, Frame* frame)
+{
+ ASSERT(!m_isShutdown);
+ blockUntilImportComplete();
+
+ if (frame->page()->settings()->privateBrowsingEnabled())
+ return;
+
+ String oldValue;
+ RefPtr<StorageMap> newMap = m_storageMap->removeItem(key, oldValue);
+ if (newMap)
+ m_storageMap = newMap.release();
+
+ // Only notify the client if an item was actually removed
+ if (!oldValue.isNull()) {
+ if (m_storageAreaSync)
+ m_storageAreaSync->scheduleItemForSync(key, String());
+ dispatchStorageEvent(key, oldValue, String(), frame);
+ }
+}
+
+void StorageAreaImpl::clear(Frame* frame)
+{
+ ASSERT(!m_isShutdown);
+ blockUntilImportComplete();
+
+ if (frame->page()->settings()->privateBrowsingEnabled())
+ return;
+
+ m_storageMap = StorageMap::create();
+
+ if (m_storageAreaSync)
+ m_storageAreaSync->scheduleClear();
+ dispatchStorageEvent(String(), String(), String(), frame);
+}
+
+bool StorageAreaImpl::contains(const String& key) const
+{
+ ASSERT(!m_isShutdown);
+ blockUntilImportComplete();
+
+ return m_storageMap->contains(key);
+}
+
+void StorageAreaImpl::importItem(const String& key, const String& value)
+{
+ ASSERT(!m_isShutdown);
+ m_storageMap->importItem(key, value);
+}
+
+SecurityOrigin* StorageAreaImpl::securityOrigin()
+{
+ return m_securityOrigin.get();
+}
+
+void StorageAreaImpl::close()
+{
+ if (m_storageAreaSync)
+ m_storageAreaSync->scheduleFinalSync();
+
+#ifndef NDEBUG
+ m_isShutdown = true;
+#endif
+}
+
+void StorageAreaImpl::blockUntilImportComplete() const
+{
+ if (m_storageAreaSync)
+ m_storageAreaSync->blockUntilImportComplete();
+}
+
+void StorageAreaImpl::dispatchStorageEvent(const String& key, const String& oldValue, const String& newValue, Frame* sourceFrame)
+{
+ // We need to copy all relevant frames from every page to a vector since sending the event to one frame might mutate the frame tree
+ // of any given page in the group or mutate the page group itself.
+ Vector<RefPtr<Frame> > frames;
+
+ // FIXME: When can this occur?
+ Page* page = sourceFrame->page();
+ if (!page)
+ return;
+
+ if (m_storageType == SessionStorage) {
+ // Send events only to our page.
+ for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
+ if (frame->document()->securityOrigin()->equal(securityOrigin()))
+ frames.append(frame);
+ }
+
+ for (unsigned i = 0; i < frames.size(); ++i)
+ frames[i]->document()->dispatchWindowEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->documentURI(), sourceFrame->domWindow(), frames[i]->domWindow()->sessionStorage()));
+ } else {
+ // Send events to every page.
+ const HashSet<Page*>& pages = page->group().pages();
+ HashSet<Page*>::const_iterator end = pages.end();
+ for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) {
+ for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
+ if (frame->document()->securityOrigin()->equal(securityOrigin()))
+ frames.append(frame);
+ }
+ }
+
+ for (unsigned i = 0; i < frames.size(); ++i)
+ frames[i]->document()->dispatchWindowEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->documentURI(), sourceFrame->domWindow(), frames[i]->domWindow()->localStorage()));
+ }
+}
+
+}
+
+#endif // ENABLE(DOM_STORAGE)
+
diff --git a/src/3rdparty/webkit/WebCore/storage/StorageAreaImpl.h b/src/3rdparty/webkit/WebCore/storage/StorageAreaImpl.h
new file mode 100644
index 0000000..e2d14f1
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/storage/StorageAreaImpl.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef StorageAreaImpl_h
+#define StorageAreaImpl_h
+
+#if ENABLE(DOM_STORAGE)
+
+#include "StorageArea.h"
+
+namespace WebCore {
+
+ class StorageAreaImpl : public StorageArea {
+ public:
+ static PassRefPtr<StorageArea> create(StorageType, SecurityOrigin*, PassRefPtr<StorageSyncManager>);
+ virtual ~StorageAreaImpl();
+ virtual PassRefPtr<StorageArea> copy(SecurityOrigin*);
+
+ // The HTML5 DOM Storage API
+ virtual unsigned length() const;
+ virtual String key(unsigned index, ExceptionCode& ec) const;
+ virtual String getItem(const String& key) const;
+ virtual void setItem(const String& key, const String& value, ExceptionCode& ec, Frame* sourceFrame);
+ virtual void removeItem(const String& key, Frame* sourceFrame);
+ virtual void clear(Frame* sourceFrame);
+
+ virtual bool contains(const String& key) const;
+ virtual void close();
+
+ // Could be called from a background thread.
+ void importItem(const String& key, const String& value);
+ SecurityOrigin* securityOrigin();
+
+ private:
+ StorageAreaImpl(StorageType, SecurityOrigin*, PassRefPtr<StorageSyncManager>);
+ StorageAreaImpl(SecurityOrigin*, StorageAreaImpl*);
+
+ void blockUntilImportComplete() const;
+
+ void dispatchStorageEvent(const String& key, const String& oldValue, const String& newValue, Frame* sourceFrame);
+
+ StorageType m_storageType;
+ RefPtr<SecurityOrigin> m_securityOrigin;
+ RefPtr<StorageMap> m_storageMap;
+
+ RefPtr<StorageAreaSync> m_storageAreaSync;
+ RefPtr<StorageSyncManager> m_storageSyncManager;
+
+#ifndef NDEBUG
+ bool m_isShutdown;
+#endif
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(DOM_STORAGE)
+
+#endif // StorageAreaImpl_h
diff --git a/src/3rdparty/webkit/WebCore/storage/StorageAreaSync.h b/src/3rdparty/webkit/WebCore/storage/StorageAreaSync.h
index fa10e63..a7f1082 100644
--- a/src/3rdparty/webkit/WebCore/storage/StorageAreaSync.h
+++ b/src/3rdparty/webkit/WebCore/storage/StorageAreaSync.h
@@ -37,7 +37,7 @@
namespace WebCore {
class Frame;
- class StorageArea;
+ class StorageArea;
class StorageSyncManager;
class StorageAreaSync : public RefCounted<StorageAreaSync> {
@@ -57,7 +57,6 @@ namespace WebCore {
private:
StorageAreaSync(PassRefPtr<StorageSyncManager> storageSyncManager, PassRefPtr<StorageArea> storageArea);
-
void dispatchStorageEvent(const String& key, const String& oldValue, const String& newValue, Frame* sourceFrame);
Timer<StorageAreaSync> m_syncTimer;
diff --git a/src/3rdparty/webkit/WebCore/storage/StorageNamespace.cpp b/src/3rdparty/webkit/WebCore/storage/StorageNamespace.cpp
index d8d85a7..6fcae63 100644
--- a/src/3rdparty/webkit/WebCore/storage/StorageNamespace.cpp
+++ b/src/3rdparty/webkit/WebCore/storage/StorageNamespace.cpp
@@ -26,104 +26,26 @@
#include "config.h"
#include "StorageNamespace.h"
-#if ENABLE(DOM_STORAGE)
-
-#include <wtf/StdLibExtras.h>
+#include "StorageNamespaceImpl.h"
-namespace WebCore {
+#if PLATFORM(CHROMIUM)
+#error "Chromium should not compile this file and instead define its own version of these factories that navigate the multi-process boundry."
+#endif
-typedef HashMap<String, StorageNamespace*> LocalStorageNamespaceMap;
+#if ENABLE(DOM_STORAGE)
-static LocalStorageNamespaceMap& localStorageNamespaceMap()
-{
- DEFINE_STATIC_LOCAL(LocalStorageNamespaceMap, localStorageNamespaceMap, ());
- return localStorageNamespaceMap;
-}
+namespace WebCore {
PassRefPtr<StorageNamespace> StorageNamespace::localStorageNamespace(const String& path)
{
- const String lookupPath = path.isNull() ? String("") : path;
- LocalStorageNamespaceMap::iterator it = localStorageNamespaceMap().find(lookupPath);
- if (it == localStorageNamespaceMap().end()) {
- RefPtr<StorageNamespace> storageNamespace = adoptRef(new StorageNamespace(LocalStorage, lookupPath));
- localStorageNamespaceMap().set(lookupPath, storageNamespace.get());
- return storageNamespace.release();
- }
-
- return it->second;
+ return StorageNamespaceImpl::localStorageNamespace(path);
}
PassRefPtr<StorageNamespace> StorageNamespace::sessionStorageNamespace()
{
- return adoptRef(new StorageNamespace(SessionStorage, String()));
-}
-
-StorageNamespace::StorageNamespace(StorageType storageType, const String& path)
- : m_storageType(storageType)
- , m_path(path.copy()) // FIXME: Is the .copy necessary?
- , m_syncManager(0)
-#ifndef NDEBUG
- , m_isShutdown(false)
-#endif
-{
- if (m_storageType == LocalStorage && !m_path.isEmpty())
- m_syncManager = StorageSyncManager::create(m_path);
-}
-
-StorageNamespace::~StorageNamespace()
-{
- ASSERT(isMainThread());
-
- if (m_storageType == LocalStorage) {
- ASSERT(localStorageNamespaceMap().get(m_path) == this);
- localStorageNamespaceMap().remove(m_path);
- }
-}
-
-PassRefPtr<StorageNamespace> StorageNamespace::copy()
-{
- ASSERT(isMainThread());
- ASSERT(!m_isShutdown);
-
- RefPtr<StorageNamespace> newNamespace = adoptRef(new StorageNamespace(m_storageType, m_path));
-
- StorageAreaMap::iterator end = m_storageAreaMap.end();
- for (StorageAreaMap::iterator i = m_storageAreaMap.begin(); i != end; ++i) {
- RefPtr<StorageArea> areaCopy = i->second->copy(i->first.get());
- newNamespace->m_storageAreaMap.set(i->first, areaCopy.release());
- }
-
- return newNamespace.release();
-}
-
-PassRefPtr<StorageArea> StorageNamespace::storageArea(SecurityOrigin* origin)
-{
- ASSERT(isMainThread());
- ASSERT(!m_isShutdown);
-
- RefPtr<StorageArea> storageArea;
- if (storageArea = m_storageAreaMap.get(origin))
- return storageArea.release();
-
- storageArea = StorageArea::create(m_storageType, origin, m_syncManager);
- m_storageAreaMap.set(origin, storageArea);
- return storageArea.release();
+ return StorageNamespaceImpl::sessionStorageNamespace();
}
-void StorageNamespace::close()
-{
- ASSERT(isMainThread());
- ASSERT(!m_isShutdown);
-
- StorageAreaMap::iterator end = m_storageAreaMap.end();
- for (StorageAreaMap::iterator it = m_storageAreaMap.begin(); it != end; ++it)
- it->second->close();
-
-#ifndef NDEBUG
- m_isShutdown = true;
-#endif
-}
+} // namespace WebCore
#endif // ENABLE(DOM_STORAGE)
-
-} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/storage/StorageNamespace.h b/src/3rdparty/webkit/WebCore/storage/StorageNamespace.h
index 5621b01..687cea2 100644
--- a/src/3rdparty/webkit/WebCore/storage/StorageNamespace.h
+++ b/src/3rdparty/webkit/WebCore/storage/StorageNamespace.h
@@ -39,32 +39,16 @@ namespace WebCore {
class StorageArea;
class StorageSyncManager;
+ // This interface is required for Chromium since these actions need to be proxied between processes.
class StorageNamespace : public RefCounted<StorageNamespace> {
public:
- ~StorageNamespace();
-
static PassRefPtr<StorageNamespace> localStorageNamespace(const String& path);
static PassRefPtr<StorageNamespace> sessionStorageNamespace();
- PassRefPtr<StorageArea> storageArea(SecurityOrigin*);
- PassRefPtr<StorageNamespace> copy();
- void close();
-
- private:
- StorageNamespace(StorageType, const String& path);
-
- typedef HashMap<RefPtr<SecurityOrigin>, RefPtr<StorageArea>, SecurityOriginHash> StorageAreaMap;
- StorageAreaMap m_storageAreaMap;
-
- StorageType m_storageType;
-
- // Only used if m_storageType == LocalStorage and the path was not "" in our constructor.
- String m_path;
- RefPtr<StorageSyncManager> m_syncManager;
-
-#ifndef NDEBUG
- bool m_isShutdown;
-#endif
+ virtual ~StorageNamespace() { }
+ virtual PassRefPtr<StorageArea> storageArea(SecurityOrigin*) = 0;
+ virtual PassRefPtr<StorageNamespace> copy() = 0;
+ virtual void close() = 0;
};
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/storage/StorageNamespaceImpl.cpp b/src/3rdparty/webkit/WebCore/storage/StorageNamespaceImpl.cpp
new file mode 100644
index 0000000..39ec27b
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/storage/StorageNamespaceImpl.cpp
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "StorageNamespaceImpl.h"
+
+#if ENABLE(DOM_STORAGE)
+
+#include <wtf/StdLibExtras.h>
+
+namespace WebCore {
+
+typedef HashMap<String, StorageNamespace*> LocalStorageNamespaceMap;
+
+static LocalStorageNamespaceMap& localStorageNamespaceMap()
+{
+ DEFINE_STATIC_LOCAL(LocalStorageNamespaceMap, localStorageNamespaceMap, ());
+ return localStorageNamespaceMap;
+}
+
+PassRefPtr<StorageNamespace> StorageNamespaceImpl::localStorageNamespace(const String& path)
+{
+ const String lookupPath = path.isNull() ? String("") : path;
+ LocalStorageNamespaceMap::iterator it = localStorageNamespaceMap().find(lookupPath);
+ if (it == localStorageNamespaceMap().end()) {
+ RefPtr<StorageNamespace> storageNamespace = adoptRef(new StorageNamespaceImpl(LocalStorage, lookupPath));
+ localStorageNamespaceMap().set(lookupPath, storageNamespace.get());
+ return storageNamespace.release();
+ }
+
+ return it->second;
+}
+
+PassRefPtr<StorageNamespace> StorageNamespaceImpl::sessionStorageNamespace()
+{
+ return adoptRef(new StorageNamespaceImpl(SessionStorage, String()));
+}
+
+StorageNamespaceImpl::StorageNamespaceImpl(StorageType storageType, const String& path)
+ : m_storageType(storageType)
+ , m_path(path.copy()) // FIXME: Is the .copy necessary?
+ , m_syncManager(0)
+#ifndef NDEBUG
+ , m_isShutdown(false)
+#endif
+{
+ if (m_storageType == LocalStorage && !m_path.isEmpty())
+ m_syncManager = StorageSyncManager::create(m_path);
+}
+
+StorageNamespaceImpl::~StorageNamespaceImpl()
+{
+ ASSERT(isMainThread());
+
+ if (m_storageType == LocalStorage) {
+ ASSERT(localStorageNamespaceMap().get(m_path) == this);
+ localStorageNamespaceMap().remove(m_path);
+ }
+}
+
+PassRefPtr<StorageNamespace> StorageNamespaceImpl::copy()
+{
+ ASSERT(isMainThread());
+ ASSERT(!m_isShutdown);
+
+ StorageNamespaceImpl* newNamespace = new StorageNamespaceImpl(m_storageType, m_path);
+
+ StorageAreaMap::iterator end = m_storageAreaMap.end();
+ for (StorageAreaMap::iterator i = m_storageAreaMap.begin(); i != end; ++i) {
+ RefPtr<StorageArea> areaCopy = i->second->copy(i->first.get());
+ newNamespace->m_storageAreaMap.set(i->first, areaCopy.release());
+ }
+
+ return adoptRef(newNamespace);
+}
+
+PassRefPtr<StorageArea> StorageNamespaceImpl::storageArea(SecurityOrigin* origin)
+{
+ ASSERT(isMainThread());
+ ASSERT(!m_isShutdown);
+
+ RefPtr<StorageArea> storageArea;
+ if (storageArea = m_storageAreaMap.get(origin))
+ return storageArea.release();
+
+ storageArea = StorageArea::create(m_storageType, origin, m_syncManager);
+ m_storageAreaMap.set(origin, storageArea);
+ return storageArea.release();
+}
+
+void StorageNamespaceImpl::close()
+{
+ ASSERT(isMainThread());
+ ASSERT(!m_isShutdown);
+
+ StorageAreaMap::iterator end = m_storageAreaMap.end();
+ for (StorageAreaMap::iterator it = m_storageAreaMap.begin(); it != end; ++it)
+ it->second->close();
+
+#ifndef NDEBUG
+ m_isShutdown = true;
+#endif
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(DOM_STORAGE)
diff --git a/src/3rdparty/webkit/WebCore/storage/StorageNamespaceImpl.h b/src/3rdparty/webkit/WebCore/storage/StorageNamespaceImpl.h
new file mode 100644
index 0000000..6c5a9dc
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/storage/StorageNamespaceImpl.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef StorageNamespaceImpl_h
+#define StorageNamespaceImpl_h
+
+#if ENABLE(DOM_STORAGE)
+
+#include "StorageNamespace.h"
+
+namespace WebCore {
+
+ class StorageNamespaceImpl : public StorageNamespace {
+ public:
+ static PassRefPtr<StorageNamespace> localStorageNamespace(const String& path);
+ static PassRefPtr<StorageNamespace> sessionStorageNamespace();
+
+ virtual ~StorageNamespaceImpl();
+ virtual PassRefPtr<StorageArea> storageArea(SecurityOrigin*);
+ virtual PassRefPtr<StorageNamespace> copy();
+ virtual void close();
+
+ private:
+ StorageNamespaceImpl(StorageType, const String& path);
+
+ typedef HashMap<RefPtr<SecurityOrigin>, RefPtr<StorageArea>, SecurityOriginHash> StorageAreaMap;
+ StorageAreaMap m_storageAreaMap;
+
+ StorageType m_storageType;
+
+ // Only used if m_storageType == LocalStorage and the path was not "" in our constructor.
+ String m_path;
+ RefPtr<StorageSyncManager> m_syncManager;
+
+#ifndef NDEBUG
+ bool m_isShutdown;
+#endif
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(DOM_STORAGE)
+
+#endif // StorageNamespaceImpl_h