Bug 501423 - StorageEvent implementation does not match the spec, r=jst

This commit is contained in:
Honza Bambas
2010-01-28 15:53:53 +01:00
parent 59d507abe3
commit d6bdaf09d8
37 changed files with 1679 additions and 135 deletions

View File

@@ -51,6 +51,7 @@
#include "nsIContent.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "nsIDOM3Document.h"
#include "nsIDOMNSDocument.h"
#include "nsIDOMElement.h"
#include "nsIDOMStorageObsolete.h"
@@ -2144,6 +2145,7 @@ GetPrincipalDomain(nsIPrincipal* aPrincipal, nsACString& aDomain)
NS_IMETHODIMP
nsDocShell::GetSessionStorageForPrincipal(nsIPrincipal* aPrincipal,
const nsAString& aDocumentURI,
PRBool aCreate,
nsIDOMStorage** aStorage)
{
@@ -2165,7 +2167,9 @@ nsDocShell::GetSessionStorageForPrincipal(nsIPrincipal* aPrincipal,
nsDocShell* topDocShell = static_cast<nsDocShell*>(topItem.get());
if (topDocShell != this)
return topDocShell->GetSessionStorageForPrincipal(aPrincipal, aCreate,
return topDocShell->GetSessionStorageForPrincipal(aPrincipal,
aDocumentURI,
aCreate,
aStorage);
nsCAutoString currentDomain;
@@ -2185,7 +2189,7 @@ nsDocShell::GetSessionStorageForPrincipal(nsIPrincipal* aPrincipal,
nsCOMPtr<nsPIDOMStorage> pistorage = do_QueryInterface(newstorage);
if (!pistorage)
return NS_ERROR_FAILURE;
rv = pistorage->InitAsSessionStorage(aPrincipal);
rv = pistorage->InitAsSessionStorage(aPrincipal, aDocumentURI);
if (NS_FAILED(rv))
return rv;
@@ -2193,19 +2197,57 @@ nsDocShell::GetSessionStorageForPrincipal(nsIPrincipal* aPrincipal,
return NS_ERROR_OUT_OF_MEMORY;
newstorage.swap(*aStorage);
return NS_OK;
#if defined(PR_LOGGING) && defined(DEBUG)
PR_LOG(gDocShellLog, PR_LOG_DEBUG,
("nsDocShell[%p]: created a new sessionStorage %p",
this, *aStorage));
#endif
}
else if (*aStorage) {
nsCOMPtr<nsPIDOMStorage> piStorage = do_QueryInterface(*aStorage);
if (piStorage) {
PRBool canAccess = piStorage->CanAccess(aPrincipal);
NS_ASSERTION(canAccess,
"GetSessionStorageForPrincipal got a storage "
"that could not be accessed!");
if (!canAccess) {
NS_RELEASE(*aStorage);
return NS_ERROR_DOM_SECURITY_ERR;
}
}
#if defined(PR_LOGGING) && defined(DEBUG)
PR_LOG(gDocShellLog, PR_LOG_DEBUG,
("nsDocShell[%p]: returns existing sessionStorage %p",
this, *aStorage));
#endif
}
nsCOMPtr<nsPIDOMStorage> piStorage = do_QueryInterface(*aStorage);
if (piStorage) {
PRBool canAccess = piStorage->CanAccess(aPrincipal);
NS_ASSERTION(canAccess,
"GetSessionStorageForPrincipal got a storage "
"that could not be accessed!");
if (!canAccess) {
NS_RELEASE(*aStorage);
return NS_ERROR_DOM_SECURITY_ERR;
}
if (aCreate) {
// We are asked to create a new storage object. This indicates
// that a new windows wants it. At this moment we "fork" the existing
// storage object (what it means is described in the paragraph bellow).
// We must create a single object per a single window to distinguish
// a window originating oparations on the storage object to succesfully
// prevent dispatch of a storage event to this same window that ivoked
// a change in its storage. We also do this to correctly fill
// documentURI property in the storage event.
//
// The difference between clone and fork is that clone creates
// a completelly new and independent storage, but fork only creates
// a new object wrapping the storage implementation and data and
// the forked storage then behaves completelly the same way as
// the storage it has been forked of, all such forked storage objects
// shares their state and data and change on one such object affects
// all others the same way.
nsCOMPtr<nsPIDOMStorage> piStorage = do_QueryInterface(*aStorage);
nsCOMPtr<nsIDOMStorage> fork = piStorage->Fork(aDocumentURI);
#if defined(PR_LOGGING) && defined(DEBUG)
PR_LOG(gDocShellLog, PR_LOG_DEBUG,
("nsDocShell[%p]: forked sessionStorage %p to %p",
this, *aStorage, fork.get()));
#endif
fork.swap(*aStorage);
}
return NS_OK;
@@ -2213,13 +2255,15 @@ nsDocShell::GetSessionStorageForPrincipal(nsIPrincipal* aPrincipal,
NS_IMETHODIMP
nsDocShell::GetSessionStorageForURI(nsIURI* aURI,
const nsAString& aDocumentURI,
nsIDOMStorage** aStorage)
{
return GetSessionStorageForURI(aURI, PR_TRUE, aStorage);
return GetSessionStorageForURI(aURI, aDocumentURI, PR_TRUE, aStorage);
}
nsresult
nsDocShell::GetSessionStorageForURI(nsIURI* aURI,
const nsSubstring& aDocumentURI,
PRBool aCreate,
nsIDOMStorage** aStorage)
{
@@ -2240,7 +2284,7 @@ nsDocShell::GetSessionStorageForURI(nsIURI* aURI,
if (NS_FAILED(rv))
return rv;
return GetSessionStorageForPrincipal(principal, aCreate, aStorage);
return GetSessionStorageForPrincipal(principal, aDocumentURI, aCreate, aStorage);
}
nsresult
@@ -2272,6 +2316,11 @@ nsDocShell::AddSessionStorage(nsIPrincipal* aPrincipal,
if (mStorages.GetWeak(currentDomain))
return NS_ERROR_NOT_AVAILABLE;
#if defined(PR_LOGGING) && defined(DEBUG)
PR_LOG(gDocShellLog, PR_LOG_DEBUG,
("nsDocShell[%p]: was added a sessionStorage %p",
this, aStorage));
#endif
if (!mStorages.Put(currentDomain, aStorage))
return NS_ERROR_OUT_OF_MEMORY;
}