diff --git a/browser/components/sessionstore/src/nsSessionStore.js b/browser/components/sessionstore/src/nsSessionStore.js index d3220eb98fe..cb85ab67852 100644 --- a/browser/components/sessionstore/src/nsSessionStore.js +++ b/browser/components/sessionstore/src/nsSessionStore.js @@ -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 } diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 98f3746e412..285435d2d7b 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -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 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 topItem; + rv = GetSameTypeRootTreeItem(getter_AddRefs(topItem)); + if (NS_FAILED(rv)) + return rv; + + if (!topItem) + return NS_ERROR_FAILURE; + + nsDocShell* topDocShell = static_cast(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 newstorage = + do_CreateInstance("@mozilla.org/dom/storage;2"); + if (!newstorage) + return NS_ERROR_OUT_OF_MEMORY; + + nsCOMPtr 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 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 innerURI = NS_GetInnermostURI(aURI); - NS_ASSERTION(innerURI, "Failed to get innermost URI"); - if (!innerURI) - return NS_ERROR_FAILURE; + nsresult rv; - nsCOMPtr topItem; - nsresult rv = GetSameTypeRootTreeItem(getter_AddRefs(topItem)); + nsCOMPtr 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 principal; + rv = securityManager->GetCodebasePrincipal(aURI, getter_AddRefs(principal)); if (NS_FAILED(rv)) return rv; - if (!topItem) - return NS_ERROR_FAILURE; - - nsDocShell* topDocShell = static_cast(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 newstorage = - do_CreateInstance("@mozilla.org/dom/storage;1"); - if (!newstorage) - return NS_ERROR_OUT_OF_MEMORY; - - nsCOMPtr 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 topItem; @@ -2258,15 +2256,23 @@ nsDocShell::AddSessionStorage(const nsACString& aDomain, if (topItem) { nsCOMPtr 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); } } diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index c1c7f8c19b2..6c1a8ba8d33 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -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 mStorages; - nsIntRect mBounds; // Dimensions of the docshell + nsInterfaceHashtable 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. diff --git a/docshell/base/nsIDocShell.idl b/docshell/base/nsIDocShell.idl index 7fca20093db..a3cd87699de 100644 --- a/docshell/base/nsIDocShell.idl +++ b/docshell/base/nsIDocShell.idl @@ -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); -}; diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index da1b969f1ca..84281e527f7 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -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 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 docShell = - do_QueryInterface(GetDocShell()); + nsIDocShell* docShell = GetDocShell(); if (principal && docShell) { - nsCOMPtr storage; + nsCOMPtr 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(userArg); - nsCOMPtr storage; + nsCOMPtr storage; win->GetSessionStorage(getter_AddRefs(storage)); if (storage) { diff --git a/dom/interfaces/storage/nsIDOMStorageWindow.idl b/dom/interfaces/storage/nsIDOMStorageWindow.idl index 373ba3c9c96..afecc4e292b 100644 --- a/dom/interfaces/storage/nsIDOMStorageWindow.idl +++ b/dom/interfaces/storage/nsIDOMStorageWindow.idl @@ -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. diff --git a/dom/interfaces/storage/nsPIDOMStorage.h b/dom/interfaces/storage/nsPIDOMStorage.h index c3ae78c51a1..2ee17f0c706 100644 --- a/dom/interfaces/storage/nsPIDOMStorage.h +++ b/dom/interfaces/storage/nsPIDOMStorage.h @@ -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 Clone() = 0; + virtual already_AddRefed Clone() = 0; virtual nsTArray *GetKeys() = 0; - virtual const nsCString &Domain() = 0; + virtual nsIPrincipal* Principal() = 0; virtual PRBool CanAccess(nsIPrincipal *aPrincipal) = 0; }; diff --git a/dom/src/storage/nsDOMStorage.cpp b/dom/src/storage/nsDOMStorage.cpp index 2b718db7327..22549fb4d79 100644 --- a/dom/src/storage/nsDOMStorage.cpp +++ b/dom/src/storage/nsDOMStorage.cpp @@ -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(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 uri; + rv = aPrincipal->GetURI(getter_AddRefs(uri)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr 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(userArg); - - newstorage->SetItem(aEntry->GetKey(), aEntry->mItem->GetValueInternal()); - - if (aEntry->mItem->IsSecure()) { - newstorage->SetSecure(aEntry->GetKey(), PR_TRUE); - } - - return PL_DHASH_NEXT; -} - -already_AddRefed +already_AddRefed 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 +already_AddRefed 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 * @@ -1430,10 +1446,10 @@ nsDOMStorage2::GetKeys() return mStorage->GetKeys(); } -const nsCString & -nsDOMStorage2::Domain() +nsIPrincipal* +nsDOMStorage2::Principal() { - return mStorage->Domain(); + return mPrincipal; } PRBool diff --git a/dom/src/storage/nsDOMStorage.h b/dom/src/storage/nsDOMStorage.h index 2633f254c99..6d1d4ae90f8 100644 --- a/dom/src/storage/nsDOMStorage.h +++ b/dom/src/storage/nsDOMStorage.h @@ -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 Clone(); + virtual already_AddRefed Clone(); virtual nsTArray *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 Clone(); + virtual already_AddRefed Clone(); virtual nsTArray *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); diff --git a/dom/tests/mochitest/Makefile.in b/dom/tests/mochitest/Makefile.in index 35b751542b8..9e3d220f664 100644 --- a/dom/tests/mochitest/Makefile.in +++ b/dom/tests/mochitest/Makefile.in @@ -54,6 +54,7 @@ DIRS += \ whatwg \ geolocation \ localstorage \ + sessionstorage \ $(NULL) include $(topsrcdir)/config/rules.mk diff --git a/dom/tests/mochitest/sessionstorage/Makefile.in b/dom/tests/mochitest/sessionstorage/Makefile.in new file mode 100644 index 00000000000..234902c2675 --- /dev/null +++ b/dom/tests/mochitest/sessionstorage/Makefile.in @@ -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) diff --git a/dom/tests/mochitest/sessionstorage/frameEqual.html b/dom/tests/mochitest/sessionstorage/frameEqual.html new file mode 100644 index 00000000000..787f3ee3eb3 --- /dev/null +++ b/dom/tests/mochitest/sessionstorage/frameEqual.html @@ -0,0 +1,47 @@ + + +slave for sessionStorage test + + + + + + + + + diff --git a/dom/tests/mochitest/sessionstorage/frameNotEqual.html b/dom/tests/mochitest/sessionstorage/frameNotEqual.html new file mode 100644 index 00000000000..221ca97e563 --- /dev/null +++ b/dom/tests/mochitest/sessionstorage/frameNotEqual.html @@ -0,0 +1,43 @@ + + +slave for sessionStorage test + + + + + + + + + diff --git a/dom/tests/mochitest/sessionstorage/frameReplace.html b/dom/tests/mochitest/sessionstorage/frameReplace.html new file mode 100644 index 00000000000..344164e8798 --- /dev/null +++ b/dom/tests/mochitest/sessionstorage/frameReplace.html @@ -0,0 +1,75 @@ + + +sessionStorage replace frame + + + + + + + diff --git a/dom/tests/mochitest/sessionstorage/interOriginSlave.js b/dom/tests/mochitest/sessionstorage/interOriginSlave.js new file mode 100644 index 00000000000..265daad470d --- /dev/null +++ b/dom/tests/mochitest/sessionstorage/interOriginSlave.js @@ -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; +} diff --git a/dom/tests/mochitest/sessionstorage/interOriginTest.js b/dom/tests/mochitest/sessionstorage/interOriginTest.js new file mode 100644 index 00000000000..adea77edb53 --- /dev/null +++ b/dom/tests/mochitest/sessionstorage/interOriginTest.js @@ -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; + } +} diff --git a/dom/tests/mochitest/sessionstorage/test_sessionStorageBase.html b/dom/tests/mochitest/sessionstorage/test_sessionStorageBase.html new file mode 100644 index 00000000000..31e3cba1ec6 --- /dev/null +++ b/dom/tests/mochitest/sessionstorage/test_sessionStorageBase.html @@ -0,0 +1,156 @@ + + +sessionStorage basic test + + + + + + + + + + + + + diff --git a/dom/tests/mochitest/sessionstorage/test_sessionStorageClone.html b/dom/tests/mochitest/sessionstorage/test_sessionStorageClone.html new file mode 100644 index 00000000000..49f34a7664c --- /dev/null +++ b/dom/tests/mochitest/sessionstorage/test_sessionStorageClone.html @@ -0,0 +1,95 @@ + + +sessionStorage clone equal origins + + + + + + + + + + + + + diff --git a/dom/tests/mochitest/sessionstorage/test_sessionStorageReplace.html b/dom/tests/mochitest/sessionstorage/test_sessionStorageReplace.html new file mode 100644 index 00000000000..18b2cacf89d --- /dev/null +++ b/dom/tests/mochitest/sessionstorage/test_sessionStorageReplace.html @@ -0,0 +1,79 @@ + + +sessionStorage replace test + + + + + + + + + + + + + + + diff --git a/embedding/components/windowwatcher/src/nsWindowWatcher.cpp b/embedding/components/windowwatcher/src/nsWindowWatcher.cpp index f5b5664c0bb..37292311d7c 100644 --- a/embedding/components/windowwatcher/src/nsWindowWatcher.cpp +++ b/embedding/components/windowwatcher/src/nsWindowWatcher.cpp @@ -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 piWindow = do_QueryInterface(aParent); - nsCOMPtr parentDocShell; + nsIDocShell* parentDocShell = nsnull; if (piWindow) - parentDocShell = do_QueryInterface(piWindow->GetDocShell()); + parentDocShell = piWindow->GetDocShell(); if (subjectPrincipal && parentDocShell) { - nsCOMPtr storage; + nsCOMPtr storage; parentDocShell->GetSessionStorageForPrincipal(subjectPrincipal, PR_FALSE, getter_AddRefs(storage)); nsCOMPtr piStorage = @@ -944,7 +945,7 @@ nsWindowWatcher::OpenWindowJSInternal(nsIDOMWindow *aParent, if (piStorage){ storage = piStorage->Clone(); newDocShell->AddSessionStorage( - piStorage->Domain(), + piStorage->Principal(), storage); } } diff --git a/layout/build/nsLayoutCID.h b/layout/build/nsLayoutCID.h index 7795a661d1c..811cf7451a8 100644 --- a/layout/build/nsLayoutCID.h +++ b/layout/build/nsLayoutCID.h @@ -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 } } diff --git a/layout/build/nsLayoutModule.cpp b/layout/build/nsLayoutModule.cpp index b23b51e0904..ebcace7bcc3 100644 --- a/layout/build/nsLayoutModule.cpp +++ b/layout/build/nsLayoutModule.cpp @@ -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",