mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 527667 - DOM Storage (localStorage, sessionStorage) data is not cleared when 'Clear Recent History' is used with Time range not 'Everything', r+sr=jst, a=blocking2.0:betaN
This commit is contained in:
parent
2366aa408c
commit
3bc58a18b1
@ -152,6 +152,11 @@ Sanitizer.prototype = {
|
||||
// This cookie was created after our cutoff, clear it
|
||||
cookieMgr.remove(cookie.host, cookie.name, cookie.path, false);
|
||||
}
|
||||
|
||||
// Also handle all DOM storage data created after the cutoff.
|
||||
var domStorageManager = Components.classes["@mozilla.org/dom/storagemanager;1"]
|
||||
.getService(Ci.nsIDOMStorageManager);
|
||||
domStorageManager.clearStorageDataSince(this.range[0]);
|
||||
}
|
||||
else {
|
||||
// Remove everything
|
||||
|
@ -40,7 +40,7 @@
|
||||
interface nsIDOMStorage;
|
||||
interface nsIPrincipal;
|
||||
|
||||
[scriptable, uuid(fd91ec36-7da8-43bb-b8f2-4b57a862a467)]
|
||||
[scriptable, uuid(9b729267-00ed-4e5c-a3d2-b5572ca0934d)]
|
||||
interface nsIDOMStorageManager : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -59,6 +59,15 @@ interface nsIDOMStorageManager : nsISupports
|
||||
*/
|
||||
void clearOfflineApps();
|
||||
|
||||
/**
|
||||
* Clears any data stored in DOM storage since the provided time
|
||||
* @param since
|
||||
* Any storage value that has been inserted after the time specified
|
||||
* with 'since' will be deleted. The time is in microseconds, defined
|
||||
* as PR_Now() function result.
|
||||
*/
|
||||
void clearStorageDataSince(in PRInt64 since);
|
||||
|
||||
/**
|
||||
* Returns instance of localStorage object for aURI's origin.
|
||||
* This method ensures there is always only a single instance
|
||||
|
@ -65,6 +65,7 @@
|
||||
#include "nsDOMString.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsIProxyObjectManager.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
|
||||
static const PRUint32 ASK_BEFORE_ACCEPT = 1;
|
||||
static const PRUint32 ACCEPT_SESSION = 2;
|
||||
@ -402,10 +403,13 @@ nsDOMStorageManager::Observe(nsISupports *aSubject,
|
||||
|
||||
PRUint32 cap = 0;
|
||||
perm->GetCapability(&cap);
|
||||
if (!(cap & nsICookiePermission::ACCESS_SESSION) ||
|
||||
nsDependentString(aData) != NS_LITERAL_STRING("deleted"))
|
||||
if (!(cap & nsICookiePermission::ACCESS_SESSION))
|
||||
return NS_OK;
|
||||
|
||||
// In any change to ACCESS_SESSION, like add or delete, drop the session
|
||||
// only storage in-memory database. This ensures that it will always be
|
||||
// newly created and therefor preloaded with data from the persistent
|
||||
// database after we switched to ACCESS_SESSION.
|
||||
nsCAutoString host;
|
||||
perm->GetHost(host);
|
||||
if (host.IsEmpty())
|
||||
@ -438,6 +442,33 @@ nsDOMStorageManager::GetUsage(const nsAString& aDomain,
|
||||
PR_FALSE, aUsage);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMStorageManager::ClearStorageDataSince(PRInt64 aSince)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
rv = nsDOMStorage::InitDB();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = nsDOMStorage::gStorageDB->RemoveTimeRange(aSince);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIObserverService> obsserv = mozilla::services::GetObserverService();
|
||||
if (obsserv) {
|
||||
nsCOMPtr<nsISupportsPRTime> time = do_CreateInstance(
|
||||
"@mozilla.org/supports-PRTime;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = time->SetData(aSince);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = obsserv->NotifyObservers(time, NS_DOMSTORAGE_CUTOFF_OBSERVER, nsnull);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMStorageManager::ClearOfflineApps()
|
||||
{
|
||||
@ -660,6 +691,8 @@ nsDOMStorage::InitAsSessionStorage(nsIPrincipal *aPrincipal, const nsSubstring &
|
||||
mQuotaDomainDBKey.Truncate();
|
||||
#endif
|
||||
|
||||
RegisterObservers(false);
|
||||
|
||||
mStorageType = SessionStorage;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -703,7 +736,7 @@ nsDOMStorage::InitAsLocalStorage(nsIPrincipal *aPrincipal, const nsSubstring &aD
|
||||
mCanUseChromePersist = URICanUseChromePersist(URI);
|
||||
}
|
||||
|
||||
RegisterObservers();
|
||||
RegisterObservers(true);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -731,7 +764,7 @@ nsDOMStorage::InitAsGlobalStorage(const nsACString &aDomainDemanded)
|
||||
mStorageType = GlobalStorage;
|
||||
mEventBroadcaster = this;
|
||||
|
||||
RegisterObservers();
|
||||
RegisterObservers(true);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1091,6 +1124,12 @@ nsDOMStorage::SetItem(const nsAString& aKey, const nsAString& aData)
|
||||
entry->mItem = newitem;
|
||||
}
|
||||
|
||||
if (!UseDB()) {
|
||||
// This is used only for sessionStorage, no need to setup the time also when
|
||||
// loading items from the database etc.
|
||||
entry->mItem->SetInsertTimeToNow();
|
||||
}
|
||||
|
||||
if ((oldValue != aData || mStorageType == GlobalStorage) && mEventBroadcaster)
|
||||
mEventBroadcaster->BroadcastChangeNotification(aKey, oldValue, aData);
|
||||
|
||||
@ -1532,13 +1571,16 @@ nsDOMStorage::MaybeCommitTemporaryTable(bool force)
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMStorage::RegisterObservers()
|
||||
nsDOMStorage::RegisterObservers(bool persistent)
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> obsserv = mozilla::services::GetObserverService();
|
||||
if (obsserv) {
|
||||
obsserv->AddObserver(this, "profile-before-change", PR_TRUE);
|
||||
obsserv->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_TRUE);
|
||||
obsserv->AddObserver(this, NS_DOMSTORAGE_FLUSH_TIMER_OBSERVER, PR_TRUE);
|
||||
if (persistent) {
|
||||
obsserv->AddObserver(this, "profile-before-change", PR_TRUE);
|
||||
obsserv->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_TRUE);
|
||||
obsserv->AddObserver(this, NS_DOMSTORAGE_FLUSH_TIMER_OBSERVER, PR_TRUE);
|
||||
}
|
||||
obsserv->AddObserver(this, NS_DOMSTORAGE_CUTOFF_OBSERVER, PR_TRUE);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1561,6 +1603,17 @@ nsDOMStorage::SetTemporaryTableLoaded(bool loaded)
|
||||
mLoadedTemporaryTable = loaded;
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
StorageCutOffEnum(nsSessionStorageEntry* aEntry, void* userArg)
|
||||
{
|
||||
PRInt64 since = *(PRInt64*)userArg;
|
||||
|
||||
if (aEntry->mItem->ShouldBeCutOff(since))
|
||||
return PL_DHASH_REMOVE;
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMStorage::Observe(nsISupports *subject,
|
||||
const char *topic,
|
||||
@ -1579,6 +1632,30 @@ nsDOMStorage::Observe(nsISupports *subject,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!strcmp(topic, NS_DOMSTORAGE_CUTOFF_OBSERVER)) {
|
||||
if (UseDB()) {
|
||||
// If this storage is using the database (localStorage, globalStorage)
|
||||
// then just re-cache the items from the database, database is now up to
|
||||
// date.
|
||||
mItemsCached = PR_FALSE;
|
||||
CacheKeysFromDB();
|
||||
}
|
||||
else {
|
||||
// This is sessionStorage. In that case we need to prune the mItems hash
|
||||
// table. Insert times are properly set in nsDOMStorage::SetItem.
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsISupportsPRTime> time = do_QueryInterface(subject, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt64 since;
|
||||
rv = time->GetData(&since);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mItems.EnumerateEntries(StorageCutOffEnum, &since);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_WARNING("Unrecognized topic in nsDOMStorage::Observe");
|
||||
return NS_OK;
|
||||
}
|
||||
@ -2031,6 +2108,7 @@ nsDOMStorageItem::nsDOMStorageItem(nsDOMStorage* aStorage,
|
||||
: mSecure(aSecure),
|
||||
mKey(aKey),
|
||||
mValue(aValue),
|
||||
mInsertTime(0),
|
||||
mStorage(aStorage)
|
||||
{
|
||||
}
|
||||
|
@ -64,6 +64,7 @@
|
||||
#include "mozilla/TimeStamp.h"
|
||||
|
||||
#define NS_DOMSTORAGE_FLUSH_TIMER_OBSERVER "domstorage-flush-timer"
|
||||
#define NS_DOMSTORAGE_CUTOFF_OBSERVER "domstorage-cutoff"
|
||||
|
||||
#ifdef MOZ_STORAGE
|
||||
#include "nsDOMStorageDBWrapper.h"
|
||||
@ -242,7 +243,7 @@ public:
|
||||
return static_cast<nsDOMStorage*>(static_cast<nsIDOMStorageObsolete*>(aSupports));
|
||||
}
|
||||
|
||||
nsresult RegisterObservers();
|
||||
nsresult RegisterObservers(bool persistent);
|
||||
nsresult MaybeCommitTemporaryTable(bool force);
|
||||
|
||||
bool WasTemporaryTableLoaded();
|
||||
@ -464,6 +465,16 @@ public:
|
||||
mValue.Truncate();
|
||||
}
|
||||
|
||||
void SetInsertTimeToNow()
|
||||
{
|
||||
mInsertTime = PR_Now();
|
||||
}
|
||||
|
||||
bool ShouldBeCutOff(PRInt64 since)
|
||||
{
|
||||
return mInsertTime > since;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
// true if this value is for secure sites only
|
||||
@ -475,6 +486,9 @@ protected:
|
||||
// value of the item
|
||||
nsString mValue;
|
||||
|
||||
// insertion/update time
|
||||
PRInt64 mInsertTime;
|
||||
|
||||
// If this item came from the db, mStorage points to the storage
|
||||
// object where this item came from.
|
||||
nsRefPtr<nsDOMStorage> mStorage;
|
||||
|
@ -263,6 +263,25 @@ nsDOMStorageDBWrapper::RemoveOwner(const nsACString& aOwner,
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMStorageDBWrapper::RemoveTimeRange(PRInt64 aSince)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
rv = mPrivateBrowsingDB.RemoveTimeRange(aSince);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (nsDOMStorageManager::gStorageManager->InPrivateBrowsingMode())
|
||||
return NS_OK;
|
||||
|
||||
rv = mSessionOnlyDB.RemoveTimeRange(aSince);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mPersistentDB.RemoveTimeRange(aSince);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMStorageDBWrapper::RemoveOwners(const nsTArray<nsString> &aOwners,
|
||||
|
@ -177,6 +177,13 @@ public:
|
||||
RemoveOwners(const nsTArray<nsString>& aOwners,
|
||||
PRBool aIncludeSubDomains, PRBool aMatch);
|
||||
|
||||
/**
|
||||
* Removes all keys that were created after the time specified by 'aSince'.
|
||||
* 'aSince' value is compatible with PR_Now() function.
|
||||
*/
|
||||
nsresult
|
||||
RemoveTimeRange(PRInt64 aSince);
|
||||
|
||||
/**
|
||||
* Removes all keys from storage. Used when clearing storage.
|
||||
*/
|
||||
|
@ -230,6 +230,7 @@ nsDOMStorageMemoryDB::SetKey(nsDOMStorage* aStorage,
|
||||
|
||||
item->mValue = aValue;
|
||||
item->mSecure = aSecure;
|
||||
item->mInsertTime = PR_Now();
|
||||
|
||||
*aNewUsage = usage;
|
||||
|
||||
@ -379,6 +380,34 @@ nsDOMStorageMemoryDB::RemoveOwners(const nsTArray<nsString> &aOwners,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
RemoveTimeRangeEnum(const nsAString& keyname,
|
||||
nsAutoPtr<nsDOMStorageMemoryDB::nsInMemoryItem>& item,
|
||||
void *closure)
|
||||
{
|
||||
if (item->mInsertTime > *(PRInt64*)closure)
|
||||
return PL_DHASH_REMOVE;
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
RemoveTimeRangeStoragesEnum(const nsACString& key,
|
||||
nsAutoPtr<nsDOMStorageMemoryDB::nsInMemoryStorage>& storage,
|
||||
void *closure)
|
||||
{
|
||||
storage->mTable.Enumerate(RemoveTimeRangeEnum, closure);
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMStorageMemoryDB::RemoveTimeRange(PRInt64 since)
|
||||
{
|
||||
mData.Enumerate(RemoveTimeRangeStoragesEnum, &since);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMStorageMemoryDB::RemoveAll()
|
||||
{
|
||||
|
@ -56,6 +56,7 @@ public:
|
||||
public:
|
||||
PRBool mSecure;
|
||||
nsString mValue;
|
||||
PRInt64 mInsertTime;
|
||||
};
|
||||
|
||||
typedef nsClassHashtable<nsStringHashKey, nsInMemoryItem> nsStorageItemsTable;
|
||||
@ -159,6 +160,14 @@ public:
|
||||
RemoveOwners(const nsTArray<nsString>& aOwners,
|
||||
PRBool aIncludeSubDomains, PRBool aMatch);
|
||||
|
||||
/**
|
||||
* Remove all values from all scopes not marked as offline that has been
|
||||
* created after the time specified with 'aSince'. Used by the Clear Private
|
||||
* Data dialog. 'aSince' value is compatible with PR_Now() function.
|
||||
*/
|
||||
nsresult
|
||||
RemoveTimeRange(PRInt64 aSince);
|
||||
|
||||
/**
|
||||
* Removes all keys from storage. Used when clearing storage.
|
||||
*/
|
||||
|
@ -205,30 +205,63 @@ nsDOMStoragePersistentDB::Init(const nsString& aDatabaseName)
|
||||
"PRAGMA temp_store = MEMORY"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt32 schemaVersion;
|
||||
rv = mConnection->GetSchemaVersion(&schemaVersion);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mozStorageTransaction transaction(mConnection, PR_FALSE);
|
||||
|
||||
// Ensure Gecko 1.9.1 storage table
|
||||
rv = mConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE IF NOT EXISTS webappsstore2 ("
|
||||
"scope TEXT, "
|
||||
"key TEXT, "
|
||||
"value TEXT, "
|
||||
"secure INTEGER, "
|
||||
"owner TEXT)"));
|
||||
PRBool exists;
|
||||
|
||||
rv = mConnection->TableExists(NS_LITERAL_CSTRING("webappsstore2"),
|
||||
&exists);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!exists) {
|
||||
rv = mConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE webappsstore2 ("
|
||||
"scope TEXT, "
|
||||
"key TEXT, "
|
||||
"value TEXT, "
|
||||
"secure INTEGER, "
|
||||
"owner TEXT, "
|
||||
"inserttime BIGINT DEFAULT 0)"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else {
|
||||
if (schemaVersion == 0) {
|
||||
rv = mConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"ALTER TABLE webappsstore2 "
|
||||
"ADD COLUMN inserttime BIGINT DEFAULT 0"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
|
||||
if (schemaVersion == 0) {
|
||||
rv = mConnection->SetSchemaVersion(1);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
rv = mConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE UNIQUE INDEX IF NOT EXISTS scope_key_index"
|
||||
" ON webappsstore2(scope, key)"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE INDEX IF NOT EXISTS inserttime_index"
|
||||
" ON webappsstore2(inserttime)"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
||||
rv = mConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TEMPORARY TABLE webappsstore2_temp ("
|
||||
"scope TEXT, "
|
||||
"key TEXT, "
|
||||
"value TEXT, "
|
||||
"secure INTEGER, "
|
||||
"owner TEXT)"));
|
||||
"owner TEXT, "
|
||||
"inserttime BIGINT DEFAULT 0)"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
@ -236,6 +269,11 @@ nsDOMStoragePersistentDB::Init(const nsString& aDatabaseName)
|
||||
" ON webappsstore2_temp(scope, key)"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE INDEX IF NOT EXISTS inserttime_index_temp"
|
||||
" ON webappsstore2_temp(inserttime)"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
||||
rv = mConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TEMPORARY VIEW webappsstore2_view AS "
|
||||
@ -271,8 +309,6 @@ nsDOMStoragePersistentDB::Init(const nsString& aDatabaseName)
|
||||
rv = mConnection->CreateFunction(NS_LITERAL_CSTRING("ISOFFLINE"), 1, function2);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool exists;
|
||||
|
||||
// Check if there is storage of Gecko 1.9.0 and if so, upgrade that storage
|
||||
// to actual webappsstore2 table and drop the obsolete table. First process
|
||||
// this newer table upgrade to priority potential duplicates from older
|
||||
@ -355,8 +391,8 @@ nsDOMStoragePersistentDB::Init(const nsString& aDatabaseName)
|
||||
// insert a new key
|
||||
rv = mConnection->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"INSERT OR REPLACE INTO "
|
||||
"webappsstore2_temp(scope, key, value, secure) "
|
||||
"VALUES (:scope, :key, :value, :secure)"),
|
||||
"webappsstore2_temp(scope, key, value, secure, inserttime) "
|
||||
"VALUES (:scope, :key, :value, :secure, :inserttime)"),
|
||||
getter_AddRefs(mInsertKeyStatement));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
@ -391,6 +427,14 @@ nsDOMStoragePersistentDB::Init(const nsString& aDatabaseName)
|
||||
getter_AddRefs(mRemoveStorageStatement));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// remove keys that are junger then a specific time
|
||||
rv = mConnection->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"DELETE FROM webappsstore2_view "
|
||||
"WHERE inserttime > :time "
|
||||
"AND NOT ISOFFLINE(scope)"),
|
||||
getter_AddRefs(mRemoveTimeRangeStatement));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// remove all keys
|
||||
rv = mConnection->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"DELETE FROM webappsstore2_view"),
|
||||
@ -689,6 +733,9 @@ nsDOMStoragePersistentDB::SetKey(nsDOMStorage* aStorage,
|
||||
rv = binder->BindInt32ByName(NS_LITERAL_CSTRING("secure"),
|
||||
aSecure ? 1 : 0);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = binder->BindInt64ByName(NS_LITERAL_CSTRING("inserttime"),
|
||||
PR_Now());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = binder.Add();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -805,6 +852,32 @@ nsDOMStoragePersistentDB::ClearStorage(nsDOMStorage* aStorage)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMStoragePersistentDB::RemoveTimeRange(PRInt64 since)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
rv = MaybeCommitInsertTransaction();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mozStorageStatementScoper scope(mRemoveTimeRangeStatement);
|
||||
|
||||
Binder binder(mRemoveTimeRangeStatement, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = binder->BindInt64ByName(NS_LITERAL_CSTRING("time"),
|
||||
since);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = binder.Add();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mRemoveTimeRangeStatement->Execute();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMStoragePersistentDB::RemoveOwner(const nsACString& aOwner,
|
||||
PRBool aIncludeSubDomains)
|
||||
|
@ -128,6 +128,14 @@ public:
|
||||
RemoveOwners(const nsTArray<nsString>& aOwners,
|
||||
PRBool aIncludeSubDomains, PRBool aMatch);
|
||||
|
||||
/**
|
||||
* Remove all values from all scopes not marked as offline that has been
|
||||
* created after the time specified with 'aSince'. Used by the Clear Private
|
||||
* Data dialog. 'aSince' value is compatible with PR_Now() function.
|
||||
*/
|
||||
nsresult
|
||||
RemoveTimeRange(PRInt64 aSince);
|
||||
|
||||
/**
|
||||
* Removes all keys from storage. Used when clearing storage.
|
||||
*/
|
||||
@ -176,6 +184,7 @@ protected:
|
||||
nsCOMPtr<mozIStorageStatement> mRemoveKeyStatement;
|
||||
nsCOMPtr<mozIStorageStatement> mRemoveOwnerStatement;
|
||||
nsCOMPtr<mozIStorageStatement> mRemoveStorageStatement;
|
||||
nsCOMPtr<mozIStorageStatement> mRemoveTimeRangeStatement;
|
||||
nsCOMPtr<mozIStorageStatement> mRemoveAllStatement;
|
||||
nsCOMPtr<mozIStorageStatement> mGetOfflineExcludedUsageStatement;
|
||||
nsCOMPtr<mozIStorageStatement> mGetFullUsageStatement;
|
||||
|
@ -54,6 +54,7 @@ DIRS += \
|
||||
whatwg \
|
||||
geolocation \
|
||||
localstorage \
|
||||
globalstorage \
|
||||
sessionstorage \
|
||||
storageevent \
|
||||
$(NULL)
|
||||
|
54
dom/tests/mochitest/globalstorage/Makefile.in
Normal file
54
dom/tests/mochitest/globalstorage/Makefile.in
Normal file
@ -0,0 +1,54 @@
|
||||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2008
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Jan Bambas <honzab@firemni.cz>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
relativesrcdir = dom/tests/mochitest/globalstorage
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_TEST_FILES = \
|
||||
test_globalStorageDeleteSinceAPI.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
|
@ -0,0 +1,73 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>globalStorage delete since API test</title>
|
||||
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
globalStorage[window.location.hostname].removeItem("key1");
|
||||
globalStorage[window.location.hostname].removeItem("key2");
|
||||
globalStorage[window.location.hostname].removeItem("key3");
|
||||
globalStorage[window.location.hostname].removeItem("key4");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function doTest()
|
||||
{
|
||||
var since = 0;
|
||||
|
||||
setTimeout('globalStorage[window.location.hostname].key1 = "value1"', 0);
|
||||
setTimeout('globalStorage[window.location.hostname].key2 = "value2"', 100);
|
||||
setTimeout('globalStorage[window.location.hostname].key3 = "value3"', 200);
|
||||
|
||||
// Since now, all added/changed items will be deleted
|
||||
setTimeout(function() {
|
||||
// Now in microseconds...
|
||||
since = (new Date()).getTime() * 1000;
|
||||
}, 300);
|
||||
|
||||
// Rather give the timer chance to move forward, on some systems the
|
||||
// granularity may be too grainy.
|
||||
|
||||
setTimeout('globalStorage[window.location.hostname].key4 = "value4"', 500);
|
||||
setTimeout('globalStorage[window.location.hostname].key1 = "value1-2"', 600);
|
||||
|
||||
setTimeout(function() {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
is(globalStorage[window.location.hostname].length, 4, "Expected 4 items before delete");
|
||||
|
||||
try {
|
||||
var domStorageManager = Components.classes["@mozilla.org/dom/storagemanager;1"]
|
||||
.getService(Components.interfaces.nsIDOMStorageManager);
|
||||
domStorageManager.clearStorageDataSince(since);
|
||||
}
|
||||
catch(ex) {
|
||||
ok(false, ex);
|
||||
}
|
||||
|
||||
todo(globalStorage[window.location.hostname].key1 == null, "key1 deleted (Bug 600366)");
|
||||
is(globalStorage[window.location.hostname].key2, "value2", "key2 left");
|
||||
is(globalStorage[window.location.hostname].key3, "value3", "key3 left");
|
||||
todo(globalStorage[window.location.hostname].key4 == null, "key4 deleted (Bug 600366)");
|
||||
is(globalStorage[window.location.hostname].length, 2, "Expected 2 items after delete");
|
||||
|
||||
cleanup();
|
||||
}, 700);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="doTest();">
|
||||
|
||||
</body>
|
||||
</html>
|
@ -68,6 +68,8 @@ _TEST_FILES = \
|
||||
test_localStorageBase.html \
|
||||
test_localStorageBasePrivateBrowsing.html \
|
||||
test_localStorageBaseSessionOnly.html \
|
||||
test_localStorageDeleteSinceAPI.html \
|
||||
test_localStorageDeleteSinceAPIPrivateBrowsing.html \
|
||||
test_localStorageCookieSettings.html \
|
||||
test_localStorageEnablePref.html \
|
||||
test_localStorageOriginsEquals.html \
|
||||
|
@ -0,0 +1,70 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>localStorage delete since API test</title>
|
||||
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
localStorage.clear();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function doTest()
|
||||
{
|
||||
var since = 0;
|
||||
|
||||
setTimeout('localStorage.key1 = "value1"', 0);
|
||||
setTimeout('localStorage.key2 = "value2"', 100);
|
||||
setTimeout('localStorage.key3 = "value3"', 200);
|
||||
|
||||
// Since now, all added/changed items will be deleted
|
||||
setTimeout(function() {
|
||||
// Now in microseconds...
|
||||
since = (new Date()).getTime() * 1000;
|
||||
}, 300);
|
||||
|
||||
// Rather give the timer chance to move forward, on some systems the
|
||||
// granularity may be too grainy.
|
||||
|
||||
setTimeout('localStorage.key4 = "value4"', 500);
|
||||
setTimeout('localStorage.key1 = "value1-2"', 600);
|
||||
|
||||
setTimeout(function() {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
is(localStorage.length, 4, "Expected 4 items before delete in localStorage");
|
||||
|
||||
try {
|
||||
var domStorageManager = Components.classes["@mozilla.org/dom/storagemanager;1"]
|
||||
.getService(Components.interfaces.nsIDOMStorageManager);
|
||||
domStorageManager.clearStorageDataSince(since);
|
||||
}
|
||||
catch(ex) {
|
||||
ok(false, ex);
|
||||
}
|
||||
|
||||
is(localStorage.key1, null, "key1 deleted (if this fails see bug 600366 first)");
|
||||
is(localStorage.key2, "value2", "key2 left");
|
||||
is(localStorage.key3, "value3", "key3 left");
|
||||
is(localStorage.key4, null, "key4 deleted (if this fails see bug 600366 first)");
|
||||
is(localStorage.length, 2, "Expected 2 items after delete in localStorage");
|
||||
|
||||
cleanup();
|
||||
}, 700);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="doTest();">
|
||||
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,85 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>localStorage delete since API test in Private Browsing</title>
|
||||
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="pbSwitch.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
localStorage.clear();
|
||||
leavePrivateBrowsing();
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function startTest()
|
||||
{
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
if (get_PBSvc())
|
||||
doTest();
|
||||
else
|
||||
ok(true, "No private browsing service, test could not be performed");
|
||||
}
|
||||
|
||||
function doTest()
|
||||
{
|
||||
var since = 0;
|
||||
|
||||
enterPrivateBrowsing();
|
||||
|
||||
setTimeout('localStorage.key1 = "value1"', 0);
|
||||
setTimeout('localStorage.key2 = "value2"', 100);
|
||||
setTimeout('localStorage.key3 = "value3"', 200);
|
||||
|
||||
// Since now, all added/changed items will be deleted
|
||||
setTimeout(function() {
|
||||
// Now in microseconds...
|
||||
since = (new Date()).getTime() * 1000;
|
||||
}, 300);
|
||||
|
||||
// Rather give the timer chance to move forward, on some systems the
|
||||
// granularity may be too grainy.
|
||||
|
||||
setTimeout('localStorage.key4 = "value4"', 500);
|
||||
setTimeout('localStorage.key1 = "value1-2"', 600);
|
||||
|
||||
setTimeout(function() {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
is(localStorage.length, 4, "Expected 4 items before delete in localStorage");
|
||||
|
||||
try {
|
||||
var domStorageManager = Components.classes["@mozilla.org/dom/storagemanager;1"]
|
||||
.getService(Components.interfaces.nsIDOMStorageManager);
|
||||
domStorageManager.clearStorageDataSince(since);
|
||||
}
|
||||
catch(ex) {
|
||||
ok(false, ex);
|
||||
}
|
||||
|
||||
is(localStorage.key1, null, "key1 deleted (if this fails see bug 600366 first)");
|
||||
is(localStorage.key2, "value2", "key2 left");
|
||||
is(localStorage.key3, "value3", "key3 left");
|
||||
is(localStorage.key4, null, "key4 deleted (if this fails see bug 600366 first)");
|
||||
is(localStorage.length, 2, "Expected 2 items after delete in localStorage");
|
||||
|
||||
cleanup();
|
||||
}, 700);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="startTest();">
|
||||
|
||||
</body>
|
||||
</html>
|
@ -53,6 +53,7 @@ _TEST_FILES = \
|
||||
file_https.html \
|
||||
test_sessionStorageBase.html \
|
||||
test_sessionStorageClone.html \
|
||||
test_sessionStorageDeleteSinceAPI.html \
|
||||
test_sessionStorageReplace.html \
|
||||
test_sessionStorageHttpHttps.html \
|
||||
interOriginSlave.js \
|
||||
|
@ -0,0 +1,67 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>sessionStorage delete since API test</title>
|
||||
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
sessionStorage.clear();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function doTest()
|
||||
{
|
||||
var since = 0;
|
||||
|
||||
setTimeout('sessionStorage.key1 = "value1"', 0);
|
||||
setTimeout('sessionStorage.key2 = "value2"', 100);
|
||||
setTimeout('sessionStorage.key3 = "value3"', 200);
|
||||
|
||||
// Since now, all added/changed items will be deleted
|
||||
setTimeout(function() {
|
||||
// Now in microseconds...
|
||||
since = (new Date()).getTime() * 1000;
|
||||
}, 300);
|
||||
|
||||
setTimeout('sessionStorage.key4 = "value4"', 500);
|
||||
setTimeout('sessionStorage.key1 = "value1-2"', 600);
|
||||
|
||||
setTimeout(function() {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
is(sessionStorage.length, 4, "Expected 4 items before delete in sessionStorage");
|
||||
|
||||
try {
|
||||
var domStorageManager = Components.classes["@mozilla.org/dom/storagemanager;1"]
|
||||
.getService(Components.interfaces.nsIDOMStorageManager);
|
||||
domStorageManager.clearStorageDataSince(since);
|
||||
}
|
||||
catch(ex) {
|
||||
ok(false, ex);
|
||||
}
|
||||
|
||||
is(sessionStorage.length, 2, "Expected 2 items after delete in sessionStorage");
|
||||
is(sessionStorage.key1, null, "key1 deleted");
|
||||
is(sessionStorage.key2, "value2", "key2 left");
|
||||
is(sessionStorage.key3, "value3", "key3 left");
|
||||
is(sessionStorage.key4, null, "key4 deleted");
|
||||
|
||||
cleanup();
|
||||
}, 700);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="doTest();">
|
||||
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user