Reviewed and landed by Brady Eidson.
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 11 Mar 2011 23:24:54 +0000 (23:24 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 11 Mar 2011 23:24:54 +0000 (23:24 +0000)
Source/WebCore:

Patch by Anton D'Auria <adauria@apple.com> on 2011-03-11
Add WebKit1 API to view and delete local storage
https://bugs.webkit.org/show_bug.cgi?id=51878

Created StorageTracker as a central point for tracking and deleting LocalStorage per origin.
StorageTracker maintains its own database of origin identifiers and backing db paths,
and this allows it to contain more relational data in the future, like variable quotas per origin.

On initialization, StorageTracker syncs its database with LocalStorage files on disk. It adds
an origin entry when StorageAreaSync performs a first sync for an origin.

All StorageTracker file operations are performed on one background thread with a task queue.

Tests: storage/domstorage/localstorage/storagetracker/storage-tracker-1-prepare.html
       storage/domstorage/localstorage/storagetracker/storage-tracker-2-create.html
       storage/domstorage/localstorage/storagetracker/storage-tracker-3-delete-all.html
       storage/domstorage/localstorage/storagetracker/storage-tracker-4-create.html
       storage/domstorage/localstorage/storagetracker/storage-tracker-5-delete-one.html

* GNUmakefile.am:
* WebCore.exp.in:
* WebCore.gypi:
* WebCore.pro:
* WebCore.vcproj/WebCore.vcproj:
* WebCore.xcodeproj/project.pbxproj:
* page/PageGroup.cpp:
(WebCore::PageGroup::clearLocalStorageForAllOrigins):
(WebCore::PageGroup::clearLocalStorageForOrigin):
(WebCore::PageGroup::syncLocalStorage):
(WebCore::PageGroup::numberOfPageGroups):
* page/PageGroup.h:
* platform/chromium/FileSystemChromium.cpp:
(WebCore::listDirectory):
* platform/posix/FileSystemPOSIX.cpp:
(WebCore::listDirectory):
* storage/LocalStorageTask.cpp:
(WebCore::LocalStorageTask::LocalStorageTask):
(WebCore::LocalStorageTask::performTask):
* storage/LocalStorageTask.h:
(WebCore::LocalStorageTask::createOriginIdentifiersImport):
(WebCore::LocalStorageTask::createSetOriginDetails):
(WebCore::LocalStorageTask::createDeleteOrigin):
(WebCore::LocalStorageTask::createDeleteAllOrigins):
* storage/StorageAreaImpl.cpp:
(WebCore::StorageAreaImpl::clearForOriginDeletion):
(WebCore::StorageAreaImpl::sync):
* storage/StorageAreaImpl.h:
* storage/StorageAreaSync.cpp:
(WebCore::StorageAreaSync::scheduleCloseDatabase):
(WebCore::StorageAreaSync::openDatabase):
(WebCore::StorageAreaSync::sync):
(WebCore::StorageAreaSync::deleteEmptyDatabase):
(WebCore::StorageAreaSync::scheduleSync):
* storage/StorageAreaSync.h:
* storage/StorageNamespace.h:
* storage/StorageNamespaceImpl.cpp:
(WebCore::StorageNamespaceImpl::clearOriginForDeletion):
(WebCore::StorageNamespaceImpl::clearAllOriginsForDeletion):
(WebCore::StorageNamespaceImpl::sync):
* storage/StorageNamespaceImpl.h:
* storage/StorageTracker.cpp: Added.
(WebCore::StorageTracker::initializeTracker):
(WebCore::StorageTracker::tracker):
(WebCore::StorageTracker::StorageTracker):
(WebCore::StorageTracker::setStorageDirectoryPath):
(WebCore::StorageTracker::trackerDatabasePath):
(WebCore::StorageTracker::openTrackerDatabase):
(WebCore::StorageTracker::importOriginIdentifiers):
(WebCore::StorageTracker::syncImportOriginIdentifiers):
(WebCore::StorageTracker::syncFileSystemAndTrackerDatabase):
(WebCore::StorageTracker::setOriginDetails):
(WebCore::StorageTracker::scheduleTask):
(WebCore::StorageTracker::syncSetOriginDetails):
(WebCore::StorageTracker::origins):
(WebCore::StorageTracker::deleteAllOrigins):
(WebCore::StorageTracker::syncDeleteAllOrigins):
(WebCore::StorageTracker::deleteOrigin):
(WebCore::StorageTracker::syncDeleteOrigin):
(WebCore::StorageTracker::willDeleteAllOrigins):
(WebCore::StorageTracker::willDeleteOrigin):
(WebCore::StorageTracker::canDeleteOrigin):
(WebCore::StorageTracker::cancelDeletingOrigin):
(WebCore::StorageTracker::setClient):
(WebCore::StorageTracker::syncLocalStorage):
* storage/StorageTracker.h: Added.
* storage/StorageTrackerClient.h: Added.
(WebCore::StorageTrackerClient::~StorageTrackerClient):

Source/WebKit:

Patch by Anton D'Auria <adauria@apple.com> on 2011-03-11
Add WebKit1 API to view and delete local storage
https://bugs.webkit.org/show_bug.cgi?id=51878

* WebKit.xcodeproj/project.pbxproj:

Source/WebKit/chromium:

Patch by Anton D'Auria <adauria@apple.com> on 2011-03-11
Add WebKit1 API to view and delete local storage
https://bugs.webkit.org/show_bug.cgi?id=51878

* src/StorageNamespaceProxy.cpp:
(WebCore::StorageNamespaceProxy::clearOriginForDeletion):
(WebCore::StorageNamespaceProxy::clearAllOriginsForDeletion):
(WebCore::StorageNamespaceProxy::sync):
* src/StorageNamespaceProxy.h:

Source/WebKit/mac:

Patch by Anton D'Auria <adauria@apple.com> on 2011-03-11
https://bugs.webkit.org/show_bug.cgi?id=51878
Add WebKit1 API to view and delete local storage

* Storage/WebStorageManager.mm: Added.
(+[WebStorageManager sharedWebStorageManager]):
(-[WebStorageManager origins]):
(-[WebStorageManager deleteAllOrigins]):
(-[WebStorageManager deleteOrigin:]):
(-[WebStorageManager syncLocalStorage]):
(-[WebStorageManager syncFileSystemAndTrackerDatabase]):
(storageDirectoryPath):
(WebKitInitializeStorageIfNecessary):
* Storage/WebStorageManagerInternal.h: Added.
* Storage/WebStorageManagerPrivate.h: Added.
* Storage/WebStorageTrackerClient.h: Added.
* Storage/WebStorageTrackerClient.mm: Added.
(WebStorageTrackerClient::sharedWebStorageTrackerClient):
(WebStorageTrackerClient::WebStorageTrackerClient):
(WebStorageTrackerClient::~WebStorageTrackerClient):
(WebStorageTrackerClient::dispatchDidModifyOriginOnMainThread):
(WebStorageTrackerClient::dispatchDidModifyOrigin):
* WebCoreSupport/WebSecurityOrigin.mm:
(-[WebSecurityOrigin protocol]):
(-[WebSecurityOrigin host]):
(-[WebSecurityOrigin databaseIdentifier]):
(-[WebSecurityOrigin domain]):
(-[WebSecurityOrigin _initWithWebCoreSecurityOrigin:]):
* WebCoreSupport/WebSecurityOriginPrivate.h:
* WebKit.exp:
* WebView/WebView.mm:
(-[WebView _commonInitializationWithFrameName:groupName:usesDocumentViews:]):

Tools:

Patch by Anton D'Auria <adauria@apple.com> on 2011-03-11
https://bugs.webkit.org/show_bug.cgi?id=51878
Add WebKit1 API to view and delete local storage

Added tests that write to LocalStorage, delete one origin, get list of origins with local storage, delete all origins.

* DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj:
* DumpRenderTree/LayoutTestController.cpp:
(syncLocalStorageCallback):
(observeStorageTrackerNotificationsCallback):
(deleteAllLocalStorageCallback):
(deleteLocalStorageForOriginCallback):
(originsWithLocalStorageCallback):
(LayoutTestController::staticFunctions):
* DumpRenderTree/LayoutTestController.h:
* DumpRenderTree/StorageTrackerDelegate.h: Added.
* DumpRenderTree/StorageTrackerDelegate.mm: Added.
(-[StorageTrackerDelegate init]):
(-[StorageTrackerDelegate logNotifications:controller:]):
(-[StorageTrackerDelegate originModified:]):
(-[StorageTrackerDelegate dealloc]):
(-[StorageTrackerDelegate setControllerToNotifyDone:]):
* DumpRenderTree/chromium/LayoutTestController.cpp:
(LayoutTestController::LayoutTestController):
(LayoutTestController::deleteAllLocalStorage):
(LayoutTestController::originsWithLocalStorage):
(LayoutTestController::deleteLocalStorageForOrigin):
(observeStorageTrackerNotifications):
(syncLocalStorage):
* DumpRenderTree/chromium/LayoutTestController.h:
* DumpRenderTree/gtk/LayoutTestControllerGtk.cpp:
(LayoutTestController::originsWithLocalStorage):
(LayoutTestController::deleteAllLocalStorage):
(LayoutTestController::deleteLocalStorageForOrigin):
(LayoutTestController::observeStorageTrackerNotifications):
(LayoutTestController::syncLocalStorage):
* DumpRenderTree/mac/DumpRenderTree.mm:
(resetDefaultsToConsistentValues):
(allocateGlobalControllers):
(releaseGlobalControllers):
* DumpRenderTree/mac/DumpRenderTreeMac.h:
* DumpRenderTree/mac/LayoutTestControllerMac.mm:
(LayoutTestController::syncLocalStorage):
(LayoutTestController::observeStorageTrackerNotifications):
(LayoutTestController::deleteAllLocalStorage):
(LayoutTestController::originsWithLocalStorage):
(LayoutTestController::deleteLocalStorageForOrigin):
* DumpRenderTree/qt/LayoutTestControllerQt.cpp:
(LayoutTestController::originsWithLocalStorage):
(LayoutTestController::deleteAllLocalStorage):
(LayoutTestController::deleteLocalStorageForOrigin):
(LayoutTestController::observeStorageTrackerNotifications):
(LayoutTestController::syncLocalStorage):
* DumpRenderTree/qt/LayoutTestControllerQt.h:
* DumpRenderTree/win/LayoutTestControllerWin.cpp:
(LayoutTestController::clearAllApplicationCaches):
(LayoutTestController::syncLocalStorage):
(LayoutTestController::observeStorageTrackerNotifications):
(LayoutTestController::clearAllDatabases):
(LayoutTestController::deleteAllLocalStorage):
(LayoutTestController::originsWithLocalStorage):
(LayoutTestController::deleteLocalStorageForOrigin):
* DumpRenderTree/wx/LayoutTestControllerWx.cpp:
(LayoutTestController::syncLocalStorage):
(LayoutTestController::observeStorageTrackerNotifications):
(LayoutTestController::clearAllDatabases):
(LayoutTestController::deleteAllLocalStorage):
(LayoutTestController::originsWithLocalStorage):
(LayoutTestController::deleteLocalStorageForOrigin):

LayoutTests:

Patch by Anton D'Auria <adauria@apple.com> on 2011-03-11
Add WebKit1 API to view and delete local storage
https://bugs.webkit.org/show_bug.cgi?id=51878

* platform/chromium/test_expectations.txt:
* storage/domstorage/localstorage/storagetracker: Added.
* storage/domstorage/localstorage/storagetracker/storage-tracker-1-prepare-expected.txt: Added.
* storage/domstorage/localstorage/storagetracker/storage-tracker-1-prepare.html: Added.
* storage/domstorage/localstorage/storagetracker/storage-tracker-2-create-expected.txt: Added.
* storage/domstorage/localstorage/storagetracker/storage-tracker-2-create.html: Added.
* storage/domstorage/localstorage/storagetracker/storage-tracker-3-delete-all-expected.txt: Added.
* storage/domstorage/localstorage/storagetracker/storage-tracker-3-delete-all.html: Added.
* storage/domstorage/localstorage/storagetracker/storage-tracker-4-create-expected.txt: Added.
* storage/domstorage/localstorage/storagetracker/storage-tracker-4-create.html: Added.
* storage/domstorage/localstorage/storagetracker/storage-tracker-5-delete-one-expected.txt: Added.
* storage/domstorage/localstorage/storagetracker/storage-tracker-5-delete-one.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@80892 268f45cc-cd09-0410-ab3c-d52691b4dbfc

66 files changed:
LayoutTests/ChangeLog
LayoutTests/platform/chromium/test_expectations.txt
LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-1-prepare-expected.txt [new file with mode: 0644]
LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-1-prepare.html [new file with mode: 0644]
LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-2-create-expected.txt [new file with mode: 0644]
LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-2-create.html [new file with mode: 0644]
LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-3-delete-all-expected.txt [new file with mode: 0644]
LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-3-delete-all.html [new file with mode: 0644]
LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-4-create-expected.txt [new file with mode: 0644]
LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-4-create.html [new file with mode: 0644]
LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-5-delete-one-expected.txt [new file with mode: 0644]
LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-5-delete-one.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/GNUmakefile.am
Source/WebCore/WebCore.exp.in
Source/WebCore/WebCore.gypi
Source/WebCore/WebCore.pro
Source/WebCore/WebCore.vcproj/WebCore.vcproj
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/page/PageGroup.cpp
Source/WebCore/page/PageGroup.h
Source/WebCore/platform/chromium/FileSystemChromium.cpp
Source/WebCore/platform/posix/FileSystemPOSIX.cpp
Source/WebCore/storage/LocalStorageTask.cpp
Source/WebCore/storage/LocalStorageTask.h
Source/WebCore/storage/StorageAreaImpl.cpp
Source/WebCore/storage/StorageAreaImpl.h
Source/WebCore/storage/StorageAreaSync.cpp
Source/WebCore/storage/StorageAreaSync.h
Source/WebCore/storage/StorageNamespace.h
Source/WebCore/storage/StorageNamespaceImpl.cpp
Source/WebCore/storage/StorageNamespaceImpl.h
Source/WebCore/storage/StorageTracker.cpp [new file with mode: 0644]
Source/WebCore/storage/StorageTracker.h [new file with mode: 0644]
Source/WebCore/storage/StorageTrackerClient.h [new file with mode: 0644]
Source/WebKit/ChangeLog
Source/WebKit/WebKit.xcodeproj/project.pbxproj
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/src/StorageNamespaceProxy.cpp
Source/WebKit/chromium/src/StorageNamespaceProxy.h
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/Storage/WebStorageManager.mm [new file with mode: 0644]
Source/WebKit/mac/Storage/WebStorageManagerInternal.h [new file with mode: 0644]
Source/WebKit/mac/Storage/WebStorageManagerPrivate.h [new file with mode: 0644]
Source/WebKit/mac/Storage/WebStorageTrackerClient.h [new file with mode: 0644]
Source/WebKit/mac/Storage/WebStorageTrackerClient.mm [new file with mode: 0644]
Source/WebKit/mac/WebCoreSupport/WebSecurityOrigin.mm
Source/WebKit/mac/WebCoreSupport/WebSecurityOriginPrivate.h
Source/WebKit/mac/WebKit.exp
Source/WebKit/mac/WebView/WebView.mm
Tools/ChangeLog
Tools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj
Tools/DumpRenderTree/LayoutTestController.cpp
Tools/DumpRenderTree/LayoutTestController.h
Tools/DumpRenderTree/StorageTrackerDelegate.h [new file with mode: 0644]
Tools/DumpRenderTree/StorageTrackerDelegate.mm [new file with mode: 0644]
Tools/DumpRenderTree/chromium/LayoutTestController.cpp
Tools/DumpRenderTree/chromium/LayoutTestController.h
Tools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp
Tools/DumpRenderTree/mac/DumpRenderTree.mm
Tools/DumpRenderTree/mac/DumpRenderTreeMac.h
Tools/DumpRenderTree/mac/LayoutTestControllerMac.mm
Tools/DumpRenderTree/qt/LayoutTestControllerQt.cpp
Tools/DumpRenderTree/qt/LayoutTestControllerQt.h
Tools/DumpRenderTree/win/LayoutTestControllerWin.cpp
Tools/DumpRenderTree/wx/LayoutTestControllerWx.cpp

index 78a51d4cabad0d49c74ec8472335bf8af05c9363..e158534b638317cd931e39a63e7162481a303110 100644 (file)
@@ -1,3 +1,23 @@
+2011-03-11  Anton D'Auria  <adauria@apple.com>
+
+        Reviewed and landed by Brady Eidson.
+
+        Add WebKit1 API to view and delete local storage
+        https://bugs.webkit.org/show_bug.cgi?id=51878
+
+        * platform/chromium/test_expectations.txt:
+        * storage/domstorage/localstorage/storagetracker: Added.
+        * storage/domstorage/localstorage/storagetracker/storage-tracker-1-prepare-expected.txt: Added.
+        * storage/domstorage/localstorage/storagetracker/storage-tracker-1-prepare.html: Added.
+        * storage/domstorage/localstorage/storagetracker/storage-tracker-2-create-expected.txt: Added.
+        * storage/domstorage/localstorage/storagetracker/storage-tracker-2-create.html: Added.
+        * storage/domstorage/localstorage/storagetracker/storage-tracker-3-delete-all-expected.txt: Added.
+        * storage/domstorage/localstorage/storagetracker/storage-tracker-3-delete-all.html: Added.
+        * storage/domstorage/localstorage/storagetracker/storage-tracker-4-create-expected.txt: Added.
+        * storage/domstorage/localstorage/storagetracker/storage-tracker-4-create.html: Added.
+        * storage/domstorage/localstorage/storagetracker/storage-tracker-5-delete-one-expected.txt: Added.
+        * storage/domstorage/localstorage/storagetracker/storage-tracker-5-delete-one.html: Added.
+
 2011-03-11  Jessie Berlin  <jberlin@apple.com>
 
         http/tests/websocket/tests/url-with-credential.html sometimes crashes beneath SocketStreamHandle::readStreamCallback on Windows
index 11a70b04d9a17ad416d3c6102cc948af3b07154b..abaeac39ffc24f8e71f7105879790c6b9ca44e86 100755 (executable)
@@ -151,6 +151,10 @@ WONTFIX SKIP : fast/wml = FAIL
 // most likely these tests will always be JSC specific.
 WONTFIX SKIP : fast/profiler = FAIL TIMEOUT
 
+// StorageTracker isn't used by Chromium and not all requisite platform code
+// is implemented.
+WONTFIX SKIP : storage/domstorage/localstorage/storagetracker = PASS TIMEOUT FAIL
+
 // We use worker_uitests to run workers tests. Don't run them in test_shell.
 WONTFIX SKIP : fast/workers = PASS TIMEOUT FAIL
 WONTFIX SKIP : fast/files/workers = PASS TIMEOUT FAIL
diff --git a/LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-1-prepare-expected.txt b/LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-1-prepare-expected.txt
new file mode 100644 (file)
index 0000000..5cca432
--- /dev/null
@@ -0,0 +1,10 @@
+Prepare for StorageTracker tests by ensuring that every origin with local storage is deleted.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+This test should have no visible output on success.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-1-prepare.html b/LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-1-prepare.html
new file mode 100644 (file)
index 0000000..a0a09ff
--- /dev/null
@@ -0,0 +1,44 @@
+<html>
+<head>
+<link rel="stylesheet" href="../../../../fast/js/resources/js-test-style.css">
+<script src="../../../../fast/js/resources/js-test-pre.js"></script>
+<script src="../../../../fast/js/resources/js-test-post-function.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+description("Prepare for StorageTracker tests by ensuring that every origin with local storage is deleted.");
+
+if (window.layoutTestController)
+    layoutTestController.waitUntilDone();
+    
+function finishTest() {
+    if (window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+
+function test()
+{
+    if (!window.localStorage) {
+        testFailed("localStorage DOES NOT exist");
+        return;
+    }
+    
+    debug("This test should have no visible output on success.");
+
+    if (layoutTestController.originsWithLocalStorage().length > 0) {
+        layoutTestController.observeStorageTrackerNotifications(1);
+        layoutTestController.deleteAllLocalStorage();
+    } else {
+        finishTest();
+    }
+}
+
+test();        
+
+window.successfullyParsed = true;
+isSuccessfullyParsed();
+</script>
+</body>
+</html>
diff --git a/LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-2-create-expected.txt b/LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-2-create-expected.txt
new file mode 100644 (file)
index 0000000..5ae4ee1
--- /dev/null
@@ -0,0 +1,10 @@
+Origin identifier: 'file__0'
+StorageTracker test - write local storage for this origin. Should be called after origins-prepare.html.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-2-create.html b/LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-2-create.html
new file mode 100644 (file)
index 0000000..20f4f3d
--- /dev/null
@@ -0,0 +1,47 @@
+<html>
+<head>
+<link rel="stylesheet" href="../../../../fast/js/resources/js-test-style.css">
+<script src="../../../../fast/js/resources/js-test-pre.js"></script>
+<script src="../../../../fast/js/resources/js-test-post-function.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+description("StorageTracker test - write local storage for this origin. Should be called after origins-prepare.html.");
+
+if (window.layoutTestController)
+    layoutTestController.waitUntilDone();
+    
+function finishTest() {
+    if (window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+
+function test()
+{
+    if (!window.localStorage) {
+        testFailed("localStorage DOES NOT exist");
+        return;
+    }
+    
+    if (layoutTestController.originsWithLocalStorage().length > 0) {
+        // An origin already exists so we can exit.
+        testFailed("An origin already existed with local storage.");
+        layoutTestController.notifyDone();
+    } else {
+        layoutTestController.syncLocalStorage();
+        
+        localStorage.someData = 'writeme';
+        // LayoutTestController's notifyDone will be called after the origin change notification comes in.
+        layoutTestController.observeStorageTrackerNotifications(1);
+    }
+}
+
+test();        
+
+window.successfullyParsed = true;
+isSuccessfullyParsed();
+</script>
+</body>
+</html>
diff --git a/LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-3-delete-all-expected.txt b/LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-3-delete-all-expected.txt
new file mode 100644 (file)
index 0000000..da480d9
--- /dev/null
@@ -0,0 +1,10 @@
+Test API to view origins that have local storage and to delete local storage by origin.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS layoutTestController.originsWithLocalStorage().toString() is "file__0"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-3-delete-all.html b/LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-3-delete-all.html
new file mode 100644 (file)
index 0000000..16da440
--- /dev/null
@@ -0,0 +1,47 @@
+<html>
+<head>
+<link rel="stylesheet" href="../../../../fast/js/resources/js-test-style.css">
+<script src="../../../../fast/js/resources/js-test-pre.js"></script>
+<script src="../../../../fast/js/resources/js-test-post-function.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+description("Test API to view origins that have local storage and to delete local storage by origin.");
+
+if (window.layoutTestController)
+    layoutTestController.waitUntilDone();
+    
+function finishTest() {
+    if (window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+
+function test()
+{
+    if (!window.localStorage) {
+        testFailed("localStorage DOES NOT exist");
+        return;
+    }
+
+    if (layoutTestController.originsWithLocalStorage().length > 0) {
+        shouldBeEqualToString("layoutTestController.originsWithLocalStorage().toString()", "file__0");
+        // We're just going to delete the existing origin, so we'll get one origin change notification.
+        layoutTestController.observeStorageTrackerNotifications(1);
+        layoutTestController.deleteAllLocalStorage();
+    } else {
+        layoutTestController.notifyDone();
+        testFailed("Ran with no origins with local storage");
+    }
+
+    // At this point, we're guaranteed to have one origin with local storage.
+}
+
+test();        
+
+window.successfullyParsed = true;
+isSuccessfullyParsed();
+</script>
+</body>
+</html>
diff --git a/LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-4-create-expected.txt b/LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-4-create-expected.txt
new file mode 100644 (file)
index 0000000..ab6ea2b
--- /dev/null
@@ -0,0 +1,11 @@
+Origin identifier: 'file__0'
+StorageTracker test - write local storage for this origin. Should be called after storage-tracker-3-delete-all.html.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+This test should have no visible output on success.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-4-create.html b/LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-4-create.html
new file mode 100644 (file)
index 0000000..c066fb4
--- /dev/null
@@ -0,0 +1,47 @@
+<html>
+<head>
+<link rel="stylesheet" href="../../../../fast/js/resources/js-test-style.css">
+<script src="../../../../fast/js/resources/js-test-pre.js"></script>
+<script src="../../../../fast/js/resources/js-test-post-function.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+description("StorageTracker test - write local storage for this origin. Should be called after storage-tracker-3-delete-all.html.");
+
+if (window.layoutTestController)
+    layoutTestController.waitUntilDone();
+    
+function finishTest() {
+    if (window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+
+function test()
+{
+    if (!window.localStorage) {
+        testFailed("localStorage DOES NOT exist");
+        return;
+    }
+    
+    debug("This test should have no visible output on success.");
+
+    if (layoutTestController.originsWithLocalStorage().length > 0) {
+        // An origin already exists so we can exit.
+        testFailed("An origin already existed with local storage.");
+        layoutTestController.notifyDone();
+    } else {
+        layoutTestController.syncLocalStorage();
+        localStorage.someOtherData = 'writemeMore';
+        layoutTestController.observeStorageTrackerNotifications(1);
+    }
+}
+
+test();        
+
+window.successfullyParsed = true;
+isSuccessfullyParsed();
+</script>
+</body>
+</html>
diff --git a/LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-5-delete-one-expected.txt b/LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-5-delete-one-expected.txt
new file mode 100644 (file)
index 0000000..da480d9
--- /dev/null
@@ -0,0 +1,10 @@
+Test API to view origins that have local storage and to delete local storage by origin.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS layoutTestController.originsWithLocalStorage().toString() is "file__0"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-5-delete-one.html b/LayoutTests/storage/domstorage/localstorage/storagetracker/storage-tracker-5-delete-one.html
new file mode 100644 (file)
index 0000000..3a61a73
--- /dev/null
@@ -0,0 +1,47 @@
+<html>
+<head>
+<link rel="stylesheet" href="../../../../fast/js/resources/js-test-style.css">
+<script src="../../../../fast/js/resources/js-test-pre.js"></script>
+<script src="../../../../fast/js/resources/js-test-post-function.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+description("Test API to view origins that have local storage and to delete local storage by origin.");
+
+if (window.layoutTestController)
+    layoutTestController.waitUntilDone();
+    
+function finishTest() {
+    if (window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+
+function test()
+{
+    if (!window.localStorage) {
+        testFailed("localStorage DOES NOT exist");
+        return;
+    }
+
+    if (layoutTestController.originsWithLocalStorage().length > 0) {
+        shouldBeEqualToString("layoutTestController.originsWithLocalStorage().toString()", "file__0");
+        // We're just going to delete the existing origin, so we'll get one origin change notification.
+        layoutTestController.observeStorageTrackerNotifications(1);
+        // At this point, we're guaranteed to have one origin with local storage.
+        layoutTestController.deleteLocalStorageForOrigin("file://");
+    } else {
+        testFailed("Ran with no origins with local storage.");
+        layoutTestController.notifyDone();
+    }
+
+}
+
+test();        
+
+window.successfullyParsed = true;
+isSuccessfullyParsed();
+</script>
+</body>
+</html>
index 5118e8edec2321aef7282e4ab7b220f5e137a429..89288ecd4903dcae62859869cb3c0176921d96bf 100644 (file)
@@ -1,3 +1,94 @@
+2011-03-11  Anton D'Auria  <adauria@apple.com>
+
+        Reviewed and landed by Brady Eidson.
+
+        Add WebKit1 API to view and delete local storage
+        https://bugs.webkit.org/show_bug.cgi?id=51878
+
+        Created StorageTracker as a central point for tracking and deleting LocalStorage per origin.
+        StorageTracker maintains its own database of origin identifiers and backing db paths,
+        and this allows it to contain more relational data in the future, like variable quotas per origin.
+
+        On initialization, StorageTracker syncs its database with LocalStorage files on disk. It adds
+        an origin entry when StorageAreaSync performs a first sync for an origin.
+
+        All StorageTracker file operations are performed on one background thread with a task queue.
+
+        Tests: storage/domstorage/localstorage/storagetracker/storage-tracker-1-prepare.html
+               storage/domstorage/localstorage/storagetracker/storage-tracker-2-create.html
+               storage/domstorage/localstorage/storagetracker/storage-tracker-3-delete-all.html
+               storage/domstorage/localstorage/storagetracker/storage-tracker-4-create.html
+               storage/domstorage/localstorage/storagetracker/storage-tracker-5-delete-one.html
+
+        * GNUmakefile.am:
+        * WebCore.exp.in:
+        * WebCore.gypi:
+        * WebCore.pro:
+        * WebCore.vcproj/WebCore.vcproj:
+        * WebCore.xcodeproj/project.pbxproj:
+        * page/PageGroup.cpp:
+        (WebCore::PageGroup::clearLocalStorageForAllOrigins):
+        (WebCore::PageGroup::clearLocalStorageForOrigin):
+        (WebCore::PageGroup::syncLocalStorage):
+        (WebCore::PageGroup::numberOfPageGroups):
+        * page/PageGroup.h:
+        * platform/chromium/FileSystemChromium.cpp:
+        (WebCore::listDirectory):
+        * platform/posix/FileSystemPOSIX.cpp:
+        (WebCore::listDirectory):
+        * storage/LocalStorageTask.cpp:
+        (WebCore::LocalStorageTask::LocalStorageTask):
+        (WebCore::LocalStorageTask::performTask):
+        * storage/LocalStorageTask.h:
+        (WebCore::LocalStorageTask::createOriginIdentifiersImport):
+        (WebCore::LocalStorageTask::createSetOriginDetails):
+        (WebCore::LocalStorageTask::createDeleteOrigin):
+        (WebCore::LocalStorageTask::createDeleteAllOrigins):
+        * storage/StorageAreaImpl.cpp:
+        (WebCore::StorageAreaImpl::clearForOriginDeletion):
+        (WebCore::StorageAreaImpl::sync):
+        * storage/StorageAreaImpl.h:
+        * storage/StorageAreaSync.cpp:
+        (WebCore::StorageAreaSync::scheduleCloseDatabase):
+        (WebCore::StorageAreaSync::openDatabase):
+        (WebCore::StorageAreaSync::sync):
+        (WebCore::StorageAreaSync::deleteEmptyDatabase):
+        (WebCore::StorageAreaSync::scheduleSync):
+        * storage/StorageAreaSync.h:
+        * storage/StorageNamespace.h:
+        * storage/StorageNamespaceImpl.cpp:
+        (WebCore::StorageNamespaceImpl::clearOriginForDeletion):
+        (WebCore::StorageNamespaceImpl::clearAllOriginsForDeletion):
+        (WebCore::StorageNamespaceImpl::sync):
+        * storage/StorageNamespaceImpl.h:
+        * storage/StorageTracker.cpp: Added.
+        (WebCore::StorageTracker::initializeTracker):
+        (WebCore::StorageTracker::tracker):
+        (WebCore::StorageTracker::StorageTracker):
+        (WebCore::StorageTracker::setStorageDirectoryPath):
+        (WebCore::StorageTracker::trackerDatabasePath):
+        (WebCore::StorageTracker::openTrackerDatabase):
+        (WebCore::StorageTracker::importOriginIdentifiers):
+        (WebCore::StorageTracker::syncImportOriginIdentifiers):
+        (WebCore::StorageTracker::syncFileSystemAndTrackerDatabase):
+        (WebCore::StorageTracker::setOriginDetails):
+        (WebCore::StorageTracker::scheduleTask):
+        (WebCore::StorageTracker::syncSetOriginDetails):
+        (WebCore::StorageTracker::origins):
+        (WebCore::StorageTracker::deleteAllOrigins):
+        (WebCore::StorageTracker::syncDeleteAllOrigins):
+        (WebCore::StorageTracker::deleteOrigin):
+        (WebCore::StorageTracker::syncDeleteOrigin):
+        (WebCore::StorageTracker::willDeleteAllOrigins):
+        (WebCore::StorageTracker::willDeleteOrigin):
+        (WebCore::StorageTracker::canDeleteOrigin):
+        (WebCore::StorageTracker::cancelDeletingOrigin):
+        (WebCore::StorageTracker::setClient):
+        (WebCore::StorageTracker::syncLocalStorage):
+        * storage/StorageTracker.h: Added.
+        * storage/StorageTrackerClient.h: Added.
+        (WebCore::StorageTrackerClient::~StorageTrackerClient):
+
 2011-03-11  Steve Block  <steveblock@google.com>
 
         Reviewed by Jeremy Orlow.
index 696bf4b30fe26d26c8a2728b9dd94fbe518b8109..1608e449bfae18de65af19c139f45334972e279f 100644 (file)
@@ -3218,6 +3218,9 @@ webcore_sources += \
        Source/WebCore/storage/StorageNamespaceImpl.h \
        Source/WebCore/storage/StorageSyncManager.cpp \
        Source/WebCore/storage/StorageSyncManager.h \
+       Source/WebCore/storage/StorageTracker.cpp \
+       Source/WebCore/storage/StorageTracker.h \
+       Source/WebCore/storage/StorageTrackerClient.h \
        Source/WebCore/svg/animation/SMILTimeContainer.cpp \
        Source/WebCore/svg/animation/SMILTimeContainer.h \
        Source/WebCore/svg/animation/SMILTime.cpp \
index 42b140101f7220431e022425d3c3e345dbe3035f..3df8ff3e4f017e9e49db1093dbad167475777622 100644 (file)
@@ -969,6 +969,7 @@ __ZN7WebCore9PageGroup26setShouldTrackVisitedLinksEb
 __ZN7WebCore9PageGroup29removeUserStyleSheetFromWorldEPNS_15DOMWrapperWorldERKNS_4KURLE
 __ZN7WebCore9PageGroup30removeUserStyleSheetsFromWorldEPNS_15DOMWrapperWorldE
 __ZN7WebCore9PageGroup9pageGroupERKN3WTF6StringE
+__ZN7WebCore9PageGroup18numberOfPageGroupsEv
 __ZN7WebCore9Scrollbar22maxOverlapBetweenPagesEv
 __ZN7WebCore9TimerBase4stopEv
 __ZN7WebCore9TimerBase5startEdd
@@ -1092,6 +1093,16 @@ __ZNK7WebCore14ResourceLoader11frameLoaderEv
 __ZNK7WebCore14SecurityOrigin10canDisplayERKNS_4KURLE
 __ZNK7WebCore14SecurityOrigin18databaseIdentifierEv
 __ZNK7WebCore14SecurityOrigin5equalEPKS0_
+#if ENABLE(DOM_STORAGE)
+__ZN7WebCore14StorageTracker17initializeTrackerERKN3WTF6StringE
+__ZN7WebCore14StorageTracker16deleteAllOriginsEv
+__ZN7WebCore14StorageTracker12deleteOriginEPNS_14SecurityOriginE
+__ZN7WebCore14StorageTracker7trackerEv
+__ZN7WebCore14StorageTracker7originsERN3WTF6VectorINS1_6RefPtrINS_14SecurityOriginEEELm0EEE
+__ZN7WebCore14StorageTracker9setClientEPNS_20StorageTrackerClientE
+__ZN7WebCore14StorageTracker16syncLocalStorageEv
+__ZN7WebCore14StorageTracker32syncFileSystemAndTrackerDatabaseEv
+#endif
 __ZNK7WebCore15FocusController18focusedOrMainFrameEv
 __ZNK7WebCore15GraphicsContext15platformContextEv
 __ZNK7WebCore15GraphicsContext16paintingDisabledEv
index 2b8d58743148d2dfcef51b1339f0eb49655b2c3a..8b166500b524684f0c07b3d839119d4a5d42b136 100644 (file)
             'storage/StorageNamespaceImpl.h',
             'storage/StorageSyncManager.cpp',
             'storage/StorageSyncManager.h',
+            'storage/StorageTracker.cpp',
+            'storage/StorageTracker.h',
             'storage/chromium/DatabaseObserver.h',
             'storage/chromium/DatabaseTrackerChromium.cpp',
             'storage/chromium/IDBFactoryBackendInterface.cpp',
index 6055251a0380ba73dfadec5aa8e5c5473fec5a11..ded5f304b1e451264f166e7c616e103ad5947f17 100644 (file)
@@ -2748,7 +2748,9 @@ contains(DEFINES, ENABLE_DOM_STORAGE=1) {
         storage/StorageMap.h \
         storage/StorageNamespace.h \
         storage/StorageNamespaceImpl.h \
-        storage/StorageSyncManager.h
+        storage/StorageSyncManager.h \
+        storage/StorageTracker.h \
+        storage/StorageTrackerClient.h
 
     !v8 {
         SOURCES += \
@@ -2765,7 +2767,8 @@ contains(DEFINES, ENABLE_DOM_STORAGE=1) {
         storage/StorageMap.cpp \
         storage/StorageNamespace.cpp \
         storage/StorageNamespaceImpl.cpp \
-        storage/StorageSyncManager.cpp
+        storage/StorageSyncManager.cpp \
+        storage/StorageTracker.cpp
 }
 
 contains(DEFINES, ENABLE_FILE_SYSTEM=1) {
index ec1d6360cf152d0e1afc167f2a5c9b10ea5c4167..4830b3612507ffd29188ecf7aeda9e7df29a84fd 100755 (executable)
                                >
                        </File>
                        <File
-                               RelativePath="..\storage\VersionChangeCallback.h"
+                               RelativePath="..\storage\StorageTracker.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\storage\StorageTracker.h"
                                >
                        </File>
+                       <File
+                               RelativePath="..\storage\VersionChangeCallback.h"
+                           >
+                       </File>
+
                </Filter>
                <Filter
                        Name="strings"
index 57bed2b3eae63feb16b258679656d30b0179e66d..4acf08a41b0a49d04270eedbb820b61ee4f265ea 100644 (file)
                37F818FD0D657606005E1F05 /* WebCoreURLResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 37F818FB0D657606005E1F05 /* WebCoreURLResponse.h */; settings = {ATTRIBUTES = (Private, ); }; };
                37F818FE0D657606005E1F05 /* WebCoreURLResponse.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37F818FC0D657606005E1F05 /* WebCoreURLResponse.mm */; };
                37FD4298118368460093C029 /* TreeDepthLimit.h in Headers */ = {isa = PBXBuildFile; fileRef = 37FD4297118368460093C029 /* TreeDepthLimit.h */; };
+               3AB02D2A12D4F91600FBB694 /* StorageTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 3AB02D2812D4F91600FBB694 /* StorageTracker.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               3AB02D2B12D4F91600FBB694 /* StorageTracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3AB02D2912D4F91600FBB694 /* StorageTracker.cpp */; };
+               3AC3680012EF7A09006A3D6F /* StorageTrackerClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 3AC367FE12EF7A09006A3D6F /* StorageTrackerClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
                3AC648B2129E146500C3EB25 /* EditingBoundary.h in Headers */ = {isa = PBXBuildFile; fileRef = 3AC648B1129E146500C3EB25 /* EditingBoundary.h */; settings = {ATTRIBUTES = (Private, ); }; };
                41002CCD0F66EDEF009E660D /* ScriptFunctionCall.h in Headers */ = {isa = PBXBuildFile; fileRef = 41002CCB0F66EDEF009E660D /* ScriptFunctionCall.h */; };
                41002CCE0F66EDEF009E660D /* ScriptFunctionCall.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41002CCC0F66EDEF009E660D /* ScriptFunctionCall.cpp */; };
                37F818FC0D657606005E1F05 /* WebCoreURLResponse.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebCoreURLResponse.mm; sourceTree = "<group>"; };
                37FC96DA1104ED71003E1FAD /* TrailingFloatsRootInlineBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrailingFloatsRootInlineBox.h; sourceTree = "<group>"; };
                37FD4297118368460093C029 /* TreeDepthLimit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TreeDepthLimit.h; sourceTree = "<group>"; };
+               3AB02D2812D4F91600FBB694 /* StorageTracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StorageTracker.h; sourceTree = "<group>"; };
+               3AB02D2912D4F91600FBB694 /* StorageTracker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StorageTracker.cpp; sourceTree = "<group>"; };
+               3AC367FE12EF7A09006A3D6F /* StorageTrackerClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StorageTrackerClient.h; sourceTree = "<group>"; };
                3AC648B1129E146500C3EB25 /* EditingBoundary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EditingBoundary.h; sourceTree = "<group>"; };
                41002CCB0F66EDEF009E660D /* ScriptFunctionCall.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptFunctionCall.h; sourceTree = "<group>"; };
                41002CCC0F66EDEF009E660D /* ScriptFunctionCall.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptFunctionCall.cpp; sourceTree = "<group>"; };
                                C55E38BB10040D5D00A56BDB /* StorageNamespaceImpl.h */,
                                C5102D930FD9AA2D00FAFF04 /* StorageSyncManager.cpp */,
                                C5102D920FD9AA2D00FAFF04 /* StorageSyncManager.h */,
+                               3AB02D2812D4F91600FBB694 /* StorageTracker.h */,
+                               3AB02D2912D4F91600FBB694 /* StorageTracker.cpp */,
+                               3AC367FE12EF7A09006A3D6F /* StorageTrackerClient.h */,
                        );
                        indentWidth = 4;
                        path = storage;
                                C50D0E830FF4272900AC2644 /* StorageNamespace.h in Headers */,
                                C55E38BF10040D5D00A56BDB /* StorageNamespaceImpl.h in Headers */,
                                C5102D940FD9AA2D00FAFF04 /* StorageSyncManager.h in Headers */,
+                               3AB02D2A12D4F91600FBB694 /* StorageTracker.h in Headers */,
                                65488D6B0DD5A83D009D83B2 /* StringSourceProvider.h in Headers */,
                                B23540F30D00782E002382FA /* StringTruncator.h in Headers */,
                                849F77760EFEC6200090849D /* StrokeStyleApplier.h in Headers */,
                                E1F1E8300C3C2BB9006DB391 /* XSLTExtensions.h in Headers */,
                                93F199ED08245E59001E9ABC /* XSLTProcessor.h in Headers */,
                                E1BE512E0CF6C512002EA959 /* XSLTUnicodeSort.h in Headers */,
+                               3AC3680012EF7A09006A3D6F /* StorageTrackerClient.h in Headers */,
                                977E2E0F12F0FC9C00C13379 /* XSSFilter.h in Headers */,
                                E49BD9FA131FD2ED003C56F0 /* CSSPrimitiveValueCache.h in Headers */,
                                5A574F25131DB93900471B88 /* RenderQuote.h in Headers */,
                                C50D0E820FF4272900AC2644 /* StorageNamespace.cpp in Sources */,
                                C55E38C010040D5D00A56BDB /* StorageNamespaceImpl.cpp in Sources */,
                                C5102D950FD9AA2D00FAFF04 /* StorageSyncManager.cpp in Sources */,
+                               3AB02D2B12D4F91600FBB694 /* StorageTracker.cpp in Sources */,
                                B2C3DA300D006C1D00EF6F26 /* String.cpp in Sources */,
                                B2B2645C0D00A77E000ACC1D /* StringCF.cpp in Sources */,
                                B2B2645D0D00A77E000ACC1D /* StringImplCF.cpp in Sources */,
index b9b0e3492c537cf4add23e94271b5e52dd9f1e08..32681f87ee282576403f4ec8864d73ecf78b138e 100644 (file)
@@ -33,6 +33,7 @@
 #include "GroupSettings.h"
 #include "IDBFactoryBackendInterface.h"
 #include "Page.h"
+#include "SecurityOrigin.h"
 #include "Settings.h"
 #include "StorageNamespace.h"
 
@@ -110,6 +111,54 @@ void PageGroup::closeLocalStorage()
 #endif
 }
 
+#if ENABLE(DOM_STORAGE)
+
+void PageGroup::clearLocalStorageForAllOrigins()
+{
+    if (!pageGroups)
+        return;
+
+    PageGroupMap::iterator end = pageGroups->end();
+    for (PageGroupMap::iterator it = pageGroups->begin(); it != end; ++it) {
+        if (it->second->hasLocalStorage())
+            it->second->localStorage()->clearAllOriginsForDeletion();
+    }
+}
+
+void PageGroup::clearLocalStorageForOrigin(SecurityOrigin* origin)
+{
+    if (!pageGroups)
+        return;
+
+    PageGroupMap::iterator end = pageGroups->end();
+    for (PageGroupMap::iterator it = pageGroups->begin(); it != end; ++it) {
+        if (it->second->hasLocalStorage())
+            it->second->localStorage()->clearOriginForDeletion(origin);
+    }    
+}
+    
+void PageGroup::syncLocalStorage()
+{
+    if (!pageGroups)
+        return;
+
+    PageGroupMap::iterator end = pageGroups->end();
+    for (PageGroupMap::iterator it = pageGroups->begin(); it != end; ++it) {
+        if (it->second->hasLocalStorage())
+            it->second->localStorage()->sync();
+    }
+}
+
+unsigned PageGroup::numberOfPageGroups()
+{
+    if (!pageGroups)
+        return 0;
+
+    return pageGroups->size();
+}
+
+#endif
+
 void PageGroup::addPage(Page* page)
 {
     ASSERT(page);
@@ -209,6 +258,7 @@ StorageNamespace* PageGroup::localStorage()
 
     return m_localStorage.get();
 }
+
 #endif
 
 #if ENABLE(INDEXED_DATABASE)
index 643c5e632d2d69cc7d9d54fec43bd0c90869b66a..3eac8a459743d0927e94e23a5085cb82471c083f 100644 (file)
@@ -39,6 +39,7 @@ namespace WebCore {
     class GroupSettings;
     class IDBFactoryBackendInterface;
     class Page;
+    class SecurityOrigin;
     class StorageNamespace;
 
     class PageGroup {
@@ -49,7 +50,15 @@ namespace WebCore {
         ~PageGroup();
 
         static PageGroup* pageGroup(const String& groupName);
+
+#if ENABLE(DOM_STORAGE)
         static void closeLocalStorage();
+        static void clearLocalStorageForAllOrigins();
+        static void clearLocalStorageForOrigin(SecurityOrigin*);
+        // DumpRenderTree helper that triggers a StorageArea sync.
+        static void syncLocalStorage();
+#endif
+        static unsigned numberOfPageGroups();
         
         const HashSet<Page*>& pages() const { return m_pages; }
 
index faf5e92a7fd1f4defb2883612fef4caf00808ba9..5e03c5be577de6ce6ffd4ab77ed2a99d50843654 100644 (file)
@@ -112,4 +112,11 @@ int writeToFile(PlatformFileHandle handle, const char* data, int length)
     return PlatformBridge::writeToFile(handle, data, length);
 }
 
+Vector<String> listDirectory(const String& path, const String& filter)
+{
+    notImplemented();
+
+    return Vector<String>();
+}
+
 } // namespace WebCore
index b0cc7c5a812c72156a10a0e38af5587ef92f6072..90ff4d7ee9837bc40529879955d3ea35ee863861 100644 (file)
 #include "FileSystem.h"
 
 #include "PlatformString.h"
+#include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <fnmatch.h>
 #include <libgen.h>
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -227,10 +229,28 @@ String directoryName(const String& path)
     return dirname(fsRep.mutableData());
 }
 
-// OK to not implement listDirectory at the moment, because it's only used for plug-ins, and
-// all platforms that use the shared plug-in implementation have implementations. We'd need
-// to implement it if we wanted to use PluginDatabase.cpp on the Mac. Better to not implement
-// at all and get a link error in case this arises, rather than having a stub here, because
-// with a stub you learn about the problem at runtime instead of link time.
+Vector<String> listDirectory(const String& path, const String& filter)
+{
+    Vector<String> entries;
+    CString cpath = path.utf8();
+    CString cfilter = filter.utf8();
+    DIR* dir = opendir(cpath.data());
+    if (dir) {
+        struct dirent* dp;
+        while ((dp = readdir(dir))) {
+            const char* name = dp->d_name;
+            if (!strcmp(name, ".") || !strcmp(name, ".."))
+                continue;
+            if (fnmatch(cfilter.data(), name, 0))
+                continue;
+            char filePath[1024];
+            if (static_cast<int>(sizeof(filePath) - 1) < snprintf(filePath, sizeof(filePath), "%s/%s", cpath.data(), name))
+                continue; // buffer overflow
+            entries.append(filePath);
+        }
+        closedir(dir);
+    }
+    return entries;
+}
 
 } // namespace WebCore
index d31c9914917a1ca5e92dd74ac4c82573ed4aa3ba..5d2c80778845f60c849c97938188b586a86a9cec 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "LocalStorageThread.h"
 #include "StorageAreaSync.h"
+#include "StorageTracker.h"
 
 namespace WebCore {
 
@@ -50,6 +51,27 @@ LocalStorageTask::LocalStorageTask(Type type, LocalStorageThread* thread)
     ASSERT(m_thread);
     ASSERT(m_type == TerminateThread);
 }
+    
+LocalStorageTask::LocalStorageTask(Type type)
+    : m_type(type)
+{
+    ASSERT(m_type == ImportOrigins || m_type == DeleteAllOrigins);
+}
+    
+LocalStorageTask::LocalStorageTask(Type type, const String& originIdentifier)
+    : m_type(type)
+    , m_originIdentifier(originIdentifier)
+{
+    ASSERT(m_type == DeleteOrigin);
+}
+
+LocalStorageTask::LocalStorageTask(Type type, const String& originIdentifier, const String& databaseFilename)
+    : m_type(type)
+    , m_originIdentifier(originIdentifier)
+    , m_databaseFilename(databaseFilename)
+{
+    ASSERT(m_type == SetOriginDetails);
+}
 
 LocalStorageTask::~LocalStorageTask()
 {
@@ -64,6 +86,18 @@ void LocalStorageTask::performTask()
         case AreaSync:
             m_area->performSync();
             break;
+        case SetOriginDetails:
+            StorageTracker::tracker().syncSetOriginDetails(m_originIdentifier, m_databaseFilename);
+            break;
+        case ImportOrigins:
+            StorageTracker::tracker().syncImportOriginIdentifiers();
+            break;
+        case DeleteAllOrigins:
+            StorageTracker::tracker().syncDeleteAllOrigins();
+            break;
+        case DeleteOrigin:
+            StorageTracker::tracker().syncDeleteOrigin(m_originIdentifier);
+            break;
         case DeleteEmptyDatabase:
             m_area->deleteEmptyDatabase();
             break;
index 27a8eb5a8cead2bea6a9707df6fc331509477d5f..99e72f51ccae373667ccb229c57126d74a9a8816 100644 (file)
@@ -28,6 +28,7 @@
 
 #if ENABLE(DOM_STORAGE)
 
+#include "PlatformString.h"
 #include <wtf/PassOwnPtr.h>
 #include <wtf/Threading.h>
 
@@ -40,13 +41,17 @@ namespace WebCore {
     class LocalStorageTask {
         WTF_MAKE_NONCOPYABLE(LocalStorageTask); WTF_MAKE_FAST_ALLOCATED;
     public:
-        enum Type { AreaImport, AreaSync, DeleteEmptyDatabase, TerminateThread };
+        enum Type { AreaImport, AreaSync, DeleteEmptyDatabase, SetOriginDetails, ImportOrigins, DeleteAllOrigins, DeleteOrigin, TerminateThread };
 
         ~LocalStorageTask();
 
         static PassOwnPtr<LocalStorageTask> createImport(StorageAreaSync* area) { return adoptPtr(new LocalStorageTask(AreaImport, area)); }
         static PassOwnPtr<LocalStorageTask> createSync(StorageAreaSync* area) { return adoptPtr(new LocalStorageTask(AreaSync, area)); }
         static PassOwnPtr<LocalStorageTask> createDeleteEmptyDatabase(StorageAreaSync* area) { return adoptPtr(new LocalStorageTask(DeleteEmptyDatabase, area)); }
+        static PassOwnPtr<LocalStorageTask> createOriginIdentifiersImport() { return adoptPtr(new LocalStorageTask(ImportOrigins)); }
+        static PassOwnPtr<LocalStorageTask> createSetOriginDetails(const String& originIdentifier, const String& databaseFilename) { return adoptPtr(new LocalStorageTask(SetOriginDetails, originIdentifier, databaseFilename)); }
+        static PassOwnPtr<LocalStorageTask> createDeleteOrigin(const String& originIdentifier) { return adoptPtr(new LocalStorageTask(DeleteOrigin, originIdentifier)); }
+        static PassOwnPtr<LocalStorageTask> createDeleteAllOrigins() { return adoptPtr(new LocalStorageTask(DeleteAllOrigins)); }
         static PassOwnPtr<LocalStorageTask> createTerminate(LocalStorageThread* thread) { return adoptPtr(new LocalStorageTask(TerminateThread, thread)); }
 
         void performTask();
@@ -54,10 +59,15 @@ namespace WebCore {
     private:
         LocalStorageTask(Type, StorageAreaSync*);
         LocalStorageTask(Type, LocalStorageThread*);
+        LocalStorageTask(Type, const String& originIdentifier);
+        LocalStorageTask(Type, const String& originIdentifier, const String& databaseFilename);
+        LocalStorageTask(Type);
 
         Type m_type;
         StorageAreaSync* m_area;
         LocalStorageThread* m_thread;
+        String m_originIdentifier;
+        String m_databaseFilename;
     };
 
 } // namespace WebCore
index dc25e5484a36bb2d21f03585e3ab77fdc196097e..597ace2f9c271e119600c09e22b76dc70b1e7db8 100644 (file)
@@ -227,6 +227,31 @@ void StorageAreaImpl::close()
 #endif
 }
 
+void StorageAreaImpl::clearForOriginDeletion()
+{
+    ASSERT(!m_isShutdown);
+    blockUntilImportComplete();
+    
+    if (m_storageMap->length()) {
+        unsigned quota = m_storageMap->quota();
+        m_storageMap = StorageMap::create(quota);
+    }
+
+    if (m_storageAreaSync) {
+        m_storageAreaSync->scheduleClear();
+        m_storageAreaSync->scheduleCloseDatabase();
+    }
+}
+    
+void StorageAreaImpl::sync()
+{
+    ASSERT(!m_isShutdown);
+    blockUntilImportComplete();
+    
+    if (m_storageAreaSync)
+        m_storageAreaSync->scheduleSync();
+}
+
 void StorageAreaImpl::blockUntilImportComplete() const
 {
     if (m_storageAreaSync)
index 60d72cbd9fa9a858e287f60418fc4d6eb3fbbc00..9f87e697ab85ba67d6331c94a380dd6f0d02e03b 100644 (file)
@@ -59,6 +59,11 @@ namespace WebCore {
         // Only called from a background thread.
         void importItem(const String& key, const String& value);
 
+        // Used to clear a StorageArea and close db before backing db file is deleted.
+        void clearForOriginDeletion();
+
+        void sync();
+
     private:
         StorageAreaImpl(StorageType, PassRefPtr<SecurityOrigin>, PassRefPtr<StorageSyncManager>, unsigned quota);
         StorageAreaImpl(StorageAreaImpl*);
index f2008aba32bb63b8bdabef7040415b3d028b6cd1..52a9f9344963c71c76d2736ebc5f587217eec5d7 100644 (file)
@@ -36,6 +36,7 @@
 #include "SecurityOrigin.h"
 #include "StorageAreaImpl.h"
 #include "StorageSyncManager.h"
+#include "StorageTracker.h"
 #include "SuddenTermination.h"
 #include <wtf/text/CString.h>
 
@@ -138,6 +139,25 @@ void StorageAreaSync::scheduleClear()
     }
 }
 
+void StorageAreaSync::scheduleCloseDatabase()
+{
+    ASSERT(isMainThread());
+    ASSERT(!m_finalSyncScheduled);
+
+    if (!m_database.isOpen())
+        return;
+
+    m_syncCloseDatabase = true;
+    
+    if (!m_syncTimer.isActive()) {
+        m_syncTimer.startOneShot(StorageSyncInterval);
+        
+        // The following is balanced by the call to enableSuddenTermination in the
+        // syncTimerFired function.
+        disableSuddenTermination();
+    }
+}
+
 void StorageAreaSync::syncTimerFired(Timer<StorageAreaSync>*)
 {
     ASSERT(isMainThread());
@@ -222,6 +242,10 @@ void StorageAreaSync::openDatabase(OpenDatabaseParamType openingStrategy)
         return;
     }
 
+    // A StorageTracker thread may have been scheduled to delete the db we're
+    // reopening, so cancel possible deletion.
+    StorageTracker::tracker().cancelDeletingOrigin(m_databaseIdentifier);
+
     if (!m_database.open(databaseFilename)) {
         LOG_ERROR("Failed to open database file %s for local storage", databaseFilename.utf8().data());
         markImported();
@@ -235,6 +259,8 @@ void StorageAreaSync::openDatabase(OpenDatabaseParamType openingStrategy)
         m_databaseOpenFailed = true;
         return;
     }
+
+    StorageTracker::tracker().setOriginDetails(m_databaseIdentifier, databaseFilename);
 }
 
 void StorageAreaSync::performImport()
@@ -319,6 +345,15 @@ void StorageAreaSync::sync(bool clearItems, const HashMap<String, String>& items
     if (!m_database.isOpen())
         return;
 
+    // Closing this db because it is about to be deleted by StorageTracker.
+    // The delete will be cancelled if StorageAreaSync needs to reopen the db
+    // to write new items created after the request to delete the db.
+    if (m_syncCloseDatabase) {
+        m_syncCloseDatabase = false;
+        m_database.close();
+        return;
+    }
+    
     // If the clear flag is set, then we clear all items out before we write any new ones in.
     if (clearItems) {
         SQLiteStatement clear(m_database, "DELETE FROM ItemTable");
@@ -421,12 +456,21 @@ void StorageAreaSync::deleteEmptyDatabase()
     if (!count) {
         query.finalize();
         m_database.close();
-        String databaseFilename = m_syncManager->fullDatabaseFilename(m_databaseIdentifier);
-        if (!SQLiteFileSystem::deleteDatabaseFile(databaseFilename))
-            LOG_ERROR("Failed to delete database file %s\n", databaseFilename.utf8().data());
+        if (StorageTracker::tracker().isActive())
+            StorageTracker::tracker().deleteOrigin(m_databaseIdentifier);
+        else {
+            String databaseFilename = m_syncManager->fullDatabaseFilename(m_databaseIdentifier);
+            if (!SQLiteFileSystem::deleteDatabaseFile(databaseFilename))
+                LOG_ERROR("Failed to delete database file %s\n", databaseFilename.utf8().data());
+        }
     }
 }
 
+void StorageAreaSync::scheduleSync()
+{
+    syncTimerFired(&m_syncTimer);
+}
+    
 } // namespace WebCore
 
 #endif // ENABLE(DOM_STORAGE)
index 90aa6a78372eb75f9916186a88f8a4ce2809c8e1..ebfb05307c290c9d5cc309450277f7a70c02a3c2 100644 (file)
@@ -49,6 +49,9 @@ namespace WebCore {
 
         void scheduleItemForSync(const String& key, const String& value);
         void scheduleClear();
+        void scheduleCloseDatabase();
+
+        void scheduleSync();
 
     private:
         StorageAreaSync(PassRefPtr<StorageSyncManager>, PassRefPtr<StorageAreaImpl>, const String& databaseIdentifier);
@@ -92,6 +95,8 @@ namespace WebCore {
         bool m_syncScheduled;
         bool m_syncInProgress;
         bool m_databaseOpenFailed;
+        
+        bool m_syncCloseDatabase;
 
         mutable Mutex m_importLock;
         mutable ThreadCondition m_importCondition;
index 8f09b1a1a978519dc6560d1345234bd3143ce238..cb5df85d3d625e822c5e06d36bcc49fcc94866ae 100644 (file)
@@ -50,6 +50,9 @@ public:
     virtual PassRefPtr<StorageNamespace> copy() = 0;
     virtual void close() = 0;
     virtual void unlock() = 0;
+    virtual void clearOriginForDeletion(SecurityOrigin*) = 0;
+    virtual void clearAllOriginsForDeletion() = 0;
+    virtual void sync() = 0;
 };
 
 } // namespace WebCore
index 3a21489c3983c24e492d273a437d3665aae8c8cd..d512975341ee823e971da710a7cbf2ff5cf280fb 100644 (file)
@@ -32,6 +32,7 @@
 #include "StorageAreaImpl.h"
 #include "StorageMap.h"
 #include "StorageSyncManager.h"
+#include "StorageTracker.h"
 #include <wtf/StdLibExtras.h>
 #include <wtf/text/StringHash.h>
 
@@ -144,6 +145,32 @@ void StorageNamespaceImpl::unlock()
     // Because there's a single event loop per-process, this is a no-op.
 }
 
+void StorageNamespaceImpl::clearOriginForDeletion(SecurityOrigin* origin)
+{
+    ASSERT(isMainThread());
+
+    RefPtr<StorageAreaImpl> storageArea = m_storageAreaMap.get(origin);
+    if (storageArea)
+        storageArea->clearForOriginDeletion();
+}
+
+void StorageNamespaceImpl::clearAllOriginsForDeletion()
+{
+    ASSERT(isMainThread());
+
+    StorageAreaMap::iterator end = m_storageAreaMap.end();
+    for (StorageAreaMap::iterator it = m_storageAreaMap.begin(); it != end; ++it)
+        it->second->clearForOriginDeletion();
+}
+    
+void StorageNamespaceImpl::sync()
+{
+    ASSERT(isMainThread());
+    StorageAreaMap::iterator end = m_storageAreaMap.end();
+    for (StorageAreaMap::iterator it = m_storageAreaMap.begin(); it != end; ++it)
+        it->second->sync();
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(DOM_STORAGE)
index 5221add6a595dcdaf6213c27488bcdbc5b115d44..b562696c0a28df212c3323027e6029f514c41ba0 100644 (file)
@@ -51,6 +51,14 @@ namespace WebCore {
         virtual void close();
         virtual void unlock();
 
+        // Not removing the origin's StorageArea from m_storageAreaMap because
+        // we're just deleting the underlying db file. If an item is added immediately
+        // after file deletion, we want the same StorageArea to eventually trigger
+        // a sync and for StorageAreaSync to recreate the backing db file.
+        virtual void clearOriginForDeletion(SecurityOrigin*);
+        virtual void clearAllOriginsForDeletion();
+        virtual void sync();
+        
     private:
         StorageNamespaceImpl(StorageType, const String& path, unsigned quota);
 
diff --git a/Source/WebCore/storage/StorageTracker.cpp b/Source/WebCore/storage/StorageTracker.cpp
new file mode 100644 (file)
index 0000000..f34ae85
--- /dev/null
@@ -0,0 +1,516 @@
+/*
+ * Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS 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 "StorageTracker.h"
+
+#include "DatabaseThread.h"
+#include "FileSystem.h"
+#include "LocalStorageTask.h"
+#include "LocalStorageThread.h"
+#include "Logging.h"
+#include "PageGroup.h"
+#include "SQLiteFileSystem.h"
+#include "SQLiteStatement.h"
+#include "SecurityOrigin.h"
+#include "StorageTrackerClient.h"
+#include <wtf/MainThread.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/Vector.h>
+#include <wtf/text/CString.h>
+
+namespace WebCore {
+
+static StorageTracker* storageTracker = 0;
+
+void StorageTracker::initializeTracker(const String& storagePath)
+{
+    ASSERT(!storageTracker);
+    if (storageTracker)
+        return;
+
+    storageTracker = new StorageTracker(storagePath);
+    storageTracker->setIsActive(true);
+    storageTracker->importOriginIdentifiers();
+}
+
+StorageTracker& StorageTracker::tracker()
+{
+    if (!storageTracker) {
+        storageTracker = new StorageTracker("");
+        storageTracker->importOriginIdentifiers();
+    }
+    
+    return *storageTracker;
+}
+
+StorageTracker::StorageTracker(const String& storagePath)
+    : m_client(0)
+    , m_thread(LocalStorageThread::create())
+    , m_isActive(false)
+{
+    ASSERT(isMainThread());
+        
+    setStorageDirectoryPath(storagePath);
+    
+    SQLiteFileSystem::registerSQLiteVFS();
+    
+    m_thread->start();  
+}
+
+void StorageTracker::setStorageDirectoryPath(const String& path)
+{
+    MutexLocker lockDatabase(m_databaseGuard);
+    ASSERT(!m_database.isOpen());
+    
+    m_storageDirectoryPath = path.threadsafeCopy();
+}
+
+String StorageTracker::trackerDatabasePath() const
+{
+    return SQLiteFileSystem::appendDatabaseFileNameToPath(m_storageDirectoryPath, "StorageTracker.db");
+}
+
+void StorageTracker::openTrackerDatabase(bool createIfDoesNotExist)
+{
+    ASSERT(m_isActive);
+    ASSERT(!isMainThread());
+    ASSERT(!m_databaseGuard.tryLock());
+
+    if (m_database.isOpen())
+        return;
+    
+    String databasePath = trackerDatabasePath();
+    
+    if (!SQLiteFileSystem::ensureDatabaseFileExists(databasePath, createIfDoesNotExist)) {
+        if (createIfDoesNotExist)
+            LOG_ERROR("Failed to create database file '%s'", databasePath.ascii().data());
+        return;
+    }
+    
+    if (!m_database.open(databasePath)) {
+        LOG_ERROR("Failed to open databasePath %s.", databasePath.ascii().data());
+        return;
+    }
+    
+    m_database.disableThreadingChecks();
+    
+    if (!m_database.tableExists("Origins")) {
+        if (!m_database.executeCommand("CREATE TABLE Origins (origin TEXT UNIQUE ON CONFLICT REPLACE, path TEXT);"))
+            LOG_ERROR("Failed to create Origins table.");
+    }
+}
+
+void StorageTracker::importOriginIdentifiers()
+{   
+    if (!m_isActive)
+        return;
+    
+    ASSERT(isMainThread());
+    ASSERT(m_thread);
+
+    m_thread->scheduleTask(LocalStorageTask::createOriginIdentifiersImport());
+}
+
+void StorageTracker::syncImportOriginIdentifiers()
+{
+    ASSERT(m_isActive);
+    
+    ASSERT(!isMainThread());
+
+    {
+        MutexLocker lockDatabase(m_databaseGuard);
+
+        openTrackerDatabase(false);
+        if (!m_database.isOpen())
+            return;
+        
+        SQLiteStatement statement(m_database, "SELECT origin FROM Origins");
+        if (statement.prepare() != SQLResultOk) {
+            LOG_ERROR("Failed to prepare statement.");
+            return;
+        }
+        
+        int result;
+
+        {
+            MutexLocker lockOrigins(m_originSetGuard);
+            while ((result = statement.step()) == SQLResultRow)
+                m_originSet.add(statement.getColumnText(0).threadsafeCopy());
+        }
+        
+        if (result != SQLResultDone)
+            LOG_ERROR("Failed to read in all origins from the database.");
+    }
+    
+    syncFileSystemAndTrackerDatabase();
+    
+    if (m_client) {
+        MutexLocker lockOrigins(m_originSetGuard);
+        OriginSet::const_iterator end = m_originSet.end();
+        for (OriginSet::const_iterator it = m_originSet.begin(); it != end; ++it)
+            m_client->dispatchDidModifyOrigin(*it);
+    }
+}
+    
+void StorageTracker::syncFileSystemAndTrackerDatabase()
+{
+    ASSERT(m_isActive);
+
+    DEFINE_STATIC_LOCAL(const String, fileMatchPattern, ("*.localstorage"));
+    DEFINE_STATIC_LOCAL(const String, fileExt, (".localstorage"));
+    DEFINE_STATIC_LOCAL(const unsigned, fileExtLength, (fileExt.length()));
+
+    Vector<String> paths = listDirectory(m_storageDirectoryPath, fileMatchPattern);
+    
+    // Add missing StorageTracker records.
+    OriginSet foundOrigins;
+    Vector<String>::const_iterator end = paths.end();
+    for (Vector<String>::const_iterator it = paths.begin(); it != end; ++it) {
+        String path = *it;
+        if (path.endsWith(fileExt, true) && path.length() > fileExtLength) {
+            String file = pathGetFileName(path);
+            String originIdentifier = file.substring(0, file.length() - fileExtLength);
+            if (!m_originSet.contains(originIdentifier)) {
+                if (isMainThread())
+                    setOriginDetails(originIdentifier, path);
+                else
+                    syncSetOriginDetails(originIdentifier, path);
+            }
+
+            foundOrigins.add(originIdentifier);
+        }
+    }
+
+    // Delete stale StorageTracker records.
+    OriginSet::const_iterator setEnd = m_originSet.end();
+    for (OriginSet::const_iterator it = m_originSet.begin(); it != setEnd; ++it) {
+        if (!foundOrigins.contains(*it)) {
+            if (isMainThread())
+                deleteOrigin(*it);
+            else 
+                syncDeleteOrigin(*it);
+        }
+    }
+}
+
+void StorageTracker::setOriginDetails(const String& originIdentifier, const String& databaseFile)
+{
+    if (!m_isActive)
+        return;
+
+    {
+        MutexLocker lockOrigins(m_originSetGuard);
+
+        if (m_originSet.contains(originIdentifier))
+            return;
+
+        m_originSet.add(originIdentifier);
+    }
+
+    LocalStorageTask* task = LocalStorageTask::createSetOriginDetails(originIdentifier.threadsafeCopy(), databaseFile).leakPtr();
+
+    if (isMainThread()) {
+        ASSERT(m_thread);
+        m_thread->scheduleTask(task);
+    } else 
+        callOnMainThread(scheduleTask, (void*)task);
+}
+
+void StorageTracker::scheduleTask(void* task)
+{
+    ASSERT(isMainThread());
+    ASSERT(StorageTracker::tracker().m_thread);
+    
+    if (StorageTracker::tracker().m_thread)
+        StorageTracker::tracker().m_thread->scheduleTask((LocalStorageTask*)task);
+}
+
+void StorageTracker::syncSetOriginDetails(const String& originIdentifier, const String& databaseFile)
+{
+    ASSERT(!isMainThread());
+
+    MutexLocker lockDatabase(m_databaseGuard);
+
+    openTrackerDatabase(true);
+    
+    if (!m_database.isOpen())
+        return;
+
+    SQLiteStatement statement(m_database, "INSERT INTO Origins VALUES (?, ?)");
+    if (statement.prepare() != SQLResultOk) {
+        LOG_ERROR("Unable to establish origin '%s' in the tracker", originIdentifier.ascii().data());
+        return;
+    } 
+    
+    statement.bindText(1, originIdentifier);
+    statement.bindText(2, databaseFile);
+    
+    if (statement.step() != SQLResultDone)
+        LOG_ERROR("Unable to establish origin '%s' in the tracker", originIdentifier.ascii().data());
+
+    {
+        MutexLocker lockOrigins(m_originSetGuard);
+        if (!m_originSet.contains(originIdentifier))
+            m_originSet.add(originIdentifier);
+    }
+
+    if (m_client)
+        m_client->dispatchDidModifyOrigin(originIdentifier);
+}
+
+void StorageTracker::origins(Vector<RefPtr<SecurityOrigin> >& result)
+{
+    ASSERT(m_isActive);
+    
+    if (!m_isActive)
+        return;
+    
+    // FIXME: StorageTracker is currently a singleton and should be assumed
+    // to have undefined behavior with more than one PageGroup.
+    ASSERT(PageGroup::numberOfPageGroups() == 1);
+
+    MutexLocker lockOrigins(m_originSetGuard);
+
+    OriginSet::const_iterator end = m_originSet.end();
+    for (OriginSet::const_iterator it = m_originSet.begin(); it != end; ++it)
+        result.append(SecurityOrigin::createFromDatabaseIdentifier(*it));
+}
+
+void StorageTracker::deleteAllOrigins()
+{
+    ASSERT(m_isActive);
+    ASSERT(isMainThread());
+    ASSERT(m_thread);
+    
+    if (!m_isActive)
+        return;
+    
+    // FIXME: StorageTracker is currently a singleton and should be assumed
+    // to have undefined behavior with more than one PageGroup.
+    ASSERT(PageGroup::numberOfPageGroups() == 1);
+
+    {
+        MutexLocker lockOrigins(m_originSetGuard);
+        willDeleteAllOrigins();
+        m_originSet.clear();
+    }
+
+    PageGroup::clearLocalStorageForAllOrigins();
+    
+    m_thread->scheduleTask(LocalStorageTask::createDeleteAllOrigins());
+}
+    
+void StorageTracker::syncDeleteAllOrigins()
+{
+    ASSERT(!isMainThread());
+    
+    MutexLocker lockDatabase(m_databaseGuard);
+    
+    openTrackerDatabase(false);
+    if (!m_database.isOpen())
+        return;
+    
+    SQLiteStatement statement(m_database, "SELECT origin, path FROM Origins");
+    if (statement.prepare() != SQLResultOk) {
+        LOG_ERROR("Failed to prepare statement.");
+        return;
+    }
+    
+    int result;
+    while ((result = statement.step()) == SQLResultRow) {
+        if (!canDeleteOrigin(statement.getColumnText(0)))
+                continue;
+
+        SQLiteFileSystem::deleteDatabaseFile(statement.getColumnText(1));
+        if (m_client)
+            m_client->dispatchDidModifyOrigin(statement.getColumnText(0));
+    }
+    
+    if (result != SQLResultDone)
+        LOG_ERROR("Failed to read in all origins from the database.");
+    
+    if (m_database.isOpen())
+        m_database.close();
+    
+    SQLiteFileSystem::deleteDatabaseFile(trackerDatabasePath());
+    SQLiteFileSystem::deleteEmptyDatabaseDirectory(m_storageDirectoryPath);
+}
+
+void StorageTracker::deleteOrigin(const String& originIdentifier)
+{
+    deleteOrigin(SecurityOrigin::createFromDatabaseIdentifier(originIdentifier).get());
+}
+
+void StorageTracker::deleteOrigin(SecurityOrigin* origin)
+{    
+    ASSERT(m_isActive);
+    ASSERT(isMainThread());
+    ASSERT(m_thread);
+    
+    if (!m_isActive)
+        return;
+
+    // FIXME: StorageTracker is currently a singleton and should be assumed
+    // to have undefined behavior with more than one PageGroup.
+    ASSERT(PageGroup::numberOfPageGroups() == 1);
+    
+    // Before deleting database, we need to clear in-memory local storage data
+    // in StorageArea, and to close the StorageArea db. It's possible for an
+    // item to be added immediately after closing the db and cause StorageAreaSync
+    // to reopen the db before the db is deleted by a StorageTracker thread.
+    // In this case, reopening the db in StorageAreaSync will cancel a pending
+    // StorageTracker db deletion.
+    PageGroup::clearLocalStorageForOrigin(origin);
+
+    String originId = origin->databaseIdentifier();
+    
+    {
+        MutexLocker lockOrigins(m_originSetGuard);
+        willDeleteOrigin(originId);
+        m_originSet.remove(originId);
+    }
+    
+    m_thread->scheduleTask(LocalStorageTask::createDeleteOrigin(originId));
+}
+
+void StorageTracker::syncDeleteOrigin(const String& originIdentifier)
+{
+    ASSERT(!isMainThread());
+
+    MutexLocker lockDatabase(m_databaseGuard);
+    
+    if (!canDeleteOrigin(originIdentifier)) {
+        LOG_ERROR("Attempted to delete origin '%s' while it was being created\n", originIdentifier.ascii().data());
+        return;
+    }
+    
+    openTrackerDatabase(false);
+    if (!m_database.isOpen())
+        return;
+    
+    // Get origin's db file path, delete entry in tracker's db, then delete db file.
+    SQLiteStatement pathStatement(m_database, "SELECT path FROM Origins WHERE origin=?");
+    if (pathStatement.prepare() != SQLResultOk) {
+        LOG_ERROR("Unable to prepare selection of path for origin '%s'", originIdentifier.ascii().data());
+        return;
+    }
+    pathStatement.bindText(1, originIdentifier);
+    int result = pathStatement.step();
+    if (result != SQLResultRow) {
+        LOG_ERROR("Unable to find origin '%s' in Origins table", originIdentifier.ascii().data());
+        return;
+    }
+    
+    String path = pathStatement.getColumnText(0);
+
+    ASSERT(!path.isEmpty());
+    
+    SQLiteStatement deleteStatement(m_database, "DELETE FROM Origins where origin=?");
+    if (deleteStatement.prepare() != SQLResultOk) {
+        LOG_ERROR("Unable to prepare deletion of origin '%s'", originIdentifier.ascii().data());
+        return;
+    }
+    deleteStatement.bindText(1, originIdentifier);
+    if (!deleteStatement.executeCommand()) {
+        LOG_ERROR("Unable to execute deletion of origin '%s'", originIdentifier.ascii().data());
+        return;
+    }
+
+    SQLiteFileSystem::deleteDatabaseFile(path);
+    
+    bool shouldDeleteTrackerFiles = false;
+    {
+        MutexLocker originLock(m_originSetGuard);
+        m_originSet.remove(originIdentifier);
+        shouldDeleteTrackerFiles = m_originSet.isEmpty();
+    }
+
+    if (shouldDeleteTrackerFiles) {
+        m_database.close();
+        SQLiteFileSystem::deleteDatabaseFile(trackerDatabasePath());
+        SQLiteFileSystem::deleteEmptyDatabaseDirectory(m_storageDirectoryPath);
+    }
+    
+    if (m_client)
+        m_client->dispatchDidModifyOrigin(originIdentifier);
+}
+    
+void StorageTracker::willDeleteAllOrigins()
+{
+    ASSERT(!m_originSetGuard.tryLock());
+
+    OriginSet::const_iterator end = m_originSet.end();
+    for (OriginSet::const_iterator it = m_originSet.begin(); it != end; ++it)
+        m_originsBeingDeleted.add((*it).threadsafeCopy());
+}
+
+void StorageTracker::willDeleteOrigin(const String& originIdentifier)
+{
+    ASSERT(isMainThread());
+    ASSERT(!m_originSetGuard.tryLock());
+
+    m_originsBeingDeleted.add(originIdentifier);
+}
+    
+bool StorageTracker::canDeleteOrigin(const String& originIdentifier)
+{
+    ASSERT(!m_databaseGuard.tryLock());
+    MutexLocker lockOrigins(m_originSetGuard);
+    return m_originsBeingDeleted.contains(originIdentifier);
+}
+
+void StorageTracker::cancelDeletingOrigin(const String& originIdentifier)
+{
+    if (!m_isActive)
+        return;
+
+    MutexLocker lockOrigins(m_originSetGuard);
+    MutexLocker lockDatabase(m_databaseGuard);
+    if (!m_originsBeingDeleted.isEmpty())
+        m_originsBeingDeleted.remove(originIdentifier);
+}
+
+void StorageTracker::setClient(StorageTrackerClient* client)
+{
+    m_client = client;
+}
+
+void StorageTracker::syncLocalStorage()
+{
+    PageGroup::syncLocalStorage();
+}
+    
+bool StorageTracker::isActive()
+{
+    return m_isActive;
+}
+
+void StorageTracker::setIsActive(bool flag)
+{
+    m_isActive = flag;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/storage/StorageTracker.h b/Source/WebCore/storage/StorageTracker.h
new file mode 100644 (file)
index 0000000..009f2ce
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS 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 StorageTracker_h
+#define StorageTracker_h
+
+#if ENABLE(DOM_STORAGE)
+    
+#include "PlatformString.h"
+#include "SQLiteDatabase.h"
+#include <wtf/HashSet.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/Vector.h>
+#include <wtf/text/StringHash.h>
+
+namespace WebCore {
+
+class LocalStorageTask;
+class LocalStorageThread;
+class SecurityOrigin;
+class StorageTrackerClient;    
+
+class StorageTracker {
+    WTF_MAKE_NONCOPYABLE(StorageTracker);
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    static void initializeTracker(const String& storagePath);
+    static StorageTracker& tracker();
+    static void scheduleTask(void*);
+
+    void importOriginIdentifiers();
+    void setOriginDetails(const String& originIdentifier, const String& databaseFile);
+    
+    void deleteAllOrigins();
+    void deleteOrigin(SecurityOrigin*);
+    void deleteOrigin(const String& originIdentifier);
+    void origins(Vector<RefPtr<SecurityOrigin> >& result);
+
+    void cancelDeletingOrigin(const String& originIdentifier);
+    
+    void setClient(StorageTrackerClient*);
+    
+    bool isActive();
+
+    // Sync to disk on background thread.
+    void syncDeleteAllOrigins();
+    void syncDeleteOrigin(const String& originIdentifier);
+    void syncSetOriginDetails(const String& originIdentifier, const String& databaseFile);
+    void syncImportOriginIdentifiers();
+    void syncFileSystemAndTrackerDatabase();
+
+    void syncLocalStorage();
+
+private:
+    StorageTracker(const String& storagePath);
+
+    String trackerDatabasePath() const;
+    void openTrackerDatabase(bool createIfDoesNotExist);
+
+    void setStorageDirectoryPath(const String&);
+
+    void deleteTrackerFiles();
+
+    bool canDeleteOrigin(const String& originIdentifier);
+    void willDeleteOrigin(const String& originIdentifier);
+    void willDeleteAllOrigins();
+
+    void originFilePaths(Vector<String>& paths);
+    
+    void setIsActive(bool);
+
+    Mutex m_databaseGuard;
+    SQLiteDatabase m_database;
+
+    String m_storageDirectoryPath;
+
+    StorageTrackerClient* m_client;
+
+    typedef HashSet<String> OriginSet;
+
+    Mutex m_originSetGuard;
+    OriginSet m_originSet;
+    OriginSet m_originsBeingDeleted;
+
+    OwnPtr<LocalStorageThread> m_thread;
+    
+    bool m_isActive;
+};
+    
+} // namespace WebCore
+
+#endif // ENABLE(DOM_STORAGE)
+
+#endif // StorageTracker_h
diff --git a/Source/WebCore/storage/StorageTrackerClient.h b/Source/WebCore/storage/StorageTrackerClient.h
new file mode 100644 (file)
index 0000000..9c2d53e
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS 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 StorageTrackerClient_h
+#define StorageTrackerClient_h
+
+#include <wtf/Forward.h>
+
+namespace WebCore {
+
+class StorageTrackerClient {
+public:
+    virtual ~StorageTrackerClient() { }
+    virtual void dispatchDidModifyOrigin(const String& originIdentifier) = 0;
+};
+
+} // namespace WebCore
+
+#endif // StorageTrackerClient_h
index 78e817418e89f09d6ce12172eed4366d38401851..c5f0cef3aee30e24be2004acd1be5860ae07676e 100644 (file)
@@ -1,3 +1,12 @@
+2011-03-11  Anton D'Auria  <adauria@apple.com>
+
+        Reviewed and landed by Brady Eidson.
+
+        Add WebKit1 API to view and delete local storage
+        https://bugs.webkit.org/show_bug.cgi?id=51878
+
+        * WebKit.xcodeproj/project.pbxproj:
+
 2011-03-02  Sam Weinig  <sam@webkit.org>
 
         Reviewed by Anders Carlsson.
index 5bebdbee277b02dfb6905c793a1ec581d2f33684..d10820f2b11e3c800459ce61333986f8424c1043 100644 (file)
                37B6FB4F1063530C000FDB3B /* WebPDFDocumentExtras.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37B6FB4D1063530C000FDB3B /* WebPDFDocumentExtras.mm */; };
                37D1DCA81065928C0068F7EF /* WebJSPDFDoc.h in Headers */ = {isa = PBXBuildFile; fileRef = 37D1DCA61065928C0068F7EF /* WebJSPDFDoc.h */; };
                37D1DCA91065928C0068F7EF /* WebJSPDFDoc.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37D1DCA71065928C0068F7EF /* WebJSPDFDoc.mm */; };
+               3AB02AF612C1319B00FBB694 /* WebStorageManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3AB02AF512C1319B00FBB694 /* WebStorageManager.mm */; };
+               3AB02B0012C132B200FBB694 /* WebStorageManagerPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 3AB02AFF12C132B200FBB694 /* WebStorageManagerPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               3ABB3C7A1309C3B500E93D94 /* WebStorageTrackerClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 3ABB3C781309C3B500E93D94 /* WebStorageTrackerClient.h */; };
+               3ABB3C7B1309C3B500E93D94 /* WebStorageTrackerClient.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3ABB3C791309C3B500E93D94 /* WebStorageTrackerClient.mm */; };
+               3AE15D5012DBDED4009323C8 /* WebStorageManagerInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 3AE15D4F12DBDED4009323C8 /* WebStorageManagerInternal.h */; };
                41F4484F10338E8C0030E55E /* WebWorkersPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 41F4484D10338E8C0030E55E /* WebWorkersPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
                41F4485010338E8C0030E55E /* WebWorkersPrivate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 41F4484E10338E8C0030E55E /* WebWorkersPrivate.mm */; };
                44BB8B141241A022001E3A22 /* WebArchiveInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 44BB8B131241A022001E3A22 /* WebArchiveInternal.h */; };
                3944607E020F50ED0ECA1767 /* WebBackForwardList.mm */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebBackForwardList.mm; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                3944607F020F50ED0ECA1767 /* WebHistoryItem.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebHistoryItem.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                39446080020F50ED0ECA1767 /* WebHistoryItem.mm */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebHistoryItem.mm; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
+               3AB02AF512C1319B00FBB694 /* WebStorageManager.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebStorageManager.mm; sourceTree = "<group>"; };
+               3AB02AFF12C132B200FBB694 /* WebStorageManagerPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebStorageManagerPrivate.h; sourceTree = "<group>"; };
+               3ABB3C781309C3B500E93D94 /* WebStorageTrackerClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebStorageTrackerClient.h; sourceTree = "<group>"; };
+               3ABB3C791309C3B500E93D94 /* WebStorageTrackerClient.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebStorageTrackerClient.mm; sourceTree = "<group>"; };
+               3AE15D4F12DBDED4009323C8 /* WebStorageManagerInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebStorageManagerInternal.h; sourceTree = "<group>"; };
                41F4484D10338E8C0030E55E /* WebWorkersPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebWorkersPrivate.h; path = mac/Workers/WebWorkersPrivate.h; sourceTree = "<group>"; };
                41F4484E10338E8C0030E55E /* WebWorkersPrivate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WebWorkersPrivate.mm; path = mac/Workers/WebWorkersPrivate.mm; sourceTree = "<group>"; };
                449098B90F8F82DF0076A327 /* FeatureDefines.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = FeatureDefines.xcconfig; sourceTree = "<group>"; };
                                A5DEFC0E11D5343E00885273 /* WebDatabaseQuotaManager.mm */,
                                511F3FD30CECC88F00852565 /* WebDatabaseTrackerClient.h */,
                                511F3FD40CECC88F00852565 /* WebDatabaseTrackerClient.mm */,
+                               3AB02AF512C1319B00FBB694 /* WebStorageManager.mm */,
+                               3AB02AFF12C132B200FBB694 /* WebStorageManagerPrivate.h */,
+                               3AE15D4F12DBDED4009323C8 /* WebStorageManagerInternal.h */,
+                               3ABB3C781309C3B500E93D94 /* WebStorageTrackerClient.h */,
+                               3ABB3C791309C3B500E93D94 /* WebStorageTrackerClient.mm */,
                        );
                        name = Storage;
                        path = mac/Storage;
                                598AD92A1201CF3B00ABAE4E /* WebDeviceOrientationProviderMockInternal.h in Headers */,
                                598ADA461202275000ABAE4E /* WebDeviceOrientationProvider.h in Headers */,
                                93E2A1A4123B0B3C009FE12A /* WebDashboardRegion.h in Headers */,
+                               3AB02B0012C132B200FBB694 /* WebStorageManagerPrivate.h in Headers */,
                                CDA62AE2125F87C2007FD118 /* WebFullScreenController.h in Headers */,
+                               3AE15D5012DBDED4009323C8 /* WebStorageManagerInternal.h in Headers */,
+                               3ABB3C7A1309C3B500E93D94 /* WebStorageTrackerClient.h in Headers */,
                                BC42D324131ED1E00075FA4B /* WebLocalizableStringsInternal.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                                598AD9221201CF1000ABAE4E /* WebDeviceOrientation.mm in Sources */,
                                598AD9281201CF3200ABAE4E /* WebDeviceOrientationProviderMock.mm in Sources */,
                                93E2A1A5123B0B3C009FE12A /* WebDashboardRegion.mm in Sources */,
+                               3AB02AF612C1319B00FBB694 /* WebStorageManager.mm in Sources */,
                                CDA62AE3125F87C2007FD118 /* WebFullScreenController.mm in Sources */,
+                               3ABB3C7B1309C3B500E93D94 /* WebStorageTrackerClient.mm in Sources */,
                                BC42D34D131ED3880075FA4B /* WebLocalizableStringsInternal.mm in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
index 7e123ebf3c174928ffbd2571f4e34c5e2eceb1b3..d4c3a56dff302160f9e7226b1b245ffa1c4976c8 100644 (file)
@@ -1,3 +1,16 @@
+2011-03-11  Anton D'Auria  <adauria@apple.com>
+
+        Reviewed and landed by Brady Eidson.
+
+        Add WebKit1 API to view and delete local storage
+        https://bugs.webkit.org/show_bug.cgi?id=51878
+
+        * src/StorageNamespaceProxy.cpp:
+        (WebCore::StorageNamespaceProxy::clearOriginForDeletion):
+        (WebCore::StorageNamespaceProxy::clearAllOriginsForDeletion):
+        (WebCore::StorageNamespaceProxy::sync):
+        * src/StorageNamespaceProxy.h:
+
 2011-03-11  Dominic Mazzoni  <dmazzoni@google.com>
 
         Reviewed by Dimitri Glazkov.
index ec0dbcec1db4d48c87fa58df25aeb81663357d78..ef19b2f3407f2f4603391b85a93eaf4ee6102b3e 100644 (file)
@@ -92,6 +92,21 @@ void StorageNamespaceProxy::unlock()
     // FIXME: Implement.
 }
 
+void StorageNamespaceProxy::clearOriginForDeletion(SecurityOrigin* origin)
+{
+    ASSERT_NOT_REACHED();
+}
+
+void StorageNamespaceProxy::clearAllOriginsForDeletion()
+{
+    ASSERT_NOT_REACHED();
+}
+
+void StorageNamespaceProxy::sync()
+{
+    ASSERT_NOT_REACHED();
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(DOM_STORAGE)
index 28d7a2360dbd800e3f0375d96e3b24b4f002d903..938853120ddc50df17b894df049f24de189680fc 100644 (file)
@@ -43,6 +43,11 @@ public:
     virtual PassRefPtr<StorageNamespace> copy();
     virtual void close();
     virtual void unlock();
+    
+    virtual void clearOriginForDeletion(SecurityOrigin*);
+    virtual void clearAllOriginsForDeletion();
+    
+    virtual void sync();
 
 private:
     OwnPtr<WebKit::WebStorageNamespace> m_storageNamespace;
index 676534d9d07b1d380e457d7391de9a08ae022ebf..058356bf3b417d1c636f02e74ea752ba72fd6107 100644 (file)
@@ -1,3 +1,39 @@
+2011-03-11  Anton D'Auria  <adauria@apple.com>
+
+        Reviewed and landed by Brady Eidson.
+
+        https://bugs.webkit.org/show_bug.cgi?id=51878
+        Add WebKit1 API to view and delete local storage
+
+        * Storage/WebStorageManager.mm: Added.
+        (+[WebStorageManager sharedWebStorageManager]):
+        (-[WebStorageManager origins]):
+        (-[WebStorageManager deleteAllOrigins]):
+        (-[WebStorageManager deleteOrigin:]):
+        (-[WebStorageManager syncLocalStorage]):
+        (-[WebStorageManager syncFileSystemAndTrackerDatabase]):
+        (storageDirectoryPath):
+        (WebKitInitializeStorageIfNecessary):
+        * Storage/WebStorageManagerInternal.h: Added.
+        * Storage/WebStorageManagerPrivate.h: Added.
+        * Storage/WebStorageTrackerClient.h: Added.
+        * Storage/WebStorageTrackerClient.mm: Added.
+        (WebStorageTrackerClient::sharedWebStorageTrackerClient):
+        (WebStorageTrackerClient::WebStorageTrackerClient):
+        (WebStorageTrackerClient::~WebStorageTrackerClient):
+        (WebStorageTrackerClient::dispatchDidModifyOriginOnMainThread):
+        (WebStorageTrackerClient::dispatchDidModifyOrigin):
+        * WebCoreSupport/WebSecurityOrigin.mm:
+        (-[WebSecurityOrigin protocol]):
+        (-[WebSecurityOrigin host]):
+        (-[WebSecurityOrigin databaseIdentifier]):
+        (-[WebSecurityOrigin domain]):
+        (-[WebSecurityOrigin _initWithWebCoreSecurityOrigin:]):
+        * WebCoreSupport/WebSecurityOriginPrivate.h:
+        * WebKit.exp:
+        * WebView/WebView.mm:
+        (-[WebView _commonInitializationWithFrameName:groupName:usesDocumentViews:]):
+
 2011-03-10  Anders Carlsson  <andersca@apple.com>
 
         Reviewed by Sam Weinig.
diff --git a/Source/WebKit/mac/Storage/WebStorageManager.mm b/Source/WebKit/mac/Storage/WebStorageManager.mm
new file mode 100644 (file)
index 0000000..23f699f
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS 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.
+ */
+
+#if ENABLE(DOM_STORAGE)
+
+#import "WebSecurityOriginInternal.h"
+#import "WebStorageManagerPrivate.h"
+#import "WebStorageManagerInternal.h"
+#import "WebStorageTrackerClient.h"
+
+#import <WebCore/SecurityOrigin.h>
+#import <WebCore/StorageTracker.h>
+
+using namespace WebCore;
+
+NSString * const WebStorageDirectoryDefaultsKey = @"WebKitLocalStorageDatabasePathPreferenceKey";
+NSString * const WebStorageDidModifyOriginNotification = @"WebStorageDidModifyOriginNotification";
+
+static NSString *storageDirectoryPath();
+
+@implementation WebStorageManager
+
++ (WebStorageManager *)sharedWebStorageManager
+{
+    static WebStorageManager *sharedManager = [[WebStorageManager alloc] init];
+    return sharedManager;
+}
+
+- (NSArray *)origins
+{
+    Vector<RefPtr<SecurityOrigin> > coreOrigins;
+
+    StorageTracker::tracker().origins(coreOrigins);
+
+    NSMutableArray *webOrigins = [[NSMutableArray alloc] initWithCapacity:coreOrigins.size()];
+
+    for (size_t i = 0; i < coreOrigins.size(); ++i) {
+        WebSecurityOrigin *webOrigin = [[WebSecurityOrigin alloc] _initWithWebCoreSecurityOrigin:coreOrigins[i].get()];
+        [webOrigins addObject:webOrigin];
+        [webOrigin release];
+    }
+
+    return [webOrigins autorelease];
+}
+
+- (void)deleteAllOrigins
+{
+    StorageTracker::tracker().deleteAllOrigins();
+}
+
+- (void)deleteOrigin:(WebSecurityOrigin *)origin
+{
+    StorageTracker::tracker().deleteOrigin([origin _core]);
+}
+
+- (void)syncLocalStorage
+{
+    StorageTracker::tracker().syncLocalStorage();
+}
+
+- (void)syncFileSystemAndTrackerDatabase
+{
+    StorageTracker::tracker().syncFileSystemAndTrackerDatabase();
+}
+
+static NSString *storageDirectoryPath()
+{
+    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+    NSString *storageDirectory = [defaults objectForKey:WebStorageDirectoryDefaultsKey];
+    if (!storageDirectory || ![storageDirectory isKindOfClass:[NSString class]])
+        storageDirectory = @"~/Library/WebKit/LocalStorage";
+    
+    return [storageDirectory stringByStandardizingPath];
+}
+
+void WebKitInitializeStorageIfNecessary()
+{
+    static BOOL initialized = NO;
+    if (initialized)
+        return;
+    
+    StorageTracker::initializeTracker(storageDirectoryPath());
+    
+    StorageTracker::tracker().setClient(WebStorageTrackerClient::sharedWebStorageTrackerClient());
+    
+    initialized = YES;
+}
+
+@end
+
+#endif
diff --git a/Source/WebKit/mac/Storage/WebStorageManagerInternal.h b/Source/WebKit/mac/Storage/WebStorageManagerInternal.h
new file mode 100644 (file)
index 0000000..d3d3604
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS 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.
+ */
+#if ENABLE(DOM_STORAGE)
+
+void WebKitInitializeStorageIfNecessary();
+
+#endif
diff --git a/Source/WebKit/mac/Storage/WebStorageManagerPrivate.h b/Source/WebKit/mac/Storage/WebStorageManagerPrivate.h
new file mode 100644 (file)
index 0000000..34db3f6
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS 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.
+ */
+
+extern NSString * const WebStorageDirectoryDefaultsKey;
+extern NSString * const WebStorageDidModifyOriginNotification;
+
+@class WebSecurityOrigin;
+
+@interface WebStorageManager : NSObject
+
++ (WebStorageManager *)sharedWebStorageManager;
+
+// Returns an array of WebSecurityOrigin objects that have LocalStorage.
+- (NSArray *)origins;
+
+- (void)deleteAllOrigins;
+- (void)deleteOrigin:(WebSecurityOrigin *)origin;
+
+- (void)syncLocalStorage;
+- (void)syncFileSystemAndTrackerDatabase;
+
+@end
+
diff --git a/Source/WebKit/mac/Storage/WebStorageTrackerClient.h b/Source/WebKit/mac/Storage/WebStorageTrackerClient.h
new file mode 100644 (file)
index 0000000..d3c190c
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS 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.
+ */
+#if ENABLE(DOM_STORAGE)
+
+#import <WebCore/SecurityOrigin.h>
+#import <WebCore/StorageTrackerClient.h>
+
+using namespace WebCore;
+
+class WebStorageTrackerClient : public WebCore::StorageTrackerClient {
+public:
+    static WebStorageTrackerClient* sharedWebStorageTrackerClient();
+    static void dispatchDidModifyOriginOnMainThread(void* context);
+    
+    virtual ~WebStorageTrackerClient();
+    virtual void dispatchDidModifyOrigin(const String& originIdentifier);
+    virtual void dispatchDidModifyOrigin(PassRefPtr<SecurityOrigin>);
+private:
+    WebStorageTrackerClient();
+};
+
+#endif
diff --git a/Source/WebKit/mac/Storage/WebStorageTrackerClient.mm b/Source/WebKit/mac/Storage/WebStorageTrackerClient.mm
new file mode 100644 (file)
index 0000000..0a53b2b
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS 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.
+ */
+
+#if ENABLE(DOM_STORAGE)
+
+#import "WebStorageTrackerClient.h"
+
+#import "WebSecurityOriginInternal.h"
+#import "WebStorageManagerPrivate.h"
+#import <WebCore/PlatformString.h>
+#import <WebCore/SecurityOrigin.h>
+#import <wtf/MainThread.h>
+#import <wtf/RetainPtr.h>
+
+using namespace WebCore;
+
+WebStorageTrackerClient* WebStorageTrackerClient::sharedWebStorageTrackerClient()
+{
+    static WebStorageTrackerClient* sharedClient = new WebStorageTrackerClient();
+    return sharedClient;
+}
+
+WebStorageTrackerClient::WebStorageTrackerClient()
+{
+}
+
+WebStorageTrackerClient::~WebStorageTrackerClient()
+{
+}
+
+void WebStorageTrackerClient::dispatchDidModifyOriginOnMainThread(void* context)
+{
+    ASSERT(isMainThread());
+    WebStorageTrackerClient::sharedWebStorageTrackerClient()->dispatchDidModifyOrigin(static_cast<SecurityOrigin*>(context));
+}
+
+void WebStorageTrackerClient::dispatchDidModifyOrigin(PassRefPtr<SecurityOrigin> origin)
+{
+    RetainPtr<WebSecurityOrigin> webSecurityOrigin(AdoptNS, [[WebSecurityOrigin alloc] _initWithWebCoreSecurityOrigin:origin.get()]);
+
+    [[NSNotificationCenter defaultCenter] postNotificationName:WebStorageDidModifyOriginNotification 
+                                                        object:webSecurityOrigin.get()];
+}
+
+void WebStorageTrackerClient::dispatchDidModifyOrigin(const String& originIdentifier)
+{
+    PassRefPtr<SecurityOrigin> origin = SecurityOrigin::createFromDatabaseIdentifier(originIdentifier);
+
+    if (!isMainThread()) {
+        callOnMainThread(dispatchDidModifyOriginOnMainThread, static_cast<void*>(origin.leakRef()));
+        return;
+    }
+
+    dispatchDidModifyOrigin(origin);
+}
+
+#endif
index 385d869acc1b97151859eca437f913ee45f680a2..131a1ac1403f2c636652f9db87fd2b2da866b019 100644 (file)
@@ -46,23 +46,28 @@ using namespace WebCore;
 
     RefPtr<SecurityOrigin> origin = SecurityOrigin::create(KURL([url absoluteURL]));
     origin->ref();
-    _private = reinterpret_cast<WebSecurityOriginPrivate*>(origin.get());
+    _private = reinterpret_cast<WebSecurityOriginPrivate *>(origin.get());
 
     return self;
 }
 
-- (NSString*)protocol
+- (NSString *)protocol
 {
     return reinterpret_cast<SecurityOrigin*>(_private)->protocol();
 }
 
-- (NSString*)host
+- (NSString *)host
 {
     return reinterpret_cast<SecurityOrigin*>(_private)->host();
 }
 
+- (NSString *)databaseIdentifier
+{
+    return reinterpret_cast<SecurityOrigin*>(_private)->databaseIdentifier();
+}
+
 // Deprecated. Use host instead. This needs to stay here until we ship a new Safari.
-- (NSString*)domain
+- (NSString *)domain
 {
     return [self host];
 }
@@ -111,7 +116,7 @@ using namespace WebCore;
         return nil;
 
     origin->ref();
-    _private = reinterpret_cast<WebSecurityOriginPrivate*>(origin);
+    _private = reinterpret_cast<WebSecurityOriginPrivate *>(origin);
 
     return self;
 }
index 2973d9263b34f735c85e61a08e7907be97d4f1e6..a784aba67e316480814efac01cc14a0c4ee062dd 100644 (file)
 
 - (id)initWithURL:(NSURL *)url;
 
-- (NSString*)protocol;
-- (NSString*)host;
+- (NSString *)protocol;
+- (NSString *)host;
+
+- (NSString *)databaseIdentifier;
 
 // Returns zero if the port is the default port for the protocol, non-zero otherwise.
 - (unsigned short)port;
index 7c203075d7906a1dc14e730614de6ca63487db6a..ec8f74b8b07a9001957730565a4c210e7b3c78e3 100644 (file)
@@ -6,6 +6,7 @@
 .objc_class_name_WebCoreStatistics
 .objc_class_name_WebDataSource
 .objc_class_name_WebDatabaseManager
+.objc_class_name_WebStorageManager
 .objc_class_name_WebDefaultPolicyDelegate
 .objc_class_name_WebDeviceOrientation
 .objc_class_name_WebDeviceOrientationProviderMock
@@ -114,6 +115,8 @@ _WebReportError
 _WebScriptErrorDescriptionKey
 _WebScriptErrorDomain
 _WebScriptErrorLineNumberKey
+_WebStorageDirectoryDefaultsKey
+_WebStorageDidModifyOriginNotification
 _WebURLNamePboardType
 _WebURLPboardType
 _WebViewDidBeginEditingNotification
index 8ffc822caa307e0fa603461fd0f6ff9cde946f3b..006e10eb6b19c9741ede20e4558b639221869c9b 100644 (file)
@@ -97,6 +97,7 @@
 #import "WebPreferencesPrivate.h"
 #import "WebScriptDebugDelegate.h"
 #import "WebScriptWorldInternal.h"
+#import "WebStorageManagerInternal.h"
 #import "WebSystemInterface.h"
 #import "WebTextCompletionController.h"
 #import "WebTextIterator.h"
@@ -687,6 +688,10 @@ static NSString *leakMailQuirksUserScriptPath()
 #if ENABLE(DATABASE)
         WebKitInitializeDatabasesIfNecessary();
 #endif
+
+#if ENABLE(DOM_STORAGE)
+        WebKitInitializeStorageIfNecessary();
+#endif
         WebKitInitializeApplicationCachePathIfNecessary();
         patchMailRemoveAttributesMethod();
         
index 35466db90e27925604368789ad87aa5a739e25ca..d54ff57df02ea149bf924aa97faa635662b744d7 100644 (file)
@@ -1,3 +1,76 @@
+2011-03-11  Anton D'Auria  <adauria@apple.com>
+
+        Reviewed and landed by Brady Eidson.
+
+        https://bugs.webkit.org/show_bug.cgi?id=51878
+        Add WebKit1 API to view and delete local storage
+
+        Added tests that write to LocalStorage, delete one origin, get list of origins with local storage, delete all origins.
+
+        * DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj:
+        * DumpRenderTree/LayoutTestController.cpp:
+        (syncLocalStorageCallback):
+        (observeStorageTrackerNotificationsCallback):
+        (deleteAllLocalStorageCallback):
+        (deleteLocalStorageForOriginCallback):
+        (originsWithLocalStorageCallback):
+        (LayoutTestController::staticFunctions):
+        * DumpRenderTree/LayoutTestController.h:
+        * DumpRenderTree/StorageTrackerDelegate.h: Added.
+        * DumpRenderTree/StorageTrackerDelegate.mm: Added.
+        (-[StorageTrackerDelegate init]):
+        (-[StorageTrackerDelegate logNotifications:controller:]):
+        (-[StorageTrackerDelegate originModified:]):
+        (-[StorageTrackerDelegate dealloc]):
+        (-[StorageTrackerDelegate setControllerToNotifyDone:]):
+        * DumpRenderTree/chromium/LayoutTestController.cpp:
+        (LayoutTestController::LayoutTestController):
+        (LayoutTestController::deleteAllLocalStorage):
+        (LayoutTestController::originsWithLocalStorage):
+        (LayoutTestController::deleteLocalStorageForOrigin):
+        (observeStorageTrackerNotifications):
+        (syncLocalStorage):
+        * DumpRenderTree/chromium/LayoutTestController.h:
+        * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp:
+        (LayoutTestController::originsWithLocalStorage):
+        (LayoutTestController::deleteAllLocalStorage):
+        (LayoutTestController::deleteLocalStorageForOrigin):
+        (LayoutTestController::observeStorageTrackerNotifications):
+        (LayoutTestController::syncLocalStorage):
+        * DumpRenderTree/mac/DumpRenderTree.mm:
+        (resetDefaultsToConsistentValues):
+        (allocateGlobalControllers):
+        (releaseGlobalControllers):
+        * DumpRenderTree/mac/DumpRenderTreeMac.h:
+        * DumpRenderTree/mac/LayoutTestControllerMac.mm:
+        (LayoutTestController::syncLocalStorage):
+        (LayoutTestController::observeStorageTrackerNotifications):
+        (LayoutTestController::deleteAllLocalStorage):
+        (LayoutTestController::originsWithLocalStorage):
+        (LayoutTestController::deleteLocalStorageForOrigin):
+        * DumpRenderTree/qt/LayoutTestControllerQt.cpp:
+        (LayoutTestController::originsWithLocalStorage):
+        (LayoutTestController::deleteAllLocalStorage):
+        (LayoutTestController::deleteLocalStorageForOrigin):
+        (LayoutTestController::observeStorageTrackerNotifications):
+        (LayoutTestController::syncLocalStorage):
+        * DumpRenderTree/qt/LayoutTestControllerQt.h:
+        * DumpRenderTree/win/LayoutTestControllerWin.cpp:
+        (LayoutTestController::clearAllApplicationCaches):
+        (LayoutTestController::syncLocalStorage):
+        (LayoutTestController::observeStorageTrackerNotifications):
+        (LayoutTestController::clearAllDatabases):
+        (LayoutTestController::deleteAllLocalStorage):
+        (LayoutTestController::originsWithLocalStorage):
+        (LayoutTestController::deleteLocalStorageForOrigin):
+        * DumpRenderTree/wx/LayoutTestControllerWx.cpp:
+        (LayoutTestController::syncLocalStorage):
+        (LayoutTestController::observeStorageTrackerNotifications):
+        (LayoutTestController::clearAllDatabases):
+        (LayoutTestController::deleteAllLocalStorage):
+        (LayoutTestController::originsWithLocalStorage):
+        (LayoutTestController::deleteLocalStorageForOrigin):
+
 2011-03-11  Jessie Berlin  <jberlin@apple.com>
 
         Reviewed by Adam Roben.
index 000d83ac9ae823a38bd529a2699a0c2cac7a869d..5585bb332b7f63474da8926f9b8100134766dde1 100644 (file)
@@ -50,6 +50,8 @@
                29CFBA2E12273A1000BC30C0 /* AccessibilityTextMarkerMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 29CFBA2D12273A1000BC30C0 /* AccessibilityTextMarkerMac.mm */; };
                3713EDE2115BE19300705720 /* ColorBits-A.png in Copy Font Files */ = {isa = PBXBuildFile; fileRef = 3713EDDF115BE16F00705720 /* ColorBits-A.png */; };
                3713EDE3115BE19300705720 /* ColorBits.ttf in Copy Font Files */ = {isa = PBXBuildFile; fileRef = 3713EDE0115BE16F00705720 /* ColorBits.ttf */; };
+               3A5626CB131CA02A002BE6D9 /* StorageTrackerDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3A5626C1131C8B17002BE6D9 /* StorageTrackerDelegate.mm */; };
+               3A5626CC131CA036002BE6D9 /* StorageTrackerDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5626C0131C8B17002BE6D9 /* StorageTrackerDelegate.h */; };
                440590711268453800CFD48D /* WebArchiveDumpSupportMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 440590701268453800CFD48D /* WebArchiveDumpSupportMac.mm */; };
                4437730E125CBC3600AAE02C /* WebArchiveDumpSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 44A997830FCDE86400580F10 /* WebArchiveDumpSupport.cpp */; };
                4437730F125CBC4D00AAE02C /* WebArchiveDumpSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 44A997820FCDE86400580F10 /* WebArchiveDumpSupport.h */; };
                375F09770DAC3CB600C8B4E5 /* WebKitWeightWatcher700.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = WebKitWeightWatcher700.ttf; path = fonts/WebKitWeightWatcher700.ttf; sourceTree = "<group>"; };
                375F09780DAC3CB600C8B4E5 /* WebKitWeightWatcher800.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = WebKitWeightWatcher800.ttf; path = fonts/WebKitWeightWatcher800.ttf; sourceTree = "<group>"; };
                375F09790DAC3CB600C8B4E5 /* WebKitWeightWatcher900.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = WebKitWeightWatcher900.ttf; path = fonts/WebKitWeightWatcher900.ttf; sourceTree = "<group>"; };
+               3A5626C0131C8B17002BE6D9 /* StorageTrackerDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StorageTrackerDelegate.h; sourceTree = "<group>"; };
+               3A5626C1131C8B17002BE6D9 /* StorageTrackerDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = StorageTrackerDelegate.mm; sourceTree = "<group>"; };
                440590701268453800CFD48D /* WebArchiveDumpSupportMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WebArchiveDumpSupportMac.mm; path = mac/WebArchiveDumpSupportMac.mm; sourceTree = "<group>"; };
                44A997820FCDE86400580F10 /* WebArchiveDumpSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebArchiveDumpSupport.h; path = cf/WebArchiveDumpSupport.h; sourceTree = "<group>"; };
                44A997830FCDE86400580F10 /* WebArchiveDumpSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebArchiveDumpSupport.cpp; path = cf/WebArchiveDumpSupport.cpp; sourceTree = "<group>"; };
                                BCA18B5E0C9B08C200114369 /* ResourceLoadDelegate.mm */,
                                BCA18B5F0C9B08C200114369 /* UIDelegate.h */,
                                BCA18B600C9B08C200114369 /* UIDelegate.mm */,
+                               3A5626C0131C8B17002BE6D9 /* StorageTrackerDelegate.h */,
+                               3A5626C1131C8B17002BE6D9 /* StorageTrackerDelegate.mm */,
                        );
                        name = Delegates;
                        sourceTree = "<group>";
                                5185F6B310714E12007AA393 /* HistoryDelegate.h in Headers */,
                                E1B7816711AF31C3007E1BC2 /* MockGeolocationProvider.h in Headers */,
                                29CFBA10122736E600BC30C0 /* AccessibilityTextMarker.h in Headers */,
+                               3A5626CC131CA036002BE6D9 /* StorageTrackerDelegate.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                E1B7816511AF31B7007E1BC2 /* MockGeolocationProvider.mm in Sources */,
                                29CFBA11122736E600BC30C0 /* AccessibilityTextMarker.cpp in Sources */,
                                29CFBA2E12273A1000BC30C0 /* AccessibilityTextMarkerMac.mm in Sources */,
+                               3A5626CB131CA02A002BE6D9 /* StorageTrackerDelegate.mm in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index 9f1877c371c06b43e5b35432b666c814be8fb8bc..077a0d243746dd5397bcdf4dbc9646417f99ae13 100644 (file)
@@ -394,6 +394,60 @@ static JSValueRef clearAllDatabasesCallback(JSContextRef context, JSObjectRef fu
     return JSValueMakeUndefined(context);
 }
 
+static JSValueRef syncLocalStorageCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+
+    controller->syncLocalStorage();
+
+    return JSValueMakeUndefined(context);
+}
+
+static JSValueRef observeStorageTrackerNotificationsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+
+    if (argumentCount < 1)
+        return JSValueMakeUndefined(context);
+
+    unsigned numNotifications = JSValueToNumber(context, arguments[0], exception);
+
+    ASSERT(!*exception);
+
+    controller->observeStorageTrackerNotifications(numNotifications);
+
+    return JSValueMakeUndefined(context);
+}
+
+static JSValueRef deleteAllLocalStorageCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+    controller->deleteAllLocalStorage();
+
+    return JSValueMakeUndefined(context);
+}
+
+static JSValueRef deleteLocalStorageForOriginCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+
+    if (argumentCount < 1)
+        return JSValueMakeUndefined(context);
+
+    JSRetainPtr<JSStringRef> url(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+    ASSERT(!*exception);
+
+    controller->deleteLocalStorageForOrigin(url.get());
+
+    return JSValueMakeUndefined(context);
+}
+
+static JSValueRef originsWithLocalStorageCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+    return controller->originsWithLocalStorage(context);
+}
+
 static JSValueRef clearBackForwardListCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
 {
     // Has mac & windows implementation
@@ -2163,6 +2217,13 @@ JSStaticFunction* LayoutTestController::staticFunctions()
         { "addOriginAccessWhitelistEntry", addOriginAccessWhitelistEntryCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "setScrollbarPolicy", setScrollbarPolicyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "authenticateSession", authenticateSessionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+        { "deleteAllLocalStorage", deleteAllLocalStorageCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+        { "syncLocalStorage", syncLocalStorageCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },                
+        { "observeStorageTrackerNotifications", observeStorageTrackerNotificationsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },        
+        { "deleteLocalStorageForOrigin", deleteLocalStorageForOriginCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+        { "originsWithLocalStorage", originsWithLocalStorageCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+        { "observeStorageTrackerNotifications", observeStorageTrackerNotificationsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+        { "syncLocalStorage", syncLocalStorageCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "setShouldPaintBrokenImage", setShouldPaintBrokenImageCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { 0, 0, 0 }
     };
index 4b1c04e3f669a98c280445e35b91b1089ec6d760..55fe2200f4500f7d046614fe6b75761e1283dc05 100644 (file)
@@ -308,6 +308,12 @@ public:
 
     JSRetainPtr<JSStringRef> markerTextForListItem(JSContextRef context, JSValueRef nodeObject) const;
 
+    JSValueRef originsWithLocalStorage(JSContextRef);
+    void deleteAllLocalStorage();
+    void deleteLocalStorageForOrigin(JSStringRef originIdentifier);
+    void observeStorageTrackerNotifications(unsigned number);
+    void syncLocalStorage();
+
     void setShouldPaintBrokenImage(bool);
     bool shouldPaintBrokenImage() const { return m_shouldPaintBrokenImage; }
 
diff --git a/Tools/DumpRenderTree/StorageTrackerDelegate.h b/Tools/DumpRenderTree/StorageTrackerDelegate.h
new file mode 100644 (file)
index 0000000..e025a44
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2011 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. 
+ */
+
+class LayoutTestController;
+
+@interface StorageTrackerDelegate : NSObject {
+    unsigned numberOfNotificationsToLog;
+    LayoutTestController* controllerToNotifyDone;
+}
+
+- (void)logNotifications:(unsigned)number controller:(LayoutTestController*)controller;
+- (void)originModified:(NSNotification *)notification;
+- (void)setControllerToNotifyDone:(LayoutTestController*)controller;
+
+@end
diff --git a/Tools/DumpRenderTree/StorageTrackerDelegate.mm b/Tools/DumpRenderTree/StorageTrackerDelegate.mm
new file mode 100644 (file)
index 0000000..343880b
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2011 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. 
+ */
+
+#import "config.h"
+#import "StorageTrackerDelegate.h"
+
+#import "LayoutTestController.h"
+#import <WebKit/WebSecurityOriginPrivate.h>
+#import <WebKit/WebStorageManagerPrivate.h>
+
+@implementation StorageTrackerDelegate
+
+- (id)init
+{
+    self = [super init];
+    if (!self)
+        return nil;
+
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(originModified:) name:WebStorageDidModifyOriginNotification object:nil];
+
+    return self;
+}
+
+- (void)logNotifications:(unsigned)number controller:(LayoutTestController*)controller
+{
+    controllerToNotifyDone = controller;
+
+    numberOfNotificationsToLog = number;
+}
+
+- (void)originModified:(NSNotification *)notification
+{
+    if (!numberOfNotificationsToLog)
+        return;
+
+    numberOfNotificationsToLog--;
+    
+    if (numberOfNotificationsToLog == 0 && controllerToNotifyDone) {
+        NSArray *origins = [[WebStorageManager sharedWebStorageManager] origins];
+        for (WebSecurityOrigin *origin in origins)
+            printf("Origin identifier: '%s'\n", [[origin databaseIdentifier] UTF8String]);
+        
+        controllerToNotifyDone->notifyDone();
+    }
+}
+
+- (void)dealloc
+{
+    [[NSNotificationCenter defaultCenter] removeObserver:self name:WebStorageDidModifyOriginNotification object:nil];
+    
+    [super dealloc];
+}
+
+- (void)setControllerToNotifyDone:(LayoutTestController*)controller
+{
+    controllerToNotifyDone = controller;
+}
+
+
+@end
index 1db73705a42f764090b30108e71e3381bcc87e89..62acb1f97ff074fc4418c803cbd6219c1347f895 100644 (file)
@@ -193,7 +193,12 @@ LayoutTestController::LayoutTestController(TestShell* shell)
     bindMethod("setPrivateBrowsingEnabled", &LayoutTestController::setPrivateBrowsingEnabled);
     bindMethod("setUseDashboardCompatibilityMode", &LayoutTestController::setUseDashboardCompatibilityMode);
     bindMethod("storeWebScriptObject", &LayoutTestController::storeWebScriptObject);
-
+    bindMethod("deleteAllLocalStorage", &LayoutTestController::deleteAllLocalStorage);
+    bindMethod("originsWithLocalStorage", &LayoutTestController::originsWithLocalStorage);
+    bindMethod("deleteLocalStorageForOrigin", &LayoutTestController::deleteLocalStorageForOrigin);
+    bindMethod("observeStorageTrackerNotifications", &LayoutTestController::observeStorageTrackerNotifications);
+    bindMethod("syncLocalStorage", &LayoutTestController::syncLocalStorage);
+    
     // The fallback method is called when an unknown method is invoked.
     bindFallbackMethod(&LayoutTestController::fallbackMethod);
 
@@ -1620,3 +1625,30 @@ void LayoutTestController::setValueForUser(const CppArgumentList& arguments, Cpp
 
     input->setValue(cppVariantToWebString(arguments[1]), true);
 }
+
+void LayoutTestController::deleteAllLocalStorage(const CppArgumentList& arguments, CppVariant*)
+{
+    // Not Implemented
+}
+
+void LayoutTestController::originsWithLocalStorage(const CppArgumentList& arguments, CppVariant*)
+{
+    // Not Implemented
+}
+
+void LayoutTestController::deleteLocalStorageForOrigin(const CppArgumentList& arguments, CppVariant*)
+{
+    // Not Implemented
+}
+
+void LayoutTestController::observeStorageTrackerNotifications(const CppArgumentList&, CppVariant*)
+{
+    // Not Implemented
+}
+
+void LayoutTestController::syncLocalStorage(const CppArgumentList&, CppVariant*)
+{
+    // Not Implemented
+}
+
+
index 3db3b53f1f39724e7a8e24f868a2b62e650607ca..99324a97559ab41e703102d23906967622391b54 100644 (file)
@@ -341,6 +341,13 @@ public:
     // Forwards the setValueForUser() call to the element.
     void setValueForUser(const CppArgumentList&, CppVariant*);
 
+    // LocalStorage origin-related
+    void deleteAllLocalStorage(const CppArgumentList&, CppVariant*);
+    void originsWithLocalStorage(const CppArgumentList&, CppVariant*);
+    void deleteLocalStorageForOrigin(const CppArgumentList&, CppVariant*);
+    void observeStorageTrackerNotifications(const CppArgumentList&, CppVariant*);
+    void syncLocalStorage(const CppArgumentList&, CppVariant*);
+
 public:
     // The following methods are not exposed to JavaScript.
     void setWorkQueueFrozen(bool frozen) { m_workQueue.setFrozen(frozen); }
index e73eb46232442768d51f238ca6b5d2019248ef75..5215612076c148456a8a6a96e2fd569a0a4e1a0e 100644 (file)
@@ -651,6 +651,31 @@ void LayoutTestController::setDatabaseQuota(unsigned long long quota)
     webkit_security_origin_set_web_database_quota(origin, quota);
 }
 
+JSValueRef LayoutTestController::originsWithLocalStorage(JSContextRef)
+{
+        // FIXME: implement
+}
+
+void LayoutTestController::deleteAllLocalStorage()
+{
+        // FIXME: implement
+}
+
+void LayoutTestController::deleteLocalStorageForOrigin(JSStringRef originIdentifier)
+{
+        // FIXME: implement
+}
+
+void LayoutTestController::observeStorageTrackerNotifications(unsigned number)
+{
+        // FIXME: implement
+}
+
+void LayoutTestController::syncLocalStorage()
+{
+    // FIXME: implement
+}
+
 void LayoutTestController::setDomainRelaxationForbiddenForURLScheme(bool, JSStringRef)
 {
     // FIXME: implement
index dca0d38d7ad8233cecfa54b9cb57eb527fc43377..ab5dfd23fbb0334b914a4217447bc06b1c11b01d 100644 (file)
@@ -48,6 +48,7 @@
 #import "PixelDumpSupport.h"
 #import "PolicyDelegate.h"
 #import "ResourceLoadDelegate.h"
+#import "StorageTrackerDelegate.h"
 #import "UIDelegate.h"
 #import "WebArchiveDumpSupport.h"
 #import "WorkQueue.h"
@@ -77,6 +78,7 @@
 #import <WebKit/WebPreferencesPrivate.h>
 #import <WebKit/WebPreferenceKeysPrivate.h>
 #import <WebKit/WebResourceLoadDelegate.h>
+#import <WebKit/WebStorageManagerPrivate.h>
 #import <WebKit/WebTypesInternal.h>
 #import <WebKit/WebViewPrivate.h>
 #import <getopt.h>
@@ -134,6 +136,7 @@ static EditingDelegate *editingDelegate;
 static ResourceLoadDelegate *resourceLoadDelegate;
 static HistoryDelegate *historyDelegate;
 PolicyDelegate *policyDelegate;
+StorageTrackerDelegate *storageDelegate;
 
 static int dumpPixels;
 static int threaded;
@@ -414,6 +417,7 @@ static void resetDefaultsToConsistentValues()
 
     NSString *path = libraryPathForDumpRenderTree();
     [defaults setObject:[path stringByAppendingPathComponent:@"Databases"] forKey:WebDatabaseDirectoryDefaultsKey];
+    [defaults setObject:[path stringByAppendingPathComponent:@"LocalStorage"] forKey:WebStorageDirectoryDefaultsKey];
     [defaults setObject:[path stringByAppendingPathComponent:@"LocalCache"] forKey:WebKitLocalCacheDefaultsKey];
 
     WebPreferences *preferences = [WebPreferences standardPreferences];
@@ -545,6 +549,7 @@ static void allocateGlobalControllers()
     resourceLoadDelegate = [[ResourceLoadDelegate alloc] init];
     policyDelegate = [[PolicyDelegate alloc] init];
     historyDelegate = [[HistoryDelegate alloc] init];
+    storageDelegate = [[StorageTrackerDelegate alloc] init];
 }
 
 // ObjC++ doens't seem to let me pass NSObject*& sadly.
@@ -562,6 +567,7 @@ static void releaseGlobalControllers()
     releaseAndZero(&resourceLoadDelegate);
     releaseAndZero(&uiDelegate);
     releaseAndZero(&policyDelegate);
+    releaseAndZero(&storageDelegate);
 }
 
 static void initializeGlobalsFromCommandLineOptions(int argc, const char *argv[])
index 36c5eacb571bf11f9809c50bbe871aa035cb7e7c..901008cc12ff54f6018dc634883a0fc7a23dbea8 100644 (file)
@@ -35,6 +35,7 @@
 @class DumpRenderTreeDraggingInfo;
 @class NavigationController;
 @class PolicyDelegate;
+@class StorageTrackerDelegate;
 @class WebFrame;
 @class WebScriptWorld;
 @class WebView;
@@ -42,6 +43,7 @@
 class DumpRenderTreeDraggingInfo;
 class NavigationController;
 class PolicyDelegate;
+class StorageTrackerDelegate;
 class WebFrame;
 class WebScriptWorld;
 class WebView;
@@ -54,6 +56,7 @@ extern WebFrame* topLoadingFrame;
 extern DumpRenderTreeDraggingInfo *draggingInfo;
 extern NavigationController* gNavigationController;
 extern PolicyDelegate* policyDelegate;
+extern StorageTrackerDelegate* storageDelegate;
 
 extern const unsigned maxViewHeight;
 extern const unsigned maxViewWidth;
index 72ec7598530de0143aa610d1d28242e53f06775c..58a7adfa2aaacfed257e374032868db6e75a51fb 100644 (file)
@@ -33,6 +33,7 @@
 #import "EditingDelegate.h"
 #import "MockGeolocationProvider.h"
 #import "PolicyDelegate.h"
+#import "StorageTrackerDelegate.h"
 #import "UIDelegate.h"
 #import "WorkQueue.h"
 #import "WorkQueueItem.h"
@@ -66,6 +67,7 @@
 #import <WebKit/WebQuotaManager.h>
 #import <WebKit/WebScriptWorld.h>
 #import <WebKit/WebSecurityOriginPrivate.h>
+#import <WebKit/WebStorageManagerPrivate.h>
 #import <WebKit/WebTypesInternal.h>
 #import <WebKit/WebView.h>
 #import <WebKit/WebViewPrivate.h>
@@ -133,11 +135,53 @@ void LayoutTestController::clearAllApplicationCaches()
     [WebApplicationCache deleteAllApplicationCaches];
 }
 
+void LayoutTestController::syncLocalStorage()
+{
+    [[WebStorageManager sharedWebStorageManager] syncLocalStorage];
+}
+
+void LayoutTestController::observeStorageTrackerNotifications(unsigned number)
+{
+    [storageDelegate logNotifications:number controller:this];
+}
+
 void LayoutTestController::clearAllDatabases()
 {
     [[WebDatabaseManager sharedWebDatabaseManager] deleteAllDatabases];
 }
 
+void LayoutTestController::deleteAllLocalStorage()
+{
+    [[WebStorageManager sharedWebStorageManager] deleteAllOrigins];
+}
+
+JSValueRef LayoutTestController::originsWithLocalStorage(JSContextRef context)
+{
+    WebStorageManager *storage = [WebStorageManager sharedWebStorageManager];
+
+    NSArray *origins = [storage origins];
+    NSInteger count = [origins count];
+
+    JSValueRef jsOriginsArray[count];
+    for (NSInteger i = 0; i < count; i++) {
+        NSString *origin = [[origins objectAtIndex:i] databaseIdentifier];
+        JSStringRef str = JSStringCreateWithCFString((CFStringRef)origin);
+        jsOriginsArray[i] = JSValueMakeString(context, str);
+    }
+
+    JSObjectRef jsArrayObject = JSObjectMakeArray(context, count, jsOriginsArray, NULL);
+    return jsArrayObject;
+}
+
+void LayoutTestController::deleteLocalStorageForOrigin(JSStringRef URL)
+{
+    RetainPtr<CFStringRef> urlCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, URL));
+    
+    WebSecurityOrigin *origin = [[WebSecurityOrigin alloc] initWithURL:[NSURL URLWithString:(NSString *)urlCF.get()]];
+
+    [[WebStorageManager sharedWebStorageManager] deleteOrigin:origin];
+}
+
 void LayoutTestController::clearBackForwardList()
 {
     WebBackForwardList *backForwardList = [[mainFrame webView] backForwardList];
index 74055e20007c5d161b7457aac6014d2ccd253460..ad9e968598de58b8ca92c58b6c0b70380e034776 100644 (file)
@@ -842,5 +842,30 @@ void LayoutTestController::setMinimumTimerInterval(double minimumTimerInterval)
     DumpRenderTreeSupportQt::setMinimumTimerInterval(m_drt->webPage(), minimumTimerInterval);
 }
 
+void LayoutTestController::originsWithLocalStorage()
+{
+    // FIXME: Implement.
+}
+
+void LayoutTestController::deleteAllLocalStorage()
+{
+    // FIXME: Implement.
+}
+
+void LayoutTestController::deleteLocalStorageForOrigin(const QString& originIdentifier)
+{
+    // FIXME: Implement.
+}
+
+void LayoutTestController::observeStorageTrackerNotifications(unsigned number)
+{
+    // FIXME: Implement.
+}
+
+void LayoutTestController::syncLocalStorage()
+{
+    // FIXME: Implement.
+}
+
 const unsigned LayoutTestController::maxViewWidth = 800;
 const unsigned LayoutTestController::maxViewHeight = 600;
index 0b5bbbacc6ce02f26faec21babce71b62a6d90cd..41d0acaf73090132a3b14b306565184f19891b09 100644 (file)
@@ -253,6 +253,12 @@ public slots:
     void addUserStyleSheet(const QString& sourceCode);
 
     void setMinimumTimerInterval(double);
+    
+    void originsWithLocalStorage();
+    void deleteAllLocalStorage();
+    void deleteLocalStorageForOrigin(const QString& originIdentifier);
+    void observeStorageTrackerNotifications(unsigned number);
+    void syncLocalStorage();
 
 private slots:
     void processWork();
index 12a3a55b8ab626d8200cc14358df289f02661821..1d1730f8be09c778d72524fe86fb3cecaf8862b2 100644 (file)
@@ -1428,6 +1428,32 @@ void LayoutTestController::setSerializeHTTPLoads(bool)
     // FIXME: Implement.
 }
 
+void LayoutTestController::syncLocalStorage()
+{
+    // FIXME: Implement.
+}
+
+void LayoutTestController::observeStorageTrackerNotifications(unsigned number)
+{
+    // FIXME: Implement.
+}
+
+void LayoutTestController::deleteAllLocalStorage()
+{
+    // FIXME: Implement.
+}
+
+JSValueRef LayoutTestController::originsWithLocalStorage(JSContextRef context)
+{
+    // FIXME: Implement.
+    return JSValueMakeUndefined(context);
+}
+
+void LayoutTestController::deleteLocalStorageForOrigin(JSStringRef URL)
+{
+    // FIXME: Implement.
+}
+
 void LayoutTestController::setMinimumTimerInterval(double minimumTimerInterval)
 {
     COMPtr<IWebView> webView;
@@ -1440,3 +1466,5 @@ void LayoutTestController::setMinimumTimerInterval(double minimumTimerInterval)
 
     viewPrivate->setMinimumTimerInterval(minimumTimerInterval);
 }
+
+
index a95aa505ad7cdd3da05fc7896ed8bfd708f89580..e6e5c4eec1c357d7571327263c0fdaef1837ac18 100644 (file)
@@ -558,4 +558,33 @@ void LayoutTestController::setSerializeHTTPLoads(bool)
 void LayoutTestController::setMinimumTimerInterval(double interval) {
 
 }
-    
+
+void LayoutTestController::syncLocalStorage()
+{
+    // FIXME: Implement.
+}
+
+void LayoutTestController::observeStorageTrackerNotifications(unsigned number)
+{
+    // FIXME: Implement.
+}
+
+void LayoutTestController::clearAllDatabases()
+{
+    // FIXME: Implement.
+}
+
+void LayoutTestController::deleteAllLocalStorage()
+{
+    // FIXME: Implement.
+}
+
+JSValueRef LayoutTestController::originsWithLocalStorage(JSContextRef context)
+{
+    // FIXME: Implement.
+}
+
+void LayoutTestController::deleteLocalStorageForOrigin(JSStringRef URL)
+{
+    // FIXME: Implement.
+}