Fixing bug 335540. Implement whatwg webapps storage. Patch by neil@mozilla.com and jst@mozilla.com, r/sr=neil/vlad/jst.

This commit is contained in:
jst@mozilla.jstenback.com
2006-05-19 05:57:36 +00:00
parent c218afa52c
commit f297efc1af
28 changed files with 2941 additions and 26 deletions

View File

@@ -52,6 +52,8 @@
#include "nsIDOMDocument.h"
#include "nsIDOMNSDocument.h"
#include "nsIDOMElement.h"
#include "nsIDOMStorage.h"
#include "nsPIDOMStorage.h"
#include "nsIDocumentViewer.h"
#include "nsIDocumentLoaderFactory.h"
#include "nsCURILoader.h"
@@ -340,6 +342,9 @@ nsDocShell::Init()
rv = mContentListener->Init();
NS_ENSURE_SUCCESS(rv, rv);
if (!mStorages.Init())
return NS_ERROR_OUT_OF_MEMORY;
// We want to hold a strong ref to the loadgroup, so it better hold a weak
// ref to us... use an InterfaceRequestorProxy to do this.
nsCOMPtr<InterfaceRequestorProxy> proxy =
@@ -1659,6 +1664,78 @@ nsDocShell::HistoryPurged(PRInt32 aNumEntries)
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetSessionStorageForDomain(const nsACString& aDomain,
nsIDOMStorage** aStorage)
{
NS_ENSURE_ARG_POINTER(aStorage);
*aStorage = nsnull;
if (aDomain.IsEmpty())
return NS_OK;
nsCOMPtr<nsIDocShellTreeItem> topItem;
nsresult rv = GetSameTypeRootTreeItem(getter_AddRefs(topItem));
if (NS_FAILED(rv))
return rv;
if (!topItem)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIDocShell> topDocShell = do_QueryInterface(topItem);
if (topDocShell != this)
return topDocShell->GetSessionStorageForDomain(aDomain, aStorage);
if (!mStorages.Get(aDomain, aStorage)) {
nsCOMPtr<nsIDOMStorage> 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->Init(NS_ConvertUTF8toUTF16(aDomain), PR_FALSE);
if (!mStorages.Put(aDomain, newstorage))
return NS_ERROR_OUT_OF_MEMORY;
*aStorage = newstorage;
NS_ADDREF(*aStorage);
}
return NS_OK;
}
nsresult
nsDocShell::AddSessionStorage(const nsACString& aDomain,
nsIDOMStorage* aStorage)
{
NS_ENSURE_ARG_POINTER(aStorage);
if (aDomain.IsEmpty())
return NS_OK;
nsCOMPtr<nsIDocShellTreeItem> topItem;
nsresult rv = GetSameTypeRootTreeItem(getter_AddRefs(topItem));
if (NS_FAILED(rv))
return rv;
if (topItem) {
nsCOMPtr<nsIDocShell> topDocShell = do_QueryInterface(topItem);
if (topDocShell == this) {
if (!mStorages.Put(aDomain, aStorage))
return NS_ERROR_OUT_OF_MEMORY;
}
else {
return topDocShell->AddSessionStorage(aDomain, aStorage);
}
}
return NS_OK;
}
//*****************************************************************************
// nsDocShell::nsIDocShellTreeItem
//*****************************************************************************
@@ -6278,6 +6355,40 @@ nsDocShell::InternalLoad(nsIURI * aURI,
nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(newWin);
targetDocShell = do_QueryInterface(webNav);
nsCOMPtr<nsIScriptObjectPrincipal> sop =
do_QueryInterface(mScriptGlobal);
nsCOMPtr<nsIURI> currentCodebase;
if (sop) {
nsIPrincipal *principal = sop->GetPrincipal();
if (principal) {
principal->GetURI(getter_AddRefs(currentCodebase));
}
}
// We opened a new window for the target, clone the
// session storage if the current URI's domain matches
// that of the loading URI.
if (targetDocShell && currentCodebase && aURI) {
nsCAutoString thisDomain, newDomain;
nsresult gethostrv = currentCodebase->GetAsciiHost(thisDomain);
gethostrv |= aURI->GetAsciiHost(newDomain);
if (NS_SUCCEEDED(gethostrv) && thisDomain.Equals(newDomain)) {
nsCOMPtr<nsIDOMStorage> storage;
GetSessionStorageForDomain(thisDomain,
getter_AddRefs(storage));
nsCOMPtr<nsPIDOMStorage> piStorage =
do_QueryInterface(storage);
if (piStorage) {
nsCOMPtr<nsIDOMStorage> newstorage =
piStorage->Clone();
targetDocShell->AddSessionStorage(thisDomain,
newstorage);
}
}
}
}
//