зеркало из https://github.com/mozilla/pjs.git
Bug 455070 - Make sessionStorage object conform the WHATWG spec, r+sr=jst
This commit is contained in:
Родитель
d4e58eb985
Коммит
2b0d93ff16
|
@ -1271,7 +1271,7 @@ SessionStoreService.prototype = {
|
|||
|
||||
for (let i = 0; i < aHistory.count; i++) {
|
||||
let uri = aHistory.getEntryAtIndex(i, false).URI;
|
||||
// sessionStorage is saved per domain (cf. nsDocShell::GetSessionStorageForURI)
|
||||
// sessionStorage is saved per origin (cf. nsDocShell::GetSessionStorageForURI)
|
||||
let domain = uri.spec;
|
||||
try {
|
||||
if (uri.host)
|
||||
|
@ -1295,9 +1295,7 @@ SessionStoreService.prototype = {
|
|||
try {
|
||||
let key = storage.key(j);
|
||||
let item = storage.getItem(key);
|
||||
data[key] = { value: item.value };
|
||||
if (uri.schemeIs("https") && item.secure)
|
||||
data[key].secure = true;
|
||||
data[key] = item;
|
||||
}
|
||||
catch (ex) { /* XXXzeniko this currently throws for secured items (cf. bug 442048) */ }
|
||||
}
|
||||
|
@ -2108,9 +2106,7 @@ SessionStoreService.prototype = {
|
|||
let storage = aDocShell.getSessionStorageForURI(uri);
|
||||
for (let key in aStorageData[url]) {
|
||||
try {
|
||||
storage.setItem(key, aStorageData[url][key].value);
|
||||
if (uri.schemeIs("https"))
|
||||
storage.getItem(key).secure = aStorageData[url][key].secure || false;
|
||||
storage.setItem(key, aStorageData[url][key]);
|
||||
}
|
||||
catch (ex) { Cu.reportError(ex); } // throws e.g. for URIs that can't have sessionStorage
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "nsIDOMNSDocument.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMStorageObsolete.h"
|
||||
#include "nsIDOMStorage.h"
|
||||
#include "nsPIDOMStorage.h"
|
||||
#include "nsIDocumentViewer.h"
|
||||
#include "nsIDocumentLoaderFactory.h"
|
||||
|
@ -853,7 +854,6 @@ NS_INTERFACE_MAP_BEGIN(nsDocShell)
|
|||
NS_INTERFACE_MAP_ENTRY(nsIAuthPromptProvider)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsILoadContext)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDocShell_MOZILLA_1_9_1)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIWebShellServices)
|
||||
NS_INTERFACE_MAP_ENTRY(nsILinkHandler)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIClipboardCommands)
|
||||
|
@ -2143,7 +2143,7 @@ nsDocShell::HistoryPurged(PRInt32 aNumEntries)
|
|||
NS_IMETHODIMP
|
||||
nsDocShell::GetSessionStorageForPrincipal(nsIPrincipal* aPrincipal,
|
||||
PRBool aCreate,
|
||||
nsIDOMStorageObsolete** aStorage)
|
||||
nsIDOMStorage** aStorage)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aStorage);
|
||||
*aStorage = nsnull;
|
||||
|
@ -2151,19 +2151,46 @@ nsDocShell::GetSessionStorageForPrincipal(nsIPrincipal* aPrincipal,
|
|||
if (!aPrincipal)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIURI> codebaseURI;
|
||||
nsresult rv = aPrincipal->GetDomain(getter_AddRefs(codebaseURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!codebaseURI) {
|
||||
rv = aPrincipal->GetURI(getter_AddRefs(codebaseURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
nsresult rv;
|
||||
|
||||
if (!codebaseURI)
|
||||
nsCOMPtr<nsIDocShellTreeItem> topItem;
|
||||
rv = GetSameTypeRootTreeItem(getter_AddRefs(topItem));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (!topItem)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsDocShell* topDocShell = static_cast<nsDocShell*>(topItem.get());
|
||||
if (topDocShell != this)
|
||||
return topDocShell->GetSessionStorageForPrincipal(aPrincipal, aCreate,
|
||||
aStorage);
|
||||
|
||||
nsXPIDLCString origin;
|
||||
rv = aPrincipal->GetOrigin(getter_Copies(origin));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (origin.IsEmpty())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (!mStorages.Get(origin, aStorage) && aCreate) {
|
||||
nsCOMPtr<nsIDOMStorage> newstorage =
|
||||
do_CreateInstance("@mozilla.org/dom/storage;2");
|
||||
if (!newstorage)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsCOMPtr<nsPIDOMStorage> pistorage = do_QueryInterface(newstorage);
|
||||
if (!pistorage)
|
||||
return NS_ERROR_FAILURE;
|
||||
pistorage->InitAsSessionStorage(aPrincipal);
|
||||
|
||||
if (!mStorages.Put(origin, newstorage))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
newstorage.swap(*aStorage);
|
||||
return NS_OK;
|
||||
|
||||
rv = GetSessionStorageForURI(codebaseURI, aCreate, aStorage);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMStorage> piStorage = do_QueryInterface(*aStorage);
|
||||
if (piStorage) {
|
||||
|
@ -2182,7 +2209,7 @@ nsDocShell::GetSessionStorageForPrincipal(nsIPrincipal* aPrincipal,
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetSessionStorageForURI(nsIURI* aURI,
|
||||
nsIDOMStorageObsolete** aStorage)
|
||||
nsIDOMStorage** aStorage)
|
||||
{
|
||||
return GetSessionStorageForURI(aURI, PR_TRUE, aStorage);
|
||||
}
|
||||
|
@ -2190,64 +2217,35 @@ nsDocShell::GetSessionStorageForURI(nsIURI* aURI,
|
|||
nsresult
|
||||
nsDocShell::GetSessionStorageForURI(nsIURI* aURI,
|
||||
PRBool aCreate,
|
||||
nsIDOMStorageObsolete** aStorage)
|
||||
nsIDOMStorage** aStorage)
|
||||
{
|
||||
NS_ENSURE_ARG(aURI);
|
||||
NS_ENSURE_ARG_POINTER(aStorage);
|
||||
|
||||
*aStorage = nsnull;
|
||||
|
||||
nsCOMPtr<nsIURI> innerURI = NS_GetInnermostURI(aURI);
|
||||
NS_ASSERTION(innerURI, "Failed to get innermost URI");
|
||||
if (!innerURI)
|
||||
return NS_ERROR_FAILURE;
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> topItem;
|
||||
nsresult rv = GetSameTypeRootTreeItem(getter_AddRefs(topItem));
|
||||
nsCOMPtr<nsIScriptSecurityManager> securityManager =
|
||||
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// This is terrible hack and should go away along with this whole method.
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
rv = securityManager->GetCodebasePrincipal(aURI, getter_AddRefs(principal));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (!topItem)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsDocShell* topDocShell = static_cast<nsDocShell*>(topItem.get());
|
||||
if (topDocShell != this)
|
||||
return topDocShell->GetSessionStorageForURI(aURI, aCreate, aStorage);
|
||||
|
||||
nsCAutoString currentDomain;
|
||||
rv = innerURI->GetAsciiHost(currentDomain);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (currentDomain.IsEmpty())
|
||||
return NS_OK;
|
||||
|
||||
if (!mStorages.Get(currentDomain, aStorage) && aCreate) {
|
||||
nsCOMPtr<nsIDOMStorageObsolete> newstorage =
|
||||
do_CreateInstance("@mozilla.org/dom/storage;1");
|
||||
if (!newstorage)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsCOMPtr<nsPIDOMStorage> pistorage = do_QueryInterface(newstorage);
|
||||
if (!pistorage)
|
||||
return NS_ERROR_FAILURE;
|
||||
pistorage->InitAsSessionStorage(aURI);
|
||||
|
||||
if (!mStorages.Put(currentDomain, newstorage))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
newstorage.swap(*aStorage);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return GetSessionStorageForPrincipal(principal, aCreate, aStorage);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocShell::AddSessionStorage(const nsACString& aDomain,
|
||||
nsIDOMStorageObsolete* aStorage)
|
||||
nsDocShell::AddSessionStorage(nsIPrincipal* aPrincipal,
|
||||
nsIDOMStorage* aStorage)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aStorage);
|
||||
|
||||
if (aDomain.IsEmpty())
|
||||
if (!aPrincipal)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> topItem;
|
||||
|
@ -2258,15 +2256,23 @@ nsDocShell::AddSessionStorage(const nsACString& aDomain,
|
|||
if (topItem) {
|
||||
nsCOMPtr<nsIDocShell> topDocShell = do_QueryInterface(topItem);
|
||||
if (topDocShell == this) {
|
||||
nsXPIDLCString origin;
|
||||
rv = aPrincipal->GetOrigin(getter_Copies(origin));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (origin.IsEmpty())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Do not replace an existing session storage.
|
||||
if (mStorages.GetWeak(aDomain))
|
||||
if (mStorages.GetWeak(origin))
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
if (!mStorages.Put(aDomain, aStorage))
|
||||
if (!mStorages.Put(origin, aStorage))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
else {
|
||||
return topDocShell->AddSessionStorage(aDomain, aStorage);
|
||||
return topDocShell->AddSessionStorage(aPrincipal, aStorage);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -213,7 +213,6 @@ class nsDocShell : public nsDocLoader,
|
|||
public nsIAuthPromptProvider,
|
||||
public nsIObserver,
|
||||
public nsILoadContext,
|
||||
public nsIDocShell_MOZILLA_1_9_1,
|
||||
public nsIWebShellServices,
|
||||
public nsILinkHandler,
|
||||
public nsIClipboardCommands
|
||||
|
@ -248,7 +247,6 @@ public:
|
|||
NS_DECL_NSIAUTHPROMPTPROVIDER
|
||||
NS_DECL_NSIOBSERVER
|
||||
NS_DECL_NSILOADCONTEXT
|
||||
NS_DECL_NSIDOCSHELL_MOZILLA_1_9_1
|
||||
NS_DECL_NSICLIPBOARDCOMMANDS
|
||||
NS_DECL_NSIWEBSHELLSERVICES
|
||||
|
||||
|
@ -606,7 +604,7 @@ protected:
|
|||
|
||||
nsresult GetSessionStorageForURI(nsIURI* aURI,
|
||||
PRBool create,
|
||||
nsIDOMStorageObsolete** aStorage);
|
||||
nsIDOMStorage** aStorage);
|
||||
|
||||
// helpers for executing commands
|
||||
nsresult GetControllerForCommand(const char *inCommand,
|
||||
|
@ -630,10 +628,13 @@ protected:
|
|||
};
|
||||
|
||||
// hash of session storages, keyed by domain
|
||||
nsInterfaceHashtable<nsCStringHashKey, nsIDOMStorageObsolete> mStorages;
|
||||
nsIntRect mBounds; // Dimensions of the docshell
|
||||
nsInterfaceHashtable<nsCStringHashKey, nsIDOMStorage> mStorages;
|
||||
|
||||
// Dimensions of the docshell
|
||||
nsIntRect mBounds;
|
||||
nsString mName;
|
||||
nsString mTitle;
|
||||
|
||||
/**
|
||||
* Content-Type Hint of the most-recently initiated load. Used for
|
||||
* session history entries.
|
||||
|
|
|
@ -66,10 +66,10 @@ interface nsIRequest;
|
|||
interface nsISHEntry;
|
||||
interface nsILayoutHistoryState;
|
||||
interface nsISecureBrowserUI;
|
||||
interface nsIDOMStorageObsolete;
|
||||
interface nsIDOMStorage;
|
||||
interface nsIPrincipal;
|
||||
|
||||
[scriptable, uuid(f100ede8-fa36-4ed2-99b2-71a3b94f9a70)]
|
||||
[scriptable, uuid(3156f677-f444-4c3e-a47f-b47e568eafd6)]
|
||||
interface nsIDocShell : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -439,15 +439,25 @@ interface nsIDocShell : nsISupports
|
|||
*
|
||||
* @param uri the uri of the storage object to retrieve
|
||||
*/
|
||||
nsIDOMStorageObsolete getSessionStorageForURI(in nsIURI uri);
|
||||
nsIDOMStorage getSessionStorageForURI(in nsIURI uri);
|
||||
|
||||
/*
|
||||
* Retrieves the WebApps session storage object for the supplied principal.
|
||||
*
|
||||
* @param principal returns a storage for this principal
|
||||
* @param create If true and a session storage object doesn't
|
||||
* already exist, a new one will be created.
|
||||
*/
|
||||
nsIDOMStorage getSessionStorageForPrincipal(in nsIPrincipal principal,
|
||||
in boolean create);
|
||||
|
||||
/*
|
||||
* Add a WebApps session storage object to the docshell.
|
||||
*
|
||||
* @param domain the domain the storage object is associated with
|
||||
* @param principal the principal the storage object is associated with
|
||||
* @param storage the storage object to add
|
||||
*/
|
||||
void addSessionStorage(in ACString aDomain, in nsIDOMStorageObsolete storage);
|
||||
void addSessionStorage(in nsIPrincipal principal, in nsIDOMStorage storage);
|
||||
|
||||
/**
|
||||
* Gets the channel for the currently loaded document, if any.
|
||||
|
@ -489,17 +499,3 @@ interface nsIDocShell : nsISupports
|
|||
**/
|
||||
attribute boolean isOffScreenBrowser;
|
||||
};
|
||||
|
||||
[scriptable, uuid(460ba822-e664-4c38-9b08-98d2736473d7)]
|
||||
interface nsIDocShell_MOZILLA_1_9_1 : nsISupports
|
||||
{
|
||||
/*
|
||||
* Retrieves the WebApps session storage object for the supplied principal.
|
||||
*
|
||||
* @param principal returns a storage for this principal
|
||||
* @param create If true and a session storage object doesn't
|
||||
* already exist, a new one will be created.
|
||||
*/
|
||||
nsIDOMStorageObsolete getSessionStorageForPrincipal(in nsIPrincipal principal,
|
||||
in boolean create);
|
||||
};
|
||||
|
|
|
@ -6772,15 +6772,14 @@ nsGlobalWindow::GetDocument(nsIDOMDocumentView ** aDocumentView)
|
|||
//*****************************************************************************
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalWindow::GetSessionStorage(nsIDOMStorageObsolete ** aSessionStorage)
|
||||
nsGlobalWindow::GetSessionStorage(nsIDOMStorage ** aSessionStorage)
|
||||
{
|
||||
FORWARD_TO_INNER(GetSessionStorage, (aSessionStorage), NS_ERROR_UNEXPECTED);
|
||||
|
||||
*aSessionStorage = nsnull;
|
||||
|
||||
nsIPrincipal *principal = GetPrincipal();
|
||||
nsCOMPtr<nsIDocShell_MOZILLA_1_9_1> docShell =
|
||||
do_QueryInterface(GetDocShell());
|
||||
nsIDocShell* docShell = GetDocShell();
|
||||
|
||||
if (!principal || !docShell) {
|
||||
return NS_OK;
|
||||
|
@ -6986,10 +6985,9 @@ nsGlobalWindow::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
|
||||
principal = GetPrincipal();
|
||||
if (!aData) {
|
||||
nsCOMPtr<nsIDocShell_MOZILLA_1_9_1> docShell =
|
||||
do_QueryInterface(GetDocShell());
|
||||
nsIDocShell* docShell = GetDocShell();
|
||||
if (principal && docShell) {
|
||||
nsCOMPtr<nsIDOMStorageObsolete> storage;
|
||||
nsCOMPtr<nsIDOMStorage> storage;
|
||||
docShell->GetSessionStorageForPrincipal(principal,
|
||||
PR_FALSE,
|
||||
getter_AddRefs(storage));
|
||||
|
@ -7083,7 +7081,7 @@ FirePendingStorageEvents(const nsAString& aKey, PRBool aData, void *userArg)
|
|||
{
|
||||
nsGlobalWindow *win = static_cast<nsGlobalWindow *>(userArg);
|
||||
|
||||
nsCOMPtr<nsIDOMStorageObsolete> storage;
|
||||
nsCOMPtr<nsIDOMStorage> storage;
|
||||
win->GetSessionStorage(getter_AddRefs(storage));
|
||||
|
||||
if (storage) {
|
||||
|
|
|
@ -49,13 +49,13 @@ interface nsIDOMStorageObsolete;
|
|||
interface nsIDOMStorage;
|
||||
interface nsIDOMStorageList;
|
||||
|
||||
[scriptable, uuid(390FBF21-36F5-4516-B3F2-9D1232718C69)]
|
||||
[scriptable, uuid(A44581FE-DD9B-4fd7-9893-00C4AB43F12E)]
|
||||
interface nsIDOMStorageWindow : nsISupports
|
||||
{
|
||||
/**
|
||||
* Session storage for the current browsing context.
|
||||
*/
|
||||
readonly attribute nsIDOMStorageObsolete sessionStorage;
|
||||
readonly attribute nsIDOMStorage sessionStorage;
|
||||
|
||||
/**
|
||||
* Global storage, accessible by domain.
|
||||
|
|
|
@ -48,23 +48,23 @@ class nsIURI;
|
|||
class nsIPrincipal;
|
||||
|
||||
#define NS_PIDOMSTORAGE_IID \
|
||||
{ 0x3231d539, 0xdd51, 0x4451, \
|
||||
{ 0xba, 0xdc, 0xf7, 0x72, 0xf5, 0xda, 0x1c, 0x8a } }
|
||||
{ 0x5ffbee8d, 0x9a86, 0x4a57, \
|
||||
{ 0x8c, 0x63, 0x76, 0x56, 0x18, 0x9c, 0xb2, 0xbc } }
|
||||
|
||||
class nsPIDOMStorage : public nsISupports
|
||||
{
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_PIDOMSTORAGE_IID)
|
||||
|
||||
virtual nsresult InitAsSessionStorage(nsIPrincipal *aPrincipal) = 0;
|
||||
virtual nsresult InitAsLocalStorage(nsIPrincipal *aPrincipal) = 0;
|
||||
virtual nsresult InitAsGlobalStorage(const nsACString &aDomainDemanded) = 0;
|
||||
virtual nsresult InitAsSessionStorage(nsIURI* aURI) = 0;
|
||||
|
||||
virtual already_AddRefed<nsIDOMStorageObsolete> Clone() = 0;
|
||||
virtual already_AddRefed<nsIDOMStorage> Clone() = 0;
|
||||
|
||||
virtual nsTArray<nsString> *GetKeys() = 0;
|
||||
|
||||
virtual const nsCString &Domain() = 0;
|
||||
virtual nsIPrincipal* Principal() = 0;
|
||||
virtual PRBool CanAccess(nsIPrincipal *aPrincipal) = 0;
|
||||
};
|
||||
|
||||
|
|
|
@ -516,10 +516,17 @@ NS_NewDOMStorage(nsISupports* aOuter, REFNSIID aIID, void** aResult)
|
|||
if (!storage)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(storage);
|
||||
*aResult = storage;
|
||||
return storage->QueryInterface(aIID, aResult);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
NS_IMETHODIMP
|
||||
NS_NewDOMStorage2(nsISupports* aOuter, REFNSIID aIID, void** aResult)
|
||||
{
|
||||
nsDOMStorage2* storage = new nsDOMStorage2();
|
||||
if (!storage)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
return storage->QueryInterface(aIID, aResult);
|
||||
}
|
||||
|
||||
nsDOMStorage::nsDOMStorage()
|
||||
|
@ -533,6 +540,20 @@ nsDOMStorage::nsDOMStorage()
|
|||
nsDOMStorageManager::gStorageManager->AddToStoragesHash(this);
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
CopyStorageItems(nsSessionStorageEntry* aEntry, void* userArg)
|
||||
{
|
||||
nsDOMStorage* newstorage = static_cast<nsDOMStorage*>(userArg);
|
||||
|
||||
newstorage->SetItem(aEntry->GetKey(), aEntry->mItem->GetValueInternal());
|
||||
|
||||
if (aEntry->mItem->IsSecure()) {
|
||||
newstorage->SetSecure(aEntry->GetKey(), PR_TRUE);
|
||||
}
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
nsDOMStorage::nsDOMStorage(nsDOMStorage& aThat)
|
||||
: mUseDB(PR_FALSE) // Any clone is not using the database
|
||||
, mSessionOnly(PR_TRUE)
|
||||
|
@ -544,6 +565,8 @@ nsDOMStorage::nsDOMStorage(nsDOMStorage& aThat)
|
|||
#endif
|
||||
{
|
||||
mItems.Init(8);
|
||||
aThat.mItems.EnumerateEntries(CopyStorageItems, this);
|
||||
|
||||
if (nsDOMStorageManager::gStorageManager)
|
||||
nsDOMStorageManager::gStorageManager->AddToStoragesHash(this);
|
||||
}
|
||||
|
@ -554,6 +577,29 @@ nsDOMStorage::~nsDOMStorage()
|
|||
nsDOMStorageManager::gStorageManager->RemoveFromStoragesHash(this);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMStorage::InitAsSessionStorage(nsIPrincipal *aPrincipal)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = aPrincipal->GetURI(getter_AddRefs(uri));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIURI> innerUri = NS_GetInnermostURI(uri);
|
||||
if (!innerUri)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
innerUri->GetAsciiHost(mDomain);
|
||||
|
||||
#ifdef MOZ_STORAGE
|
||||
mUseDB = PR_FALSE;
|
||||
mScopeDBKey.Truncate();
|
||||
mQuotaDomainDBKey.Truncate();
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMStorage::InitAsLocalStorage(nsIPrincipal *aPrincipal)
|
||||
{
|
||||
|
@ -615,20 +661,6 @@ nsDOMStorage::InitAsGlobalStorage(const nsACString &aDomainDemanded)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMStorage::InitAsSessionStorage(nsIURI* aURI)
|
||||
{
|
||||
nsCAutoString domain;
|
||||
aURI->GetAsciiHost(domain);
|
||||
mDomain = domain;
|
||||
#ifdef MOZ_STORAGE
|
||||
mUseDB = PR_FALSE;
|
||||
mScopeDBKey.Truncate();
|
||||
mQuotaDomainDBKey.Truncate();
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//static
|
||||
PRBool
|
||||
nsDOMStorage::CanUseStorage(PRPackedBool* aSessionOnly)
|
||||
|
@ -1240,41 +1272,11 @@ nsDOMStorage::ClearAll()
|
|||
mItemsCached = PR_FALSE;
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
CopyStorageItems(nsSessionStorageEntry* aEntry, void* userArg)
|
||||
{
|
||||
nsDOMStorage* newstorage = static_cast<nsDOMStorage*>(userArg);
|
||||
|
||||
newstorage->SetItem(aEntry->GetKey(), aEntry->mItem->GetValueInternal());
|
||||
|
||||
if (aEntry->mItem->IsSecure()) {
|
||||
newstorage->SetSecure(aEntry->GetKey(), PR_TRUE);
|
||||
}
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDOMStorageObsolete>
|
||||
already_AddRefed<nsIDOMStorage>
|
||||
nsDOMStorage::Clone()
|
||||
{
|
||||
if (UseDB()) {
|
||||
NS_ERROR("Uh, don't clone a global or local storage object.");
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsDOMStorage* storage = new nsDOMStorage(*this);
|
||||
if (!storage)
|
||||
return nsnull;
|
||||
|
||||
mItems.EnumerateEntries(CopyStorageItems, storage);
|
||||
|
||||
NS_ADDREF(storage);
|
||||
|
||||
if (nsDOMStorageManager::gStorageManager)
|
||||
nsDOMStorageManager::gStorageManager->AddToStoragesHash(storage);
|
||||
|
||||
return storage;
|
||||
NS_ASSERTION(PR_FALSE, "Old DOMStorage doesn't implement cloning");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
struct KeysArrayBuilderStruct
|
||||
|
@ -1309,10 +1311,10 @@ nsDOMStorage::GetKeys()
|
|||
return keystruct.keys;
|
||||
}
|
||||
|
||||
const nsCString &
|
||||
nsDOMStorage::Domain()
|
||||
nsIPrincipal*
|
||||
nsDOMStorage::Principal()
|
||||
{
|
||||
return mDomain;
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -1387,6 +1389,27 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMStorage2)
|
|||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Storage)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
nsDOMStorage2::nsDOMStorage2()
|
||||
{
|
||||
}
|
||||
|
||||
nsDOMStorage2::nsDOMStorage2(nsDOMStorage2& aThat)
|
||||
{
|
||||
mStorage = new nsDOMStorage(*aThat.mStorage.get());
|
||||
mPrincipal = aThat.mPrincipal;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMStorage2::InitAsSessionStorage(nsIPrincipal *aPrincipal)
|
||||
{
|
||||
mStorage = new nsDOMStorage();
|
||||
if (!mStorage)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mPrincipal = aPrincipal;
|
||||
return mStorage->InitAsSessionStorage(aPrincipal);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMStorage2::InitAsLocalStorage(nsIPrincipal *aPrincipal)
|
||||
{
|
||||
|
@ -1405,23 +1428,16 @@ nsDOMStorage2::InitAsGlobalStorage(const nsACString &aDomainDemanded)
|
|||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMStorage2::InitAsSessionStorage(nsIURI* aURI)
|
||||
{
|
||||
mStorage = new nsDOMStorage();
|
||||
if (!mStorage)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
return mStorage->InitAsSessionStorage(aURI);
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDOMStorageObsolete>
|
||||
already_AddRefed<nsIDOMStorage>
|
||||
nsDOMStorage2::Clone()
|
||||
{
|
||||
// XXX: this will need to be fixed before sessionStorage is moved
|
||||
// to nsIDOMStorage.
|
||||
NS_ASSERTION(PR_FALSE, "Cannot clone nsDOMStorage2");
|
||||
return nsnull;
|
||||
nsDOMStorage2* storage = new nsDOMStorage2(*this);
|
||||
if (!storage)
|
||||
return nsnull;
|
||||
|
||||
NS_ADDREF(storage);
|
||||
|
||||
return storage;
|
||||
}
|
||||
|
||||
nsTArray<nsString> *
|
||||
|
@ -1430,10 +1446,10 @@ nsDOMStorage2::GetKeys()
|
|||
return mStorage->GetKeys();
|
||||
}
|
||||
|
||||
const nsCString &
|
||||
nsDOMStorage2::Domain()
|
||||
nsIPrincipal*
|
||||
nsDOMStorage2::Principal()
|
||||
{
|
||||
return mStorage->Domain();
|
||||
return mPrincipal;
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
|
|
@ -140,12 +140,12 @@ public:
|
|||
nsresult Clear();
|
||||
|
||||
// nsPIDOMStorage
|
||||
virtual nsresult InitAsSessionStorage(nsIPrincipal *aPrincipal);
|
||||
virtual nsresult InitAsLocalStorage(nsIPrincipal *aPrincipal);
|
||||
virtual nsresult InitAsGlobalStorage(const nsACString &aDomainDemanded);
|
||||
virtual nsresult InitAsSessionStorage(nsIURI* aURI);
|
||||
virtual already_AddRefed<nsIDOMStorageObsolete> Clone();
|
||||
virtual already_AddRefed<nsIDOMStorage> Clone();
|
||||
virtual nsTArray<nsString> *GetKeys();
|
||||
virtual const nsCString &Domain();
|
||||
virtual nsIPrincipal* Principal();
|
||||
virtual PRBool CanAccess(nsIPrincipal *aPrincipal);
|
||||
|
||||
// If true, the contents of the storage should be stored in the
|
||||
|
@ -267,15 +267,18 @@ public:
|
|||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDOMStorage2, nsIDOMStorage)
|
||||
|
||||
nsDOMStorage2(nsDOMStorage2& aThat);
|
||||
nsDOMStorage2();
|
||||
|
||||
NS_DECL_NSIDOMSTORAGE
|
||||
|
||||
// nsPIDOMStorage
|
||||
virtual nsresult InitAsSessionStorage(nsIPrincipal *aPrincipal);
|
||||
virtual nsresult InitAsLocalStorage(nsIPrincipal *aPrincipal);
|
||||
virtual nsresult InitAsGlobalStorage(const nsACString &aDomainDemanded);
|
||||
virtual nsresult InitAsSessionStorage(nsIURI* aURI);
|
||||
virtual already_AddRefed<nsIDOMStorageObsolete> Clone();
|
||||
virtual already_AddRefed<nsIDOMStorage> Clone();
|
||||
virtual nsTArray<nsString> *GetKeys();
|
||||
virtual const nsCString &Domain();
|
||||
virtual nsIPrincipal* Principal();
|
||||
virtual PRBool CanAccess(nsIPrincipal *aPrincipal);
|
||||
|
||||
private:
|
||||
|
@ -432,6 +435,9 @@ protected:
|
|||
NS_IMETHODIMP
|
||||
NS_NewDOMStorage(nsISupports* aOuter, REFNSIID aIID, void** aResult);
|
||||
|
||||
NS_IMETHODIMP
|
||||
NS_NewDOMStorage2(nsISupports* aOuter, REFNSIID aIID, void** aResult);
|
||||
|
||||
nsresult
|
||||
NS_NewDOMStorageList(nsIDOMStorageList** aResult);
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ DIRS += \
|
|||
whatwg \
|
||||
geolocation \
|
||||
localstorage \
|
||||
sessionstorage \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
#
|
||||
# ***** 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 Foundation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2007
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# 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/sessionstorage
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_TEST_FILES = \
|
||||
frameReplace.html \
|
||||
frameEqual.html \
|
||||
frameNotEqual.html \
|
||||
test_sessionStorageBase.html \
|
||||
test_sessionStorageClone.html \
|
||||
test_sessionStorageReplace.html \
|
||||
interOriginSlave.js \
|
||||
interOriginTest.js \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
|
|
@ -0,0 +1,47 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>slave for sessionStorage test</title>
|
||||
|
||||
<script type="text/javascript" src="interOriginSlave.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
var currentStep = 2;
|
||||
|
||||
function doStep()
|
||||
{
|
||||
switch (currentStep)
|
||||
{
|
||||
case 2:
|
||||
is(sessionStorage.getItem("A"), "1", "A is 1 in the slave");
|
||||
is(sessionStorage.getItem("B"), "2", "B is 2 in the slave");
|
||||
is(sessionStorage.length, 2, "Num of items is 2");
|
||||
|
||||
sessionStorage.setItem("C", "3");
|
||||
is(sessionStorage.getItem("C"), "3", "C is 3 in the slave");
|
||||
is(sessionStorage.length, 3, "Num of items is 3");
|
||||
break;
|
||||
|
||||
case 4:
|
||||
is(sessionStorage.getItem("A"), "1", "A is 1 in the slave");
|
||||
is(sessionStorage.getItem("B"), "2", "B is 2 in the slave");
|
||||
is(sessionStorage.getItem("C"), "3", "C is 3 in the slave");
|
||||
is(sessionStorage.length, 3, "Num of items is 3");
|
||||
break;
|
||||
|
||||
case 6:
|
||||
return finishTest();
|
||||
}
|
||||
|
||||
++currentStep;
|
||||
++currentStep;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="postMsg('frame loaded');">
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,43 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>slave for sessionStorage test</title>
|
||||
|
||||
<script type="text/javascript" src="interOriginSlave.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
var currentStep = 2;
|
||||
|
||||
function doStep()
|
||||
{
|
||||
switch (currentStep)
|
||||
{
|
||||
case 2:
|
||||
is(sessionStorage.length, 0, "Num of items is 0");
|
||||
|
||||
sessionStorage.setItem("C", "3");
|
||||
is(sessionStorage.getItem("C"), "3", "C is 3 in the slave");
|
||||
is(sessionStorage.length, 1, "Num of items is 1");
|
||||
break;
|
||||
|
||||
case 4:
|
||||
is(sessionStorage.getItem("C"), "3", "C is 3 in the slave");
|
||||
is(sessionStorage.length, 1, "Num of items is 1");
|
||||
break;
|
||||
|
||||
case 6:
|
||||
return finishTest();
|
||||
}
|
||||
|
||||
++currentStep;
|
||||
++currentStep;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="postMsg('frame loaded');">
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,75 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>sessionStorage replace frame</title>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var shell;
|
||||
|
||||
function ok(a, message)
|
||||
{
|
||||
if (!a)
|
||||
shell.postMessage("FAILURE: " + message, "http://localhost:8888");
|
||||
else
|
||||
shell.postMessage(message, "http://localhost:8888");
|
||||
}
|
||||
|
||||
function is(a, b, message)
|
||||
{
|
||||
if (a != b)
|
||||
shell.postMessage("FAILURE: " + message + ", expected "+b+" got "+a, "http://localhost:8888");
|
||||
else
|
||||
shell.postMessage(message + ", expected "+b+" got "+a, "http://localhost:8888");
|
||||
}
|
||||
|
||||
function doTest()
|
||||
{
|
||||
var query = location.search.substring(1);
|
||||
var queries = query.split("&");
|
||||
|
||||
var action = queries[0];
|
||||
shell = queries[1];
|
||||
switch (shell)
|
||||
{
|
||||
case "frame":
|
||||
shell = parent;
|
||||
break;
|
||||
case "window":
|
||||
shell = opener;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case "init":
|
||||
sessionStorage.setItem("A", "1");
|
||||
sessionStorage.setItem("B", "2");
|
||||
sessionStorage.setItem("C", "3");
|
||||
is(sessionStorage.getItem("A"), "1", "'A' is '1'");
|
||||
is(sessionStorage.getItem("B"), "2", "'A' is '2'");
|
||||
is(sessionStorage.getItem("C"), "3", "'A' is '3'");
|
||||
break;
|
||||
|
||||
case "check":
|
||||
is(sessionStorage.getItem("A"), null, "'A' is null");
|
||||
is(sessionStorage.getItem("B"), null, "'A' is null");
|
||||
is(sessionStorage.getItem("C"), null, "'A' is null");
|
||||
break;
|
||||
|
||||
case "clean":
|
||||
is(sessionStorage.getItem("A"), "1", "'A' is '1'");
|
||||
is(sessionStorage.getItem("B"), "2", "'A' is '2'");
|
||||
is(sessionStorage.getItem("C"), "3", "'A' is '3'");
|
||||
sessionStorage.clear();
|
||||
break;
|
||||
}
|
||||
|
||||
shell.postMessage(action + "_done", "http://localhost:8888");
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body onload="doTest();">
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,42 @@
|
|||
function postMsg(message)
|
||||
{
|
||||
opener.postMessage(message, "http://localhost:8888");
|
||||
}
|
||||
|
||||
window.addEventListener("message", onMessageReceived, false);
|
||||
|
||||
function onMessageReceived(event)
|
||||
{
|
||||
//alert("slave got event: "+event.data);
|
||||
if (event.data == "step") {
|
||||
if (doStep())
|
||||
postMsg("perf");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
postMsg("Invalid message");
|
||||
}
|
||||
|
||||
function ok(a, message)
|
||||
{
|
||||
if (!a)
|
||||
postMsg("FAILURE: " + message);
|
||||
else
|
||||
postMsg(message);
|
||||
}
|
||||
|
||||
function is(a, b, message)
|
||||
{
|
||||
if (a != b)
|
||||
postMsg("FAILURE: " + message + ", expected "+b+" got "+a);
|
||||
else
|
||||
postMsg(message + ", expected "+b+" got "+a);
|
||||
}
|
||||
|
||||
function finishTest()
|
||||
{
|
||||
sessionStorage.clear();
|
||||
postMsg("done");
|
||||
return false;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
var slaveLoadsPending = 1;
|
||||
|
||||
var slaveOrigin = "";
|
||||
var slave = null;
|
||||
|
||||
var failureRegExp = new RegExp("^FAILURE");
|
||||
const slavePath = "/tests/dom/tests/mochitest/sessionstorage/";
|
||||
|
||||
window.addEventListener("message", onMessageReceived, false);
|
||||
|
||||
function onMessageReceived(event)
|
||||
{
|
||||
//alert("master got event: "+event.data);
|
||||
switch (event.data)
|
||||
{
|
||||
// Indication of the frame onload event
|
||||
case "frame loaded":
|
||||
if (--slaveLoadsPending)
|
||||
break;
|
||||
|
||||
// Just fall through...
|
||||
|
||||
// Indication of successfully finished step of a test
|
||||
case "perf":
|
||||
// We called doStep before the frame was load
|
||||
if (event.data == "perf")
|
||||
doStep();
|
||||
|
||||
slave.postMessage("step", slaveOrigin);
|
||||
break;
|
||||
|
||||
// Indication of all test parts finish (from any of the frames)
|
||||
case "done":
|
||||
sessionStorage.clear();
|
||||
slaveLoadsPending = 1;
|
||||
doNextTest();
|
||||
break;
|
||||
|
||||
// Any other message indicates error or succes message of a test
|
||||
default:
|
||||
SimpleTest.ok(!event.data.match(failureRegExp), event.data);
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>sessionStorage basic 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">
|
||||
|
||||
var INDEX_SIZE_ERR = 1;
|
||||
|
||||
function checkException(func, exc)
|
||||
{
|
||||
var exceptionThrew = false;
|
||||
try {
|
||||
func();
|
||||
}
|
||||
catch (ex) {
|
||||
exceptionThrew = true;
|
||||
is(ex.code, exc, "Expected "+exc+" exception");
|
||||
}
|
||||
ok(exceptionThrew, "Exception "+exc+" threw");
|
||||
}
|
||||
|
||||
function startTest()
|
||||
{
|
||||
// Initially check the sessionStorage is empty
|
||||
is(sessionStorage.length, 0, "The storage is empty [1]");
|
||||
checkException(function() {sessionStorage.key(0);}, INDEX_SIZE_ERR);
|
||||
checkException(function() {sessionStorage.key(-1);}, INDEX_SIZE_ERR);
|
||||
checkException(function() {sessionStorage.key(1);}, INDEX_SIZE_ERR);
|
||||
is(sessionStorage.getItem("nonexisting"), null, "Nonexisting item is null (getItem())");
|
||||
is(sessionStorage["nonexisting"], null, "Nonexisting item is null (array access)");
|
||||
is(sessionStorage.nonexisting, null, "Nonexisting item is null (property access)");
|
||||
sessionStorage.removeItem("nonexisting"); // Just check there is no exception
|
||||
|
||||
is(typeof sessionStorage.getItem("nonexisting"), "object", "getItem('nonexisting') is object");
|
||||
is(typeof sessionStorage["nonexisting"], "object", "['nonexisting'] is object");
|
||||
is(typeof sessionStorage.nonexisting, "object", "nonexisting is object");
|
||||
is(typeof sessionStorage.getItem("nonexisting2"), "object", "getItem('nonexisting2') is object");
|
||||
is(typeof sessionStorage["nonexisting2"], "object", "['nonexisting2'] is object");
|
||||
is(typeof sessionStorage.nonexisting2, "object", "nonexisting2 is object");
|
||||
|
||||
// add an empty-value key
|
||||
sessionStorage.setItem("empty", "");
|
||||
is(sessionStorage.getItem("empty"), "", "Empty value (getItem())");
|
||||
is(sessionStorage["empty"], "", "Empty value (array access)");
|
||||
is(sessionStorage.empty, "", "Empty value (property access)");
|
||||
is(typeof sessionStorage.getItem("empty"), "string", "getItem('empty') is string");
|
||||
is(typeof sessionStorage["empty"], "string", "['empty'] is string");
|
||||
is(typeof sessionStorage.empty, "string", "empty is string");
|
||||
sessionStorage.removeItem("empty");
|
||||
is(sessionStorage.length, 0, "The storage has no keys");
|
||||
is(sessionStorage.getItem("empty"), null, "empty item is null (getItem())");
|
||||
is(sessionStorage["empty"], null, "empty item is null (array access)");
|
||||
is(sessionStorage.empty, null, "empty item is null (property access)");
|
||||
is(typeof sessionStorage.getItem("empty"), "object", "getItem('empty') is object");
|
||||
is(typeof sessionStorage["empty"], "object", "['empty'] is object");
|
||||
is(typeof sessionStorage.empty, "object", "empty is object");
|
||||
|
||||
// add one key, check it is there
|
||||
sessionStorage.setItem("key1", "value1");
|
||||
is(sessionStorage.length, 1, "The storage has one key-value pair");
|
||||
is(sessionStorage.key(0), "key1");
|
||||
checkException(function() {sessionStorage.key(-1);}, INDEX_SIZE_ERR);
|
||||
checkException(function() {sessionStorage.key(1);}, INDEX_SIZE_ERR);
|
||||
|
||||
// check all access method give the correct result
|
||||
// and are of the correct type
|
||||
is(sessionStorage.getItem("key1"), "value1", "getItem('key1') == value1");
|
||||
is(sessionStorage["key1"], "value1", "['key1'] == value1");
|
||||
is(sessionStorage.key1, "value1", "key1 == value1");
|
||||
|
||||
is(typeof sessionStorage.getItem("key1"), "string", "getItem('key1') is string");
|
||||
is(typeof sessionStorage["key1"], "string", "['key1'] is string");
|
||||
is(typeof sessionStorage.key1, "string", "key1 is string");
|
||||
|
||||
// remove the previously added key and check the storage is empty
|
||||
sessionStorage.removeItem("key1");
|
||||
is(sessionStorage.length, 0, "The storage is empty [2]");
|
||||
checkException(function() {sessionStorage.key(0);}, INDEX_SIZE_ERR);
|
||||
is(sessionStorage.getItem("key1"), null, "\'key1\' removed");
|
||||
|
||||
is(typeof sessionStorage.getItem("key1"), "object", "getItem('key1') is object");
|
||||
is(typeof sessionStorage["key1"], "object", "['key1'] is object");
|
||||
is(typeof sessionStorage.key1, "object", "key1 is object");
|
||||
|
||||
// add one key, check it is there
|
||||
sessionStorage.setItem("key1", "value1");
|
||||
is(sessionStorage.length, 1, "The storage has one key-value pair");
|
||||
is(sessionStorage.key(0), "key1");
|
||||
is(sessionStorage.getItem("key1"), "value1");
|
||||
|
||||
// add a second key
|
||||
sessionStorage.setItem("key2", "value2");
|
||||
is(sessionStorage.length, 2, "The storage has two key-value pairs");
|
||||
is(sessionStorage.key(1), "key1"); // This test might not be accurate because order is not preserved
|
||||
is(sessionStorage.key(0), "key2");
|
||||
is(sessionStorage.getItem("key1"), "value1");
|
||||
is(sessionStorage.getItem("key2"), "value2");
|
||||
|
||||
// change the second key
|
||||
sessionStorage.setItem("key2", "value2-2");
|
||||
is(sessionStorage.length, 2, "The storage has two key-value pairs");
|
||||
is(sessionStorage.key(1), "key1"); // After key value changes the order must be preserved
|
||||
is(sessionStorage.key(0), "key2");
|
||||
checkException(function() {sessionStorage.key(-1);}, INDEX_SIZE_ERR);
|
||||
checkException(function() {sessionStorage.key(2);}, INDEX_SIZE_ERR);
|
||||
is(sessionStorage.getItem("key1"), "value1");
|
||||
is(sessionStorage.getItem("key2"), "value2-2");
|
||||
|
||||
// change the first key
|
||||
sessionStorage.setItem("key1", "value1-2");
|
||||
is(sessionStorage.length, 2, "The storage has two key-value pairs");
|
||||
is(sessionStorage.key(1), "key1"); // After key value changes the order must be preserved
|
||||
is(sessionStorage.key(0), "key2");
|
||||
checkException(function() {sessionStorage.key(-1);}, INDEX_SIZE_ERR);
|
||||
checkException(function() {sessionStorage.key(2);}, INDEX_SIZE_ERR);
|
||||
is(sessionStorage.getItem("key1"), "value1-2");
|
||||
is(sessionStorage.getItem("key2"), "value2-2");
|
||||
|
||||
// remove the second key
|
||||
sessionStorage.removeItem("key2");
|
||||
is(sessionStorage.length, 1, "The storage has one key-value pair");
|
||||
is(sessionStorage.key(0), "key1");
|
||||
checkException(function() {sessionStorage.key(-1);}, INDEX_SIZE_ERR);
|
||||
checkException(function() {sessionStorage.key(1);}, INDEX_SIZE_ERR);
|
||||
is(sessionStorage.getItem("key1"), "value1-2");
|
||||
|
||||
// Clear the storage
|
||||
sessionStorage.clear();
|
||||
is(sessionStorage.length, 0, "The storage is empty [3]");
|
||||
checkException(function() {sessionStorage.key(0);}, INDEX_SIZE_ERR); // this is unspecified!
|
||||
checkException(function() {sessionStorage.key(-1);}, INDEX_SIZE_ERR);
|
||||
checkException(function() {sessionStorage.key(1);}, INDEX_SIZE_ERR);
|
||||
is(sessionStorage.getItem("nonexisting"), null, "Nonexisting item is null");
|
||||
is(sessionStorage.getItem("key1"), null, "key1 removed");
|
||||
is(sessionStorage.getItem("key2"), null, "key2 removed");
|
||||
sessionStorage.removeItem("nonexisting"); // Just check there is no exception
|
||||
sessionStorage.removeItem("key1"); // Just check there is no exception
|
||||
sessionStorage.removeItem("key2"); // Just check there is no exception
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="startTest();">
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,95 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>sessionStorage clone equal origins</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="interOriginTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var currentTest = 1;
|
||||
var currentStep = 1;
|
||||
|
||||
/*
|
||||
window.addEventListener("storage", onStorageEvent, false);
|
||||
|
||||
function onStorageEvent(event)
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
||||
function doNextTest()
|
||||
{
|
||||
// We must perform the first step of the test
|
||||
// to prepare the land.
|
||||
currentStep = 1;
|
||||
doStep();
|
||||
|
||||
switch (currentTest)
|
||||
{
|
||||
case 1:
|
||||
// Open a window from the same origin and check data
|
||||
// are copied but not further modified on our side
|
||||
slaveOrigin = "http://localhost:8888";
|
||||
slave = window.open(slaveOrigin + slavePath + "frameEqual.html");
|
||||
break;
|
||||
|
||||
case 2:
|
||||
slave.close();
|
||||
// Open a window from a different origin and check data
|
||||
// are NOT copied and not modified on our side
|
||||
slaveOrigin = "http://example.com";
|
||||
slave = window.open(slaveOrigin + slavePath + "frameNotEqual.html");
|
||||
break;
|
||||
|
||||
case 3:
|
||||
slave.close();
|
||||
sessionStorage.clear();
|
||||
SimpleTest.finish();
|
||||
break;
|
||||
}
|
||||
|
||||
++currentTest;
|
||||
}
|
||||
|
||||
function doStep()
|
||||
{
|
||||
switch (currentStep)
|
||||
{
|
||||
case 1:
|
||||
sessionStorage.setItem("A", "1");
|
||||
sessionStorage.setItem("B", "2");
|
||||
is(sessionStorage.getItem("A"), "1", "A is 1 in the master");
|
||||
is(sessionStorage.getItem("B"), "2", "B is 2 in the master");
|
||||
is(sessionStorage.length, 2, "Num of items is 2");
|
||||
break;
|
||||
|
||||
case 3:
|
||||
is(sessionStorage.getItem("A"), "1", "A is 1 in the master");
|
||||
is(sessionStorage.getItem("B"), "2", "B is 2 in the master");
|
||||
is(sessionStorage.getItem("C"), null, "C is null in the master");
|
||||
is(sessionStorage.length, 2, "Num of items is 2");
|
||||
|
||||
sessionStorage.setItem("C", "4");
|
||||
is(sessionStorage.getItem("C"), "4", "C is 4 in the master");
|
||||
is(sessionStorage.length, 3, "Num of items is 3");
|
||||
break;
|
||||
}
|
||||
|
||||
++currentStep;
|
||||
++currentStep;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="doNextTest();">
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,79 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>sessionStorage replace test</title>
|
||||
|
||||
<!--
|
||||
This test checks that sessionStorage object doesn't leak
|
||||
in a window that changes its location. We do this by switching
|
||||
frame location inside of this window and then by changing location
|
||||
of a top level window.
|
||||
-->
|
||||
|
||||
<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">
|
||||
|
||||
var shell;
|
||||
var shellType;
|
||||
var failureRegExp = new RegExp("^FAILURE");
|
||||
|
||||
window.addEventListener("message", onMessageReceived, false);
|
||||
|
||||
function onMessageReceived(event)
|
||||
{
|
||||
//alert("onMessageReceived "+event.data);
|
||||
switch (event.data)
|
||||
{
|
||||
case "init_done":
|
||||
// This is frame with different origin in the same browsing context
|
||||
// as the first frame adding data to sessionStorage of the first origin.
|
||||
shell.location = "http://example.com/tests/dom/tests/mochitest/sessionStorage/frameReplace.html?check&" + shellType;
|
||||
break;
|
||||
|
||||
case "check_done":
|
||||
// Recheck and clean the sessionStorage of the first origin.
|
||||
shell.location = "http://example.org:80/tests/dom/tests/mochitest/sessionStorage/frameReplace.html?clean&" + shellType;
|
||||
break;
|
||||
|
||||
case "clean_done":
|
||||
switch (shellType)
|
||||
{
|
||||
case "frame":
|
||||
// We finished testing in a frame
|
||||
// proceed with test in a separate window
|
||||
shellType = "window";
|
||||
shell = window.open("http://example.org/tests/dom/tests/mochitest/sessionStorage/frameReplace.html?init&" + shellType);
|
||||
break;
|
||||
|
||||
case "window":
|
||||
shell.close();
|
||||
window.setTimeout(function() {SimpleTest.finish();}, 0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
SimpleTest.ok(!event.data.match(failureRegExp), event.data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function startTest()
|
||||
{
|
||||
shellType = "frame";
|
||||
shell = frame;
|
||||
shell.location = "http://example.org/tests/dom/tests/mochitest/sessionStorage/frameReplace.html?init&" + shellType;
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="startTest();">
|
||||
<iframe src="" name="frame"></iframe>
|
||||
</body>
|
||||
</html>
|
|
@ -86,6 +86,7 @@
|
|||
#include "nsISupportsArray.h"
|
||||
#include "nsIDeviceContext.h"
|
||||
#include "nsIDOMStorageObsolete.h"
|
||||
#include "nsIDOMStorage.h"
|
||||
#include "nsPIDOMStorage.h"
|
||||
#include "nsIWidget.h"
|
||||
|
||||
|
@ -931,12 +932,12 @@ nsWindowWatcher::OpenWindowJSInternal(nsIDOMWindow *aParent,
|
|||
|
||||
// Copy the current session storage for the current domain.
|
||||
nsCOMPtr<nsPIDOMWindow> piWindow = do_QueryInterface(aParent);
|
||||
nsCOMPtr<nsIDocShell_MOZILLA_1_9_1> parentDocShell;
|
||||
nsIDocShell* parentDocShell = nsnull;
|
||||
if (piWindow)
|
||||
parentDocShell = do_QueryInterface(piWindow->GetDocShell());
|
||||
parentDocShell = piWindow->GetDocShell();
|
||||
|
||||
if (subjectPrincipal && parentDocShell) {
|
||||
nsCOMPtr<nsIDOMStorageObsolete> storage;
|
||||
nsCOMPtr<nsIDOMStorage> storage;
|
||||
parentDocShell->GetSessionStorageForPrincipal(subjectPrincipal, PR_FALSE,
|
||||
getter_AddRefs(storage));
|
||||
nsCOMPtr<nsPIDOMStorage> piStorage =
|
||||
|
@ -944,7 +945,7 @@ nsWindowWatcher::OpenWindowJSInternal(nsIDOMWindow *aParent,
|
|||
if (piStorage){
|
||||
storage = piStorage->Clone();
|
||||
newDocShell->AddSessionStorage(
|
||||
piStorage->Domain(),
|
||||
piStorage->Principal(),
|
||||
storage);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -218,6 +218,10 @@
|
|||
#define NS_DOMSTORAGE_CID \
|
||||
{ 0x8b449142, 0x1eab, 0x4bfa, { 0x98, 0x30, 0xfa, 0xb6, 0xeb, 0xb0, 0x97, 0x74 } }
|
||||
|
||||
// {27AECC62-7777-428e-B34C-5973A47B8298}
|
||||
#define NS_DOMSTORAGE2_CID \
|
||||
{ 0x27aecc62, 0x7777, 0x428e, { 0xb3, 0x4c, 0x59, 0x73, 0xa4, 0x7b, 0x82, 0x98 } }
|
||||
|
||||
// {b88a4712-eb52-4c10-9b85-bf5894b510f0}
|
||||
#define NS_DOMSTORAGEMANAGER_CID \
|
||||
{ 0xb88a4712, 0xeb52, 0x4c10, { 0x9b, 0x85, 0xbf, 0x58, 0x94, 0xb5, 0x10, 0xf0 } }
|
||||
|
|
|
@ -1402,6 +1402,11 @@ static const nsModuleComponentInfo gComponents[] = {
|
|||
"@mozilla.org/dom/storage;1",
|
||||
NS_NewDOMStorage },
|
||||
|
||||
{ "DOM Storage 2",
|
||||
NS_DOMSTORAGE2_CID,
|
||||
"@mozilla.org/dom/storage;2",
|
||||
NS_NewDOMStorage2 },
|
||||
|
||||
{ "DOM Storage Manager",
|
||||
NS_DOMSTORAGEMANAGER_CID,
|
||||
"@mozilla.org/dom/storagemanager;1",
|
||||
|
|
Загрузка…
Ссылка в новой задаче