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:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user