зеркало из https://github.com/mozilla/gecko-dev.git
Bug 660237 - implement nsIDOMStorage with a proxy, r=bzbarsky, r=mayhemer
This commit is contained in:
Родитель
eafe8cdc8f
Коммит
3d909148b5
|
@ -107,11 +107,12 @@ let SessionStorageInternal = {
|
|||
let uri = Services.io.newURI(host, null, null);
|
||||
let principal = Services.scriptSecurityManager.getDocShellCodebasePrincipal(uri, aDocShell);
|
||||
let storageManager = aDocShell.QueryInterface(Ci.nsIDOMStorageManager);
|
||||
let window = aDocShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindow);
|
||||
|
||||
// There is no need to pass documentURI, it's only used to fill documentURI property of
|
||||
// domstorage event, which in this case has no consumer. Prevention of events in case
|
||||
// of missing documentURI will be solved in a followup bug to bug 600307.
|
||||
let storage = storageManager.createStorage(principal, "", aDocShell.usePrivateBrowsing);
|
||||
let storage = storageManager.createStorage(window, principal, "", aDocShell.usePrivateBrowsing);
|
||||
|
||||
for (let key of Object.keys(data)) {
|
||||
try {
|
||||
|
@ -135,9 +136,11 @@ let SessionStorageInternal = {
|
|||
let hostData = {};
|
||||
let storage;
|
||||
|
||||
let window = aDocShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindow);
|
||||
|
||||
try {
|
||||
let storageManager = aDocShell.QueryInterface(Ci.nsIDOMStorageManager);
|
||||
storage = storageManager.getStorage(aPrincipal);
|
||||
storage = storageManager.getStorage(window, aPrincipal);
|
||||
} catch (e) {
|
||||
// sessionStorage might throw if it's turned off, see bug 458954
|
||||
}
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMStorage.h"
|
||||
#include "nsPIDOMStorage.h"
|
||||
#include "nsIContentViewer.h"
|
||||
#include "nsIDocumentLoaderFactory.h"
|
||||
#include "nsCURILoader.h"
|
||||
|
@ -2790,20 +2789,27 @@ nsDocShell::GetSessionStorageForPrincipal(nsIPrincipal* aPrincipal,
|
|||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> domWin = do_GetInterface(GetAsSupports(this));
|
||||
|
||||
if (aCreate) {
|
||||
return manager->CreateStorage(aPrincipal, aDocumentURI,
|
||||
return manager->CreateStorage(domWin, aPrincipal, aDocumentURI,
|
||||
mInPrivateBrowsing, aStorage);
|
||||
}
|
||||
|
||||
return manager->GetStorage(aPrincipal, mInPrivateBrowsing, aStorage);
|
||||
return manager->GetStorage(domWin, aPrincipal, mInPrivateBrowsing,
|
||||
aStorage);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocShell::AddSessionStorage(nsIPrincipal* aPrincipal,
|
||||
nsIDOMStorage* aStorage)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMStorage> pistorage = do_QueryInterface(aStorage);
|
||||
nsIPrincipal* storagePrincipal = pistorage->GetPrincipal();
|
||||
nsRefPtr<DOMStorage> storage = static_cast<DOMStorage*>(aStorage);
|
||||
if (!storage) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
nsIPrincipal* storagePrincipal = storage->GetPrincipal();
|
||||
if (storagePrincipal != aPrincipal) {
|
||||
NS_ERROR("Wanting to add a sessionStorage for different principal");
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
|
|
|
@ -113,10 +113,6 @@
|
|||
#endif
|
||||
#include "nsIDOMXPathNSResolver.h"
|
||||
|
||||
// Storage includes
|
||||
#include "nsIDOMStorage.h"
|
||||
#include "nsPIDOMStorage.h"
|
||||
|
||||
// Drag and drop
|
||||
#include "nsIDOMFile.h"
|
||||
#include "nsDOMBlobBuilder.h" // nsDOMMultipartFile
|
||||
|
@ -345,21 +341,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
|||
NS_DEFINE_CLASSINFO_DATA(XPathNSResolver, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
// WhatWG Storage
|
||||
|
||||
// mrbkap says we don't need WANT_ADDPROPERTY on Storage objects
|
||||
// since a call to addProperty() is always followed by a call to
|
||||
// setProperty(), except in the case when a getter or setter is set
|
||||
// for a property. But we don't care about getters or setters here.
|
||||
NS_DEFINE_CLASSINFO_DATA(Storage, nsStorage2SH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS |
|
||||
nsIXPCScriptable::WANT_NEWRESOLVE |
|
||||
nsIXPCScriptable::WANT_GETPROPERTY |
|
||||
nsIXPCScriptable::WANT_SETPROPERTY |
|
||||
nsIXPCScriptable::WANT_DELPROPERTY |
|
||||
nsIXPCScriptable::DONT_ENUM_STATIC_PROPS |
|
||||
nsIXPCScriptable::WANT_NEWENUMERATE)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(Blob, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(File, nsDOMGenericSH,
|
||||
|
@ -942,10 +923,6 @@ nsDOMClassInfo::Init()
|
|||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMXPathNSResolver)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(Storage, nsIDOMStorage)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMStorage)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(Blob, nsIDOMBlob)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMBlob)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
@ -3389,217 +3366,6 @@ nsEventTargetSH::PreserveWrapper(nsISupports *aNative)
|
|||
target->PreserveWrapper(aNative);
|
||||
}
|
||||
|
||||
// Storage2SH
|
||||
|
||||
// One reason we need a newResolve hook is that in order for
|
||||
// enumeration of storage object keys to work the keys we're
|
||||
// enumerating need to exist on the storage object for the JS engine
|
||||
// to find them.
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStorage2SH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, jsid aId, JSObject **objp,
|
||||
bool *_retval)
|
||||
{
|
||||
JS::Rooted<jsid> id(cx, aId);
|
||||
if (ObjectIsNativeWrapper(cx, obj)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> realObj(cx, wrapper->GetJSObject());
|
||||
|
||||
JSAutoCompartment ac(cx, realObj);
|
||||
|
||||
// First check to see if the property is defined on our prototype,
|
||||
// after converting id to a string if it's an integer.
|
||||
|
||||
JS::Rooted<JSString*> jsstr(cx, IdToString(cx, id));
|
||||
if (!jsstr) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> proto(cx);
|
||||
if (!::JS_GetPrototype(cx, realObj, &proto)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
bool hasProp;
|
||||
|
||||
if (proto &&
|
||||
(::JS_HasPropertyById(cx, proto, id, &hasProp) &&
|
||||
hasProp)) {
|
||||
// We found the property we're resolving on the prototype,
|
||||
// nothing left to do here then.
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// We're resolving property that doesn't exist on the prototype,
|
||||
// check if the key exists in the storage object.
|
||||
|
||||
nsCOMPtr<nsIDOMStorage> storage(do_QueryWrappedNative(wrapper));
|
||||
|
||||
nsAutoJSString autoStr;
|
||||
NS_ENSURE_TRUE(autoStr.init(cx, jsstr), NS_ERROR_UNEXPECTED);
|
||||
|
||||
// GetItem() will return null if the caller can't access the session
|
||||
// storage item.
|
||||
nsAutoString data;
|
||||
nsresult rv = storage->GetItem(autoStr, data);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!DOMStringIsNull(data)) {
|
||||
if (!::JS_DefinePropertyById(cx, realObj, id, JS::UndefinedHandleValue,
|
||||
JSPROP_ENUMERATE)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*objp = realObj;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStorage2SH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *aObj, jsid aId, jsval *vp, bool *_retval)
|
||||
{
|
||||
JS::Rooted<JSObject*> obj(cx, aObj);
|
||||
JS::Rooted<jsid> id(cx, aId);
|
||||
nsCOMPtr<nsIDOMStorage> storage(do_QueryWrappedNative(wrapper));
|
||||
NS_ENSURE_TRUE(storage, NS_ERROR_UNEXPECTED);
|
||||
|
||||
JSString* key = IdToString(cx, id);
|
||||
NS_ENSURE_TRUE(key, NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsAutoJSString keyStr;
|
||||
NS_ENSURE_TRUE(keyStr.init(cx, key), NS_ERROR_UNEXPECTED);
|
||||
|
||||
// For native wrappers, do not get random names on storage objects.
|
||||
if (ObjectIsNativeWrapper(cx, obj)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsAutoString val;
|
||||
nsresult rv = storage->GetItem(keyStr, val);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (DOMStringIsNull(val)) {
|
||||
// No such key.
|
||||
*vp = JSVAL_VOID;
|
||||
} else {
|
||||
JSString* str =
|
||||
JS_NewUCStringCopyN(cx, static_cast<const jschar *>(val.get()),
|
||||
val.Length());
|
||||
NS_ENSURE_TRUE(str, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
*vp = STRING_TO_JSVAL(str);
|
||||
}
|
||||
|
||||
return NS_SUCCESS_I_DID_SOMETHING;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStorage2SH::SetProperty(nsIXPConnectWrappedNative *wrapper,
|
||||
JSContext *cx, JSObject *obj, jsid aId,
|
||||
jsval *vp, bool *_retval)
|
||||
{
|
||||
JS::Rooted<jsid> id(cx, aId);
|
||||
nsCOMPtr<nsIDOMStorage> storage(do_QueryWrappedNative(wrapper));
|
||||
NS_ENSURE_TRUE(storage, NS_ERROR_UNEXPECTED);
|
||||
|
||||
JSString *key = IdToString(cx, id);
|
||||
NS_ENSURE_TRUE(key, NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsAutoJSString keyStr;
|
||||
NS_ENSURE_TRUE(keyStr.init(cx, key), NS_ERROR_UNEXPECTED);
|
||||
|
||||
JS::Rooted<JS::Value> val(cx, *vp);
|
||||
JSString *value = JS::ToString(cx, val);
|
||||
NS_ENSURE_TRUE(value, NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsAutoJSString valueStr;
|
||||
NS_ENSURE_TRUE(valueStr.init(cx, value), NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsresult rv = storage->SetItem(keyStr, valueStr);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = NS_SUCCESS_I_DID_SOMETHING;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStorage2SH::DelProperty(nsIXPConnectWrappedNative *wrapper,
|
||||
JSContext *cx, JSObject *obj, jsid aId,
|
||||
bool *_retval)
|
||||
{
|
||||
JS::Rooted<jsid> id(cx, aId);
|
||||
nsCOMPtr<nsIDOMStorage> storage(do_QueryWrappedNative(wrapper));
|
||||
NS_ENSURE_TRUE(storage, NS_ERROR_UNEXPECTED);
|
||||
|
||||
JSString *key = IdToString(cx, id);
|
||||
NS_ENSURE_TRUE(key, NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsAutoJSString keyStr;
|
||||
NS_ENSURE_TRUE(keyStr.init(cx, key), NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsresult rv = storage->RemoveItem(keyStr);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
*_retval = true;
|
||||
return NS_SUCCESS_I_DID_SOMETHING;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStorage2SH::NewEnumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, uint32_t enum_op, jsval *statep,
|
||||
jsid *idp, bool *_retval)
|
||||
{
|
||||
if (enum_op == JSENUMERATE_INIT || enum_op == JSENUMERATE_INIT_ALL) {
|
||||
nsCOMPtr<nsPIDOMStorage> storage(do_QueryWrappedNative(wrapper));
|
||||
|
||||
// XXXndeakin need to free the keys afterwards
|
||||
nsTArray<nsString> *keys = storage->GetKeys();
|
||||
NS_ENSURE_TRUE(keys, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
*statep = PRIVATE_TO_JSVAL(keys);
|
||||
|
||||
if (idp) {
|
||||
*idp = INT_TO_JSID(keys->Length());
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsTArray<nsString> *keys = (nsTArray<nsString> *)statep->toPrivate();
|
||||
|
||||
if (enum_op == JSENUMERATE_NEXT && keys->Length() != 0) {
|
||||
nsString& key = keys->ElementAt(0);
|
||||
JS::Rooted<JSString*> str(cx, JS_NewUCStringCopyN(cx, key.get(), key.Length()));
|
||||
NS_ENSURE_TRUE(str, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
JS::Rooted<jsid> id(cx);
|
||||
JS_StringToId(cx, str, &id);
|
||||
*idp = id;
|
||||
|
||||
keys->RemoveElementAt(0);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// destroy the keys array if we have no keys or if we're done
|
||||
NS_ABORT_IF_FALSE(enum_op == JSENUMERATE_DESTROY ||
|
||||
(enum_op == JSENUMERATE_NEXT && keys->Length() == 0),
|
||||
"Bad call from the JS engine");
|
||||
delete keys;
|
||||
|
||||
*statep = JSVAL_NULL;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIDOMEventListener::HandleEvent() 'this' converter helper
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsEventListenerThisTranslator)
|
||||
|
|
|
@ -303,39 +303,6 @@ public:
|
|||
};
|
||||
|
||||
|
||||
// WebApps Storage helpers
|
||||
|
||||
class nsStorage2SH : public nsDOMGenericSH
|
||||
{
|
||||
protected:
|
||||
nsStorage2SH(nsDOMClassInfoData* aData) : nsDOMGenericSH(aData)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~nsStorage2SH()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, jsid id, JSObject **objp,
|
||||
bool *_retval) MOZ_OVERRIDE;
|
||||
NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, jsid id, JS::Value *vp, bool *_retval) MOZ_OVERRIDE;
|
||||
NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, jsid id, JS::Value *vp, bool *_retval) MOZ_OVERRIDE;
|
||||
NS_IMETHOD DelProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, jsid id, bool *_retval) MOZ_OVERRIDE;
|
||||
NS_IMETHOD NewEnumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, uint32_t enum_op, JS::Value *statep,
|
||||
jsid *idp, bool *_retval) MOZ_OVERRIDE;
|
||||
|
||||
public:
|
||||
static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
|
||||
{
|
||||
return new nsStorage2SH(aData);
|
||||
}
|
||||
};
|
||||
|
||||
// Event handler 'this' translator class, this is called by XPConnect
|
||||
// when a "function interface" (nsIDOMEventListener) is called, this
|
||||
// class extracts 'this' fomr the first argument to the called
|
||||
|
|
|
@ -48,9 +48,6 @@ DOMCI_CLASS(XSLTProcessor)
|
|||
// DOM Level 3 XPath objects
|
||||
DOMCI_CLASS(XPathNSResolver)
|
||||
|
||||
// WhatWG WebApps Objects
|
||||
DOMCI_CLASS(Storage)
|
||||
|
||||
DOMCI_CLASS(Blob)
|
||||
DOMCI_CLASS(File)
|
||||
|
||||
|
|
|
@ -16,9 +16,10 @@
|
|||
#include "nsHistory.h"
|
||||
#include "nsPerformance.h"
|
||||
#include "nsDOMNavigationTiming.h"
|
||||
#include "nsIDOMStorage.h"
|
||||
#include "nsIDOMStorageManager.h"
|
||||
#include "DOMStorage.h"
|
||||
#include "mozilla/dom/DOMStorage.h"
|
||||
#include "mozilla/dom/StorageEvent.h"
|
||||
#include "mozilla/dom/StorageEventBinding.h"
|
||||
#include "nsDOMOfflineResourceList.h"
|
||||
#include "nsError.h"
|
||||
#include "nsIIdleService.h"
|
||||
|
@ -89,7 +90,6 @@
|
|||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsIDOMOfflineResourceList.h"
|
||||
#include "nsPIDOMStorage.h"
|
||||
#include "nsDOMString.h"
|
||||
#include "nsIEmbeddingSiteWindow.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
@ -10349,7 +10349,7 @@ nsGlobalWindow::GetComputedStyleHelper(Element& aElt,
|
|||
return compStyle.forget();
|
||||
}
|
||||
|
||||
nsIDOMStorage*
|
||||
DOMStorage*
|
||||
nsGlobalWindow::GetSessionStorage(ErrorResult& aError)
|
||||
{
|
||||
FORWARD_TO_INNER_OR_THROW(GetSessionStorage, (aError), aError, nullptr);
|
||||
|
@ -10367,15 +10367,12 @@ nsGlobalWindow::GetSessionStorage(ErrorResult& aError)
|
|||
PR_LogPrint("nsGlobalWindow %p has %p sessionStorage", this, mSessionStorage.get());
|
||||
}
|
||||
#endif
|
||||
nsCOMPtr<nsPIDOMStorage> piStorage = do_QueryInterface(mSessionStorage);
|
||||
if (piStorage) {
|
||||
bool canAccess = piStorage->CanAccess(principal);
|
||||
NS_ASSERTION(canAccess,
|
||||
"window %x owned sessionStorage "
|
||||
"that could not be accessed!");
|
||||
if (!canAccess) {
|
||||
mSessionStorage = nullptr;
|
||||
}
|
||||
bool canAccess = mSessionStorage->CanAccess(principal);
|
||||
NS_ASSERTION(canAccess,
|
||||
"This window owned sessionStorage "
|
||||
"that could not be accessed!");
|
||||
if (!canAccess) {
|
||||
mSessionStorage = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10407,14 +10404,17 @@ nsGlobalWindow::GetSessionStorage(ErrorResult& aError)
|
|||
|
||||
nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(docShell);
|
||||
|
||||
aError = storageManager->CreateStorage(principal,
|
||||
documentURI,
|
||||
nsCOMPtr<nsIDOMStorage> storage;
|
||||
aError = storageManager->CreateStorage(this, principal, documentURI,
|
||||
loadContext && loadContext->UsePrivateBrowsing(),
|
||||
getter_AddRefs(mSessionStorage));
|
||||
getter_AddRefs(storage));
|
||||
if (aError.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mSessionStorage = static_cast<DOMStorage*>(storage.get());
|
||||
MOZ_ASSERT(mSessionStorage);
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
if (PR_LOG_TEST(gDOMLeakPRLog, PR_LOG_DEBUG)) {
|
||||
PR_LogPrint("nsGlobalWindow %p tried to get a new sessionStorage %p", this, mSessionStorage.get());
|
||||
|
@ -10437,7 +10437,7 @@ nsGlobalWindow::GetSessionStorage(ErrorResult& aError)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalWindow::GetSessionStorage(nsIDOMStorage ** aSessionStorage)
|
||||
nsGlobalWindow::GetSessionStorage(nsISupports** aSessionStorage)
|
||||
{
|
||||
ErrorResult rv;
|
||||
nsCOMPtr<nsIDOMStorage> storage = GetSessionStorage(rv);
|
||||
|
@ -10446,7 +10446,7 @@ nsGlobalWindow::GetSessionStorage(nsIDOMStorage ** aSessionStorage)
|
|||
return rv.ErrorCode();
|
||||
}
|
||||
|
||||
nsIDOMStorage*
|
||||
DOMStorage*
|
||||
nsGlobalWindow::GetLocalStorage(ErrorResult& aError)
|
||||
{
|
||||
FORWARD_TO_INNER_OR_THROW(GetLocalStorage, (aError), aError, nullptr);
|
||||
|
@ -10489,17 +10489,23 @@ nsGlobalWindow::GetLocalStorage(ErrorResult& aError)
|
|||
nsIDocShell* docShell = GetDocShell();
|
||||
nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(docShell);
|
||||
|
||||
aError = storageManager->CreateStorage(principal,
|
||||
documentURI,
|
||||
nsCOMPtr<nsIDOMStorage> storage;
|
||||
aError = storageManager->CreateStorage(this, principal, documentURI,
|
||||
loadContext && loadContext->UsePrivateBrowsing(),
|
||||
getter_AddRefs(mLocalStorage));
|
||||
getter_AddRefs(storage));
|
||||
if (aError.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mLocalStorage = static_cast<DOMStorage*>(storage.get());
|
||||
MOZ_ASSERT(mLocalStorage);
|
||||
}
|
||||
|
||||
return mLocalStorage;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalWindow::GetLocalStorage(nsIDOMStorage ** aLocalStorage)
|
||||
nsGlobalWindow::GetLocalStorage(nsISupports** aLocalStorage)
|
||||
{
|
||||
NS_ENSURE_ARG(aLocalStorage);
|
||||
|
||||
|
@ -11286,34 +11292,34 @@ nsGlobalWindow::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMStorage> changingStorage = event->GetStorageArea();
|
||||
nsRefPtr<DOMStorage> changingStorage = event->GetStorageArea();
|
||||
if (!changingStorage) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMStorage> istorage = changingStorage.get();
|
||||
|
||||
bool fireMozStorageChanged = false;
|
||||
principal = GetPrincipal();
|
||||
if (!principal) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMStorage> pistorage = do_QueryInterface(changingStorage);
|
||||
|
||||
nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(GetDocShell());
|
||||
bool isPrivate = loadContext && loadContext->UsePrivateBrowsing();
|
||||
if (pistorage->IsPrivate() != isPrivate) {
|
||||
if (changingStorage->IsPrivate() != isPrivate) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
switch (pistorage->GetType())
|
||||
switch (changingStorage->GetType())
|
||||
{
|
||||
case nsPIDOMStorage::SessionStorage:
|
||||
case DOMStorage::SessionStorage:
|
||||
{
|
||||
bool check = false;
|
||||
|
||||
nsCOMPtr<nsIDOMStorageManager> storageManager = do_QueryInterface(GetDocShell());
|
||||
if (storageManager) {
|
||||
rv = storageManager->CheckStorage(principal, changingStorage, &check);
|
||||
rv = storageManager->CheckStorage(principal, istorage, &check);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -11327,19 +11333,20 @@ nsGlobalWindow::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
|
||||
#ifdef PR_LOGGING
|
||||
if (PR_LOG_TEST(gDOMLeakPRLog, PR_LOG_DEBUG)) {
|
||||
PR_LogPrint("nsGlobalWindow %p with sessionStorage %p passing event from %p", this, mSessionStorage.get(), pistorage.get());
|
||||
PR_LogPrint("nsGlobalWindow %p with sessionStorage %p passing event from %p",
|
||||
this, mSessionStorage.get(), changingStorage.get());
|
||||
}
|
||||
#endif
|
||||
|
||||
fireMozStorageChanged = SameCOMIdentity(mSessionStorage, changingStorage);
|
||||
fireMozStorageChanged = mSessionStorage == changingStorage;
|
||||
break;
|
||||
}
|
||||
|
||||
case nsPIDOMStorage::LocalStorage:
|
||||
case DOMStorage::LocalStorage:
|
||||
{
|
||||
// Allow event fire only for the same principal storages
|
||||
// XXX We have to use EqualsIgnoreDomain after bug 495337 lands
|
||||
nsIPrincipal* storagePrincipal = pistorage->GetPrincipal();
|
||||
nsIPrincipal* storagePrincipal = changingStorage->GetPrincipal();
|
||||
|
||||
bool equals = false;
|
||||
rv = storagePrincipal->Equals(principal, &equals);
|
||||
|
@ -11348,7 +11355,7 @@ nsGlobalWindow::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
if (!equals)
|
||||
return NS_OK;
|
||||
|
||||
fireMozStorageChanged = SameCOMIdentity(mLocalStorage, changingStorage);
|
||||
fireMozStorageChanged = mLocalStorage == changingStorage;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -915,8 +915,8 @@ public:
|
|||
mozilla::ErrorResult& aError);
|
||||
void Btoa(const nsAString& aBinaryData, nsAString& aAsciiBase64String,
|
||||
mozilla::ErrorResult& aError);
|
||||
nsIDOMStorage* GetSessionStorage(mozilla::ErrorResult& aError);
|
||||
nsIDOMStorage* GetLocalStorage(mozilla::ErrorResult& aError);
|
||||
mozilla::dom::DOMStorage* GetSessionStorage(mozilla::ErrorResult& aError);
|
||||
mozilla::dom::DOMStorage* GetLocalStorage(mozilla::ErrorResult& aError);
|
||||
mozilla::dom::Selection* GetSelection(mozilla::ErrorResult& aError);
|
||||
mozilla::dom::indexedDB::IDBFactory* GetIndexedDB(mozilla::ErrorResult& aError);
|
||||
already_AddRefed<nsICSSDeclaration>
|
||||
|
@ -1545,8 +1545,8 @@ protected:
|
|||
// it wouldn't see the ~External function's declaration.
|
||||
nsCOMPtr<nsISupports> mExternal;
|
||||
|
||||
nsCOMPtr<nsIDOMStorage> mLocalStorage;
|
||||
nsCOMPtr<nsIDOMStorage> mSessionStorage;
|
||||
nsRefPtr<mozilla::dom::DOMStorage> mLocalStorage;
|
||||
nsRefPtr<mozilla::dom::DOMStorage> mSessionStorage;
|
||||
|
||||
// These member variable are used only on inner windows.
|
||||
nsRefPtr<mozilla::EventListenerManager> mListenerManager;
|
||||
|
|
|
@ -1083,6 +1083,10 @@ DOMInterfaces = {
|
|||
'resultNotAddRefed': [ '__indexedGetter' ],
|
||||
},
|
||||
|
||||
'Storage': {
|
||||
'nativeType': 'mozilla::dom::DOMStorage',
|
||||
},
|
||||
|
||||
'StyleSheet': {
|
||||
'nativeType': 'mozilla::CSSStyleSheet',
|
||||
},
|
||||
|
|
|
@ -76,7 +76,16 @@ function test()
|
|||
is(doc.documentElement.getAttribute("data-foo"), "baz",
|
||||
"Attribute setter should have been called again");
|
||||
|
||||
// XXXbz no way yet to test non-overridebuiltins stuff with named setter
|
||||
// Test non-overridebuiltins binding with named setter
|
||||
var s = doc.defaultView.localStorage;
|
||||
s["test_proxies_via_xray"] = "bar";
|
||||
// Check that this actually got passed on to the underlying object.
|
||||
is(s.wrappedJSObject["test_proxies_via_xray"], "bar",
|
||||
"Set should get forwarded to the underlying object without overridebuiltins");
|
||||
s["test_proxies_via_xray"] = "baz";
|
||||
// Check that this actually got passed on to the underlying object.
|
||||
is(s.wrappedJSObject["test_proxies_via_xray"], "baz",
|
||||
"Set should get forwarded to the underlying object again without overridebuiltins");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/StorageEvent.h"
|
||||
#include "nsIDOMStorage.h"
|
||||
#include "mozilla/dom/DOMStorage.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -85,7 +85,7 @@ StorageEvent::InitStorageEvent(const nsAString& aType, bool aCanBubble,
|
|||
const nsAString& aOldValue,
|
||||
const nsAString& aNewValue,
|
||||
const nsAString& aURL,
|
||||
nsIDOMStorage* aStorageArea,
|
||||
DOMStorage* aStorageArea,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
aRv = InitEvent(aType, aCanBubble, aCancelable);
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
#include "mozilla/dom/Event.h"
|
||||
#include "mozilla/dom/StorageEventBinding.h"
|
||||
|
||||
class nsIDOMStorage;
|
||||
|
||||
// Helper for EventDispatcher.
|
||||
nsresult NS_NewDOMStorageEvent(nsIDOMEvent** aDOMEvent,
|
||||
mozilla::dom::EventTarget* aOwner);
|
||||
|
@ -22,6 +20,8 @@ nsresult NS_NewDOMStorageEvent(nsIDOMEvent** aDOMEvent,
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class DOMStorage;
|
||||
|
||||
class StorageEvent : public Event
|
||||
{
|
||||
public:
|
||||
|
@ -37,7 +37,7 @@ protected:
|
|||
nsString mOldValue;
|
||||
nsString mNewValue;
|
||||
nsString mUrl;
|
||||
nsCOMPtr<nsIDOMStorage> mStorageArea;
|
||||
nsRefPtr<DOMStorage> mStorageArea;
|
||||
|
||||
public:
|
||||
virtual StorageEvent* AsStorageEvent();
|
||||
|
@ -57,7 +57,7 @@ public:
|
|||
const nsAString& aOldValue,
|
||||
const nsAString& aNewValue,
|
||||
const nsAString& aURL,
|
||||
nsIDOMStorage* aStorageArea,
|
||||
DOMStorage* aStorageArea,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void GetKey(nsString& aRetVal) const
|
||||
|
@ -80,7 +80,7 @@ public:
|
|||
aRetVal = mUrl;
|
||||
}
|
||||
|
||||
nsIDOMStorage* GetStorageArea() const
|
||||
DOMStorage* GetStorageArea() const
|
||||
{
|
||||
return mStorageArea;
|
||||
}
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
# THIS FILE IS AUTOGENERATED BY parseFailures.py - DO NOT EDIT
|
||||
[DEFAULT]
|
||||
support-files =
|
||||
|
||||
|
||||
[test_missing_arguments.html.json]
|
||||
[test_storage_local_builtins.html.json]
|
||||
[test_storage_local_in_js.html.json]
|
||||
[test_storage_local_removeitem_js.html.json]
|
||||
[test_storage_session_builtins.html.json]
|
||||
[test_storage_session_in_js.html.json]
|
||||
[test_storage_session_removeitem_js.html.json]
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"Should throw TypeError for function \"function () { localStorage.key(); }\".": true,
|
||||
"Should throw TypeError for function \"function () { localStorage.getItem(); }\".": true,
|
||||
"Should throw TypeError for function \"function () { localStorage.setItem(); }\".": true,
|
||||
"Should throw TypeError for function \"function () { localStorage.setItem(\"a\"); }\".": true,
|
||||
"Should throw TypeError for function \"function () { localStorage.removeItem(); }\".": true,
|
||||
"Should throw TypeError for function \"function () { sessionStorage.key(); }\".": true,
|
||||
"Should throw TypeError for function \"function () { sessionStorage.getItem(); }\".": true,
|
||||
"Should throw TypeError for function \"function () { sessionStorage.setItem(); }\".": true,
|
||||
"Should throw TypeError for function \"function () { sessionStorage.setItem(\"a\"); }\".": true,
|
||||
"Should throw TypeError for function \"function () { sessionStorage.removeItem(); }\".": true
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"Web Storage": true
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"Web Storage 1": true
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"Web Storage 2": true,
|
||||
"Web Storage 3": true
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"Web Storage": true
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"Web Storage 1": true
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"Web Storage 2": true,
|
||||
"Web Storage 3": true
|
||||
}
|
|
@ -32,6 +32,5 @@ MOCHITEST_MANIFESTS += [
|
|||
'failures/html/microdata/microdata-dom-api/mochitest.ini',
|
||||
'failures/html/typedarrays/mochitest.ini',
|
||||
'failures/webapps/WebStorage/tests/submissions/Infraware/mochitest.ini',
|
||||
'failures/webapps/WebStorage/tests/submissions/Ms2ger/mochitest.ini',
|
||||
'failures/webapps/XMLHttpRequest/tests/submissions/Ms2ger/mochitest.ini',
|
||||
]
|
||||
|
|
|
@ -10,7 +10,6 @@ interface nsIControllers;
|
|||
interface nsIDOMBlob;
|
||||
interface nsIDOMLocation;
|
||||
interface nsIDOMOfflineResourceList;
|
||||
interface nsIDOMStorage;
|
||||
interface nsIPrompt;
|
||||
interface nsISelection;
|
||||
interface nsIVariant;
|
||||
|
@ -24,7 +23,7 @@ interface nsIVariant;
|
|||
* @see <http://www.whatwg.org/html/#window>
|
||||
*/
|
||||
|
||||
[scriptable, uuid(d4316591-d16e-405c-8093-b441cbef3230)]
|
||||
[scriptable, uuid(c3ff0328-6c47-4e64-a22f-ac221959e258)]
|
||||
interface nsIDOMWindow : nsISupports
|
||||
{
|
||||
// the current browsing context
|
||||
|
@ -241,15 +240,17 @@ interface nsIDOMWindow : nsISupports
|
|||
// WindowSessionStorage
|
||||
/**
|
||||
* Session storage for the current browsing context.
|
||||
* This attribute is a DOMStorage
|
||||
*/
|
||||
readonly attribute nsIDOMStorage sessionStorage;
|
||||
readonly attribute nsISupports sessionStorage;
|
||||
|
||||
|
||||
// WindowLocalStorage
|
||||
/**
|
||||
* Local storage for the current browsing context.
|
||||
* This attribute is a DOMStorage
|
||||
*/
|
||||
readonly attribute nsIDOMStorage localStorage;
|
||||
readonly attribute nsISupports localStorage;
|
||||
|
||||
|
||||
// IndexedDB
|
||||
|
|
|
@ -10,8 +10,3 @@ XPIDL_SOURCES += [
|
|||
]
|
||||
|
||||
XPIDL_MODULE = 'dom_storage'
|
||||
|
||||
EXPORTS += [
|
||||
'nsPIDOMStorage.h',
|
||||
]
|
||||
|
||||
|
|
|
@ -6,63 +6,11 @@
|
|||
#include "domstubs.idl"
|
||||
|
||||
/**
|
||||
* Interface for client side storage. See
|
||||
* http://www.whatwg.org/specs/web-apps/current-work/multipage/structured.html#storage0
|
||||
* for more information.
|
||||
*
|
||||
* A storage object stores an arbitrary set of key-value pairs, which
|
||||
* may be retrieved, modified and removed as needed. A key may only
|
||||
* exist once within a storage object, and only one value may be
|
||||
* associated with a particular key. Keys are stored in a particular
|
||||
* order with the condition that this order not change by merely changing
|
||||
* the value associated with a key, but the order may change when a
|
||||
* key is added or removed.
|
||||
* Empty interface for client side storage. DOMStorage is now ported to WebIDL
|
||||
* but we still need an XPConnect interface for casting.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(43E5EDAD-1E02-42c4-9D99-C3D9DEE22A20)]
|
||||
[scriptable, uuid(425a33f0-e0e9-45e7-a95f-9908bd6ae988)]
|
||||
interface nsIDOMStorage : nsISupports
|
||||
{
|
||||
/**
|
||||
* The number of keys stored.
|
||||
*/
|
||||
readonly attribute unsigned long length;
|
||||
|
||||
/**
|
||||
* Retrieve the name of the key at a particular index.
|
||||
*
|
||||
* @param index index of the item to retrieve
|
||||
* @returns the key at index, null if there is no key at that index
|
||||
*/
|
||||
DOMString key(in unsigned long index);
|
||||
|
||||
/**
|
||||
* Retrieve an item with a given key
|
||||
*
|
||||
* @param key key to retrieve
|
||||
* @returns found data or empty string if the key was not found
|
||||
*/
|
||||
DOMString getItem([Null(Stringify)] in DOMString key);
|
||||
|
||||
/**
|
||||
* Assign a value with a key. If the key does not exist already, a new
|
||||
* key is added associated with that value. If the key already exists,
|
||||
* then the existing value is replaced with a new value.
|
||||
*
|
||||
* @param key key to set
|
||||
* @param data data to associate with the key
|
||||
*/
|
||||
void setItem([Null(Stringify)] in DOMString key, [Null(Stringify)] in DOMString data);
|
||||
|
||||
/**
|
||||
* Remove a key and its corresponding value.
|
||||
*
|
||||
* @param key key to remove
|
||||
*/
|
||||
void removeItem([Null(Stringify)] in DOMString key);
|
||||
|
||||
/**
|
||||
* Clear the content of this storage bound to a domain
|
||||
* or an origin.
|
||||
*/
|
||||
void clear();
|
||||
};
|
||||
|
|
|
@ -7,13 +7,14 @@
|
|||
|
||||
interface nsIDOMStorage;
|
||||
interface nsIPrincipal;
|
||||
interface nsIDOMWindow;
|
||||
|
||||
/**
|
||||
* General purpose interface that has two implementations, for localStorage
|
||||
* resp. sessionStorage with "@mozilla.org/dom/localStorage-manager;1" resp.
|
||||
* "@mozilla.org/dom/sessionStorage-manager;1" contract IDs.
|
||||
*/
|
||||
[scriptable, uuid(8096f9ea-fa61-4960-b5d7-fb30ac42c8d8)]
|
||||
[scriptable, uuid(a15f7ebd-4f35-4e73-a2d8-255d27fd14ee)]
|
||||
interface nsIDOMStorageManager : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -27,6 +28,8 @@ interface nsIDOMStorageManager : nsISupports
|
|||
* A new object is always returned and it is ensured there is
|
||||
* a storage for the scope created.
|
||||
*
|
||||
* @param aWindow
|
||||
* The parent window.
|
||||
* @param aPrincipal
|
||||
* Principal to bound storage to.
|
||||
* @param aDocumentURI
|
||||
|
@ -34,7 +37,8 @@ interface nsIDOMStorageManager : nsISupports
|
|||
* @param aPrivate
|
||||
* Whether the demanding document is running in Private Browsing mode or not.
|
||||
*/
|
||||
nsIDOMStorage createStorage(in nsIPrincipal aPrincipal,
|
||||
nsIDOMStorage createStorage(in nsIDOMWindow aWindow,
|
||||
in nsIPrincipal aPrincipal,
|
||||
in DOMString aDocumentURI,
|
||||
[optional] in bool aPrivate);
|
||||
/**
|
||||
|
@ -43,12 +47,15 @@ interface nsIDOMStorageManager : nsISupports
|
|||
* no object is created. Otherwise, an object (new) for the existing storage
|
||||
* scope is returned.
|
||||
*
|
||||
* @param aWindow
|
||||
* The parent window.
|
||||
* @param aPrincipal
|
||||
* Principal to bound storage to.
|
||||
* @param aPrivate
|
||||
* Whether the demanding document is running in Private Browsing mode or not.
|
||||
*/
|
||||
nsIDOMStorage getStorage(in nsIPrincipal aPrincipal,
|
||||
nsIDOMStorage getStorage(in nsIDOMWindow aWindow,
|
||||
in nsIPrincipal aPrincipal,
|
||||
[optional] in bool aPrivate);
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=2 et tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef __nsPIDOMStorage_h_
|
||||
#define __nsPIDOMStorage_h_
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
class nsIPrincipal;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class DOMStorageCache;
|
||||
class DOMStorageManager;
|
||||
|
||||
} // ::dom
|
||||
} // ::mozilla
|
||||
|
||||
// {09198A51-5D27-4992-97E4-38A9CEA2A65D}
|
||||
#define NS_PIDOMSTORAGE_IID \
|
||||
{ 0x9198a51, 0x5d27, 0x4992, \
|
||||
{ 0x97, 0xe4, 0x38, 0xa9, 0xce, 0xa2, 0xa6, 0x5d } }
|
||||
|
||||
class nsPIDOMStorage : public nsISupports
|
||||
{
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_PIDOMSTORAGE_IID)
|
||||
|
||||
enum StorageType {
|
||||
LocalStorage = 1,
|
||||
SessionStorage = 2
|
||||
};
|
||||
|
||||
virtual StorageType GetType() const = 0;
|
||||
virtual mozilla::dom::DOMStorageManager* GetManager() const = 0;
|
||||
virtual const mozilla::dom::DOMStorageCache* GetCache() const = 0;
|
||||
|
||||
virtual nsTArray<nsString>* GetKeys() = 0;
|
||||
|
||||
virtual nsIPrincipal* GetPrincipal() = 0;
|
||||
virtual bool PrincipalEquals(nsIPrincipal* principal) = 0;
|
||||
virtual bool CanAccess(nsIPrincipal *aPrincipal) = 0;
|
||||
virtual bool IsPrivate() = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsPIDOMStorage, NS_PIDOMSTORAGE_IID)
|
||||
|
||||
#endif // __nsPIDOMStorage_h_
|
|
@ -7,42 +7,44 @@
|
|||
#include "DOMStorageCache.h"
|
||||
#include "DOMStorageManager.h"
|
||||
|
||||
#include "mozilla/dom/StorageEvent.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIPermissionManager.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsICookiePermission.h"
|
||||
|
||||
#include "nsDOMClassInfoID.h"
|
||||
#include "mozilla/dom/StorageBinding.h"
|
||||
#include "mozilla/dom/StorageEvent.h"
|
||||
#include "mozilla/dom/StorageEventBinding.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
|
||||
DOMCI_DATA(Storage, mozilla::dom::DOMStorage)
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_ADDREF(DOMStorage)
|
||||
NS_IMPL_RELEASE(DOMStorage)
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMStorage, mManager, mPrincipal, mWindow)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(DOMStorage)
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMStorage)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMStorage)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMStorage)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMStorage)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMStorage)
|
||||
NS_INTERFACE_MAP_ENTRY(nsPIDOMStorage)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Storage)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
DOMStorage::DOMStorage(DOMStorageManager* aManager,
|
||||
DOMStorage::DOMStorage(nsIDOMWindow* aWindow,
|
||||
DOMStorageManager* aManager,
|
||||
DOMStorageCache* aCache,
|
||||
const nsAString& aDocumentURI,
|
||||
nsIPrincipal* aPrincipal,
|
||||
bool aIsPrivate)
|
||||
: mManager(aManager)
|
||||
: mWindow(aWindow)
|
||||
, mManager(aManager)
|
||||
, mCache(aCache)
|
||||
, mDocumentURI(aDocumentURI)
|
||||
, mPrincipal(aPrincipal)
|
||||
|
@ -50,6 +52,7 @@ DOMStorage::DOMStorage(DOMStorageManager* aManager,
|
|||
, mIsSessionOnly(false)
|
||||
{
|
||||
mCache->Preload();
|
||||
SetIsDOMBinding();
|
||||
}
|
||||
|
||||
DOMStorage::~DOMStorage()
|
||||
|
@ -57,43 +60,54 @@ DOMStorage::~DOMStorage()
|
|||
mCache->KeepAlive();
|
||||
}
|
||||
|
||||
// nsIDOMStorage (web content public API implementation)
|
||||
|
||||
NS_IMETHODIMP
|
||||
DOMStorage::GetLength(uint32_t* aLength)
|
||||
/* virtual */ JSObject*
|
||||
DOMStorage::WrapObject(JSContext* aCx)
|
||||
{
|
||||
if (!CanUseStorage(this)) {
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
|
||||
return mCache->GetLength(this, aLength);
|
||||
return StorageBinding::Wrap(aCx, this);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
DOMStorage::Key(uint32_t aIndex, nsAString& aRetval)
|
||||
uint32_t
|
||||
DOMStorage::GetLength(ErrorResult& aRv)
|
||||
{
|
||||
if (!CanUseStorage(this)) {
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return mCache->GetKey(this, aIndex, aRetval);
|
||||
uint32_t length;
|
||||
aRv = mCache->GetLength(this, &length);
|
||||
return length;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
DOMStorage::GetItem(const nsAString& aKey, nsAString& aRetval)
|
||||
void
|
||||
DOMStorage::Key(uint32_t aIndex, nsAString& aResult, ErrorResult& aRv)
|
||||
{
|
||||
if (!CanUseStorage(this)) {
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
return mCache->GetItem(this, aKey, aRetval);
|
||||
aRv = mCache->GetKey(this, aIndex, aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
DOMStorage::SetItem(const nsAString& aKey, const nsAString& aData)
|
||||
void
|
||||
DOMStorage::GetItem(const nsAString& aKey, nsAString& aResult, ErrorResult& aRv)
|
||||
{
|
||||
if (!CanUseStorage(this)) {
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
aRv = mCache->GetItem(this, aKey, aResult);
|
||||
}
|
||||
|
||||
void
|
||||
DOMStorage::SetItem(const nsAString& aKey, const nsAString& aData,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (!CanUseStorage(this)) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
Telemetry::Accumulate(GetType() == LocalStorage
|
||||
|
@ -105,58 +119,57 @@ DOMStorage::SetItem(const nsAString& aKey, const nsAString& aData)
|
|||
|
||||
nsString data;
|
||||
bool ok = data.Assign(aData, fallible_t());
|
||||
NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
|
||||
if (!ok) {
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
nsString old;
|
||||
nsresult rv = mCache->SetItem(this, aKey, data, old);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
aRv = mCache->SetItem(this, aKey, data, old);
|
||||
if (aRv.Failed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (rv != NS_SUCCESS_DOM_NO_OPERATION) {
|
||||
if (aRv.ErrorCode() != NS_SUCCESS_DOM_NO_OPERATION) {
|
||||
BroadcastChangeNotification(aKey, old, aData);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
DOMStorage::RemoveItem(const nsAString& aKey)
|
||||
void
|
||||
DOMStorage::RemoveItem(const nsAString& aKey, ErrorResult& aRv)
|
||||
{
|
||||
if (!CanUseStorage(this)) {
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoString old;
|
||||
nsresult rv = mCache->RemoveItem(this, aKey, old);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
aRv = mCache->RemoveItem(this, aKey, old);
|
||||
if (aRv.Failed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (rv != NS_SUCCESS_DOM_NO_OPERATION) {
|
||||
if (aRv.ErrorCode() != NS_SUCCESS_DOM_NO_OPERATION) {
|
||||
BroadcastChangeNotification(aKey, old, NullString());
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
DOMStorage::Clear()
|
||||
void
|
||||
DOMStorage::Clear(ErrorResult& aRv)
|
||||
{
|
||||
if (!CanUseStorage(this)) {
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
nsresult rv = mCache->Clear(this);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
aRv = mCache->Clear(this);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (rv != NS_SUCCESS_DOM_NO_OPERATION) {
|
||||
if (aRv.ErrorCode() != NS_SUCCESS_DOM_NO_OPERATION) {
|
||||
BroadcastChangeNotification(NullString(), NullString(), NullString());
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
@ -199,7 +212,7 @@ DOMStorage::BroadcastChangeNotification(const nsSubstring& aKey,
|
|||
dict.mKey = aKey;
|
||||
dict.mNewValue = aNewValue;
|
||||
dict.mOldValue = aOldValue;
|
||||
dict.mStorageArea = static_cast<nsIDOMStorage*>(this);
|
||||
dict.mStorageArea = this;
|
||||
dict.mUrl = mDocumentURI;
|
||||
|
||||
// Note, this DOM event should never reach JS. It is cloned later in
|
||||
|
@ -285,9 +298,7 @@ DOMStorage::CanUseStorage(DOMStorage* aStorage)
|
|||
return true;
|
||||
}
|
||||
|
||||
// nsPIDOMStorage
|
||||
|
||||
nsPIDOMStorage::StorageType
|
||||
DOMStorage::StorageType
|
||||
DOMStorage::GetType() const
|
||||
{
|
||||
return mManager->Type();
|
||||
|
@ -315,14 +326,16 @@ DOMStorage::CanAccess(nsIPrincipal* aPrincipal)
|
|||
return !aPrincipal || aPrincipal->Subsumes(mPrincipal);
|
||||
}
|
||||
|
||||
nsTArray<nsString>*
|
||||
DOMStorage::GetKeys()
|
||||
void
|
||||
DOMStorage::GetSupportedNames(unsigned, nsTArray<nsString>& aKeys)
|
||||
{
|
||||
if (!CanUseStorage(this)) {
|
||||
return new nsTArray<nsString>(); // return just an empty array
|
||||
// return just an empty array
|
||||
aKeys.Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
return mCache->GetKeys(this);
|
||||
mCache->GetKeys(this, aKeys);
|
||||
}
|
||||
|
||||
} // ::dom
|
||||
|
|
|
@ -7,10 +7,16 @@
|
|||
#define nsDOMStorage_h___
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "nsIDOMStorage.h"
|
||||
#include "nsPIDOMStorage.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "nsISupports.h"
|
||||
|
||||
class nsIPrincipal;
|
||||
class nsIDOMWindow;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -18,30 +24,96 @@ namespace dom {
|
|||
class DOMStorageManager;
|
||||
class DOMStorageCache;
|
||||
|
||||
class DOMStorage MOZ_FINAL : public nsIDOMStorage
|
||||
, public nsPIDOMStorage
|
||||
, public nsSupportsWeakReference
|
||||
class DOMStorage MOZ_FINAL
|
||||
: public nsIDOMStorage
|
||||
, public nsSupportsWeakReference
|
||||
, public nsWrapperCache
|
||||
{
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDOMSTORAGE
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(DOMStorage,
|
||||
nsIDOMStorage)
|
||||
|
||||
// nsPIDOMStorage
|
||||
virtual StorageType GetType() const MOZ_OVERRIDE;
|
||||
virtual DOMStorageManager* GetManager() const MOZ_OVERRIDE { return mManager; }
|
||||
virtual const DOMStorageCache* GetCache() const MOZ_OVERRIDE { return mCache; }
|
||||
enum StorageType {
|
||||
LocalStorage = 1,
|
||||
SessionStorage = 2
|
||||
};
|
||||
|
||||
virtual nsTArray<nsString>* GetKeys() MOZ_OVERRIDE;
|
||||
virtual nsIPrincipal* GetPrincipal() MOZ_OVERRIDE;
|
||||
virtual bool PrincipalEquals(nsIPrincipal* aPrincipal) MOZ_OVERRIDE;
|
||||
virtual bool CanAccess(nsIPrincipal* aPrincipal) MOZ_OVERRIDE;
|
||||
virtual bool IsPrivate() MOZ_OVERRIDE { return mIsPrivate; }
|
||||
StorageType GetType() const;
|
||||
|
||||
DOMStorage(DOMStorageManager* aManager,
|
||||
DOMStorageManager* GetManager() const
|
||||
{
|
||||
return mManager;
|
||||
}
|
||||
|
||||
DOMStorageCache const* GetCache() const
|
||||
{
|
||||
return mCache;
|
||||
}
|
||||
|
||||
nsIPrincipal* GetPrincipal();
|
||||
bool PrincipalEquals(nsIPrincipal* aPrincipal);
|
||||
bool CanAccess(nsIPrincipal* aPrincipal);
|
||||
bool IsPrivate()
|
||||
{
|
||||
return mIsPrivate;
|
||||
}
|
||||
|
||||
DOMStorage(nsIDOMWindow* aWindow,
|
||||
DOMStorageManager* aManager,
|
||||
DOMStorageCache* aCache,
|
||||
const nsAString& aDocumentURI,
|
||||
nsIPrincipal* aPrincipal,
|
||||
bool aIsPrivate);
|
||||
|
||||
// WebIDL
|
||||
JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||
|
||||
nsIDOMWindow* GetParentObject() const
|
||||
{
|
||||
return mWindow;
|
||||
}
|
||||
|
||||
uint32_t GetLength(ErrorResult& aRv);
|
||||
|
||||
void Key(uint32_t aIndex, nsAString& aResult, ErrorResult& aRv);
|
||||
|
||||
void GetItem(const nsAString& aKey, nsAString& aResult, ErrorResult& aRv);
|
||||
|
||||
bool NameIsEnumerable(const nsAString& aName) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void GetSupportedNames(unsigned, nsTArray<nsString>& aKeys);
|
||||
|
||||
void NamedGetter(const nsAString& aKey, bool& aFound, nsAString& aResult,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
GetItem(aKey, aResult, aRv);
|
||||
aFound = !aResult.IsVoid();
|
||||
}
|
||||
|
||||
void SetItem(const nsAString& aKey, const nsAString& aValue,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void NamedSetter(const nsAString& aKey, const nsAString& aValue,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
SetItem(aKey, aValue, aRv);
|
||||
}
|
||||
|
||||
void RemoveItem(const nsAString& aKey, ErrorResult& aRv);
|
||||
|
||||
void NamedDeleter(const nsAString& aKey, bool& aFound, ErrorResult& aRv)
|
||||
{
|
||||
RemoveItem(aKey, aRv);
|
||||
|
||||
aFound = (aRv.ErrorCode() != NS_SUCCESS_DOM_NO_OPERATION);
|
||||
}
|
||||
|
||||
void Clear(ErrorResult& aRv);
|
||||
|
||||
// The method checks whether the caller can use a storage.
|
||||
// CanUseStorage is called before any DOM initiated operation
|
||||
// on a storage is about to happen and ensures that the storage's
|
||||
|
@ -60,6 +132,7 @@ private:
|
|||
friend class DOMStorageManager;
|
||||
friend class DOMStorageCache;
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> mWindow;
|
||||
nsRefPtr<DOMStorageManager> mManager;
|
||||
nsRefPtr<DOMStorageCache> mCache;
|
||||
nsString mDocumentURI;
|
||||
|
|
|
@ -428,8 +428,8 @@ KeysArrayBuilder(const nsAString& aKey, const nsString aValue, void* aArg)
|
|||
|
||||
} // anon
|
||||
|
||||
nsTArray<nsString>*
|
||||
DOMStorageCache::GetKeys(const DOMStorage* aStorage)
|
||||
void
|
||||
DOMStorageCache::GetKeys(const DOMStorage* aStorage, nsTArray<nsString>& aKeys)
|
||||
{
|
||||
Telemetry::AutoTimer<Telemetry::LOCALDOMSTORAGE_GETALLKEYS_MS> autoTimer;
|
||||
|
||||
|
@ -437,12 +437,11 @@ DOMStorageCache::GetKeys(const DOMStorage* aStorage)
|
|||
WaitForPreload(Telemetry::LOCALDOMSTORAGE_GETALLKEYS_BLOCKING_MS);
|
||||
}
|
||||
|
||||
nsTArray<nsString>* result = new nsTArray<nsString>();
|
||||
if (NS_SUCCEEDED(mLoadResult)) {
|
||||
DataSet(aStorage).mKeys.EnumerateRead(KeysArrayBuilder, result);
|
||||
if (NS_FAILED(mLoadResult)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return result;
|
||||
DataSet(aStorage).mKeys.EnumerateRead(KeysArrayBuilder, &aKeys);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -98,7 +98,7 @@ public:
|
|||
nsresult RemoveItem(const DOMStorage* aStorage, const nsAString& aKey, nsString& aOld);
|
||||
nsresult Clear(const DOMStorage* aStorage);
|
||||
|
||||
nsTArray<nsString>* GetKeys(const DOMStorage* aStorage);
|
||||
void GetKeys(const DOMStorage* aStorage, nsTArray<nsString>& aKeys);
|
||||
|
||||
// Whether the principal equals principal the cache was created for
|
||||
bool CheckPrincipal(nsIPrincipal* aPrincipal) const;
|
||||
|
|
|
@ -97,7 +97,7 @@ PrincipalsEqual(nsIPrincipal* aObjectPrincipal, nsIPrincipal* aSubjectPrincipal)
|
|||
NS_IMPL_ISUPPORTS(DOMStorageManager,
|
||||
nsIDOMStorageManager)
|
||||
|
||||
DOMStorageManager::DOMStorageManager(nsPIDOMStorage::StorageType aType)
|
||||
DOMStorageManager::DOMStorageManager(DOMStorage::StorageType aType)
|
||||
: mCaches(10)
|
||||
, mType(aType)
|
||||
, mLowDiskSpace(false)
|
||||
|
@ -325,6 +325,7 @@ DOMStorageManager::DropCache(DOMStorageCache* aCache)
|
|||
|
||||
nsresult
|
||||
DOMStorageManager::GetStorageInternal(bool aCreate,
|
||||
nsIDOMWindow* aWindow,
|
||||
nsIPrincipal* aPrincipal,
|
||||
const nsAString& aDocumentURI,
|
||||
bool aPrivate,
|
||||
|
@ -372,8 +373,9 @@ DOMStorageManager::GetStorageInternal(bool aCreate,
|
|||
}
|
||||
|
||||
if (aRetval) {
|
||||
*aRetval = new DOMStorage(this, cache, aDocumentURI, aPrincipal, aPrivate);
|
||||
NS_ADDREF(*aRetval);
|
||||
nsCOMPtr<nsIDOMStorage> storage = new DOMStorage(
|
||||
aWindow, this, cache, aDocumentURI, aPrincipal, aPrivate);
|
||||
storage.forget(aRetval);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -382,24 +384,29 @@ DOMStorageManager::GetStorageInternal(bool aCreate,
|
|||
NS_IMETHODIMP
|
||||
DOMStorageManager::PrecacheStorage(nsIPrincipal* aPrincipal)
|
||||
{
|
||||
return GetStorageInternal(true, aPrincipal, EmptyString(), false, nullptr);
|
||||
return GetStorageInternal(true, nullptr, aPrincipal, EmptyString(), false,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
DOMStorageManager::CreateStorage(nsIPrincipal* aPrincipal,
|
||||
DOMStorageManager::CreateStorage(nsIDOMWindow* aWindow,
|
||||
nsIPrincipal* aPrincipal,
|
||||
const nsAString& aDocumentURI,
|
||||
bool aPrivate,
|
||||
nsIDOMStorage** aRetval)
|
||||
{
|
||||
return GetStorageInternal(true, aPrincipal, aDocumentURI, aPrivate, aRetval);
|
||||
return GetStorageInternal(true, aWindow, aPrincipal, aDocumentURI, aPrivate,
|
||||
aRetval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
DOMStorageManager::GetStorage(nsIPrincipal* aPrincipal,
|
||||
DOMStorageManager::GetStorage(nsIDOMWindow* aWindow,
|
||||
nsIPrincipal* aPrincipal,
|
||||
bool aPrivate,
|
||||
nsIDOMStorage** aRetval)
|
||||
{
|
||||
return GetStorageInternal(false, aPrincipal, EmptyString(), aPrivate, aRetval);
|
||||
return GetStorageInternal(false, aWindow, aPrincipal, EmptyString(), aPrivate,
|
||||
aRetval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -410,12 +417,12 @@ DOMStorageManager::CloneStorage(nsIDOMStorage* aStorage)
|
|||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMStorage> pstorage = do_QueryInterface(aStorage);
|
||||
if (!pstorage) {
|
||||
nsRefPtr<DOMStorage> storage = static_cast<DOMStorage*>(aStorage);
|
||||
if (!storage) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
const DOMStorageCache* origCache = pstorage->GetCache();
|
||||
const DOMStorageCache* origCache = storage->GetCache();
|
||||
|
||||
DOMStorageCache* existingCache = GetCache(origCache->Scope());
|
||||
if (existingCache) {
|
||||
|
@ -437,8 +444,8 @@ DOMStorageManager::CheckStorage(nsIPrincipal* aPrincipal,
|
|||
nsIDOMStorage* aStorage,
|
||||
bool* aRetval)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMStorage> pstorage = do_QueryInterface(aStorage);
|
||||
if (!pstorage) {
|
||||
nsRefPtr<DOMStorage> storage = static_cast<DOMStorage*>(aStorage);
|
||||
if (!storage) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
|
@ -455,11 +462,11 @@ DOMStorageManager::CheckStorage(nsIPrincipal* aPrincipal,
|
|||
}
|
||||
|
||||
DOMStorageCache* cache = GetCache(scope);
|
||||
if (cache != pstorage->GetCache()) {
|
||||
if (cache != storage->GetCache()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!pstorage->PrincipalEquals(aPrincipal)) {
|
||||
if (!storage->PrincipalEquals(aPrincipal)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -479,7 +486,7 @@ DOMStorageManager::GetLocalStorageForPrincipal(nsIPrincipal* aPrincipal,
|
|||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
return CreateStorage(aPrincipal, aDocumentURI, aPrivate, aRetval);
|
||||
return CreateStorage(nullptr, aPrincipal, aDocumentURI, aPrivate, aRetval);
|
||||
}
|
||||
|
||||
namespace { // anon
|
||||
|
|
|
@ -9,20 +9,20 @@
|
|||
#include "nsIDOMStorageManager.h"
|
||||
#include "DOMStorageObserver.h"
|
||||
|
||||
#include "nsPIDOMStorage.h"
|
||||
#include "DOMStorageCache.h"
|
||||
#include "mozilla/dom/DOMStorage.h"
|
||||
|
||||
#include "nsTHashtable.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsHashKeys.h"
|
||||
|
||||
class nsIDOMWindow;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
const nsPIDOMStorage::StorageType SessionStorage = nsPIDOMStorage::SessionStorage;
|
||||
const nsPIDOMStorage::StorageType LocalStorage = nsPIDOMStorage::LocalStorage;
|
||||
|
||||
class DOMStorage;
|
||||
const DOMStorage::StorageType SessionStorage = DOMStorage::SessionStorage;
|
||||
const DOMStorage::StorageType LocalStorage = DOMStorage::LocalStorage;
|
||||
|
||||
class DOMStorageManager : public nsIDOMStorageManager
|
||||
, public DOMStorageObserverSink
|
||||
|
@ -31,7 +31,7 @@ class DOMStorageManager : public nsIDOMStorageManager
|
|||
NS_DECL_NSIDOMSTORAGEMANAGER
|
||||
|
||||
public:
|
||||
virtual nsPIDOMStorage::StorageType Type() { return mType; }
|
||||
virtual DOMStorage::StorageType Type() { return mType; }
|
||||
|
||||
// Reads the preference for DOM storage quota
|
||||
static uint32_t GetQuota();
|
||||
|
@ -41,7 +41,7 @@ public:
|
|||
already_AddRefed<DOMStorageUsage> GetScopeUsage(const nsACString& aScope);
|
||||
|
||||
protected:
|
||||
DOMStorageManager(nsPIDOMStorage::StorageType aType);
|
||||
DOMStorageManager(DOMStorage::StorageType aType);
|
||||
virtual ~DOMStorageManager();
|
||||
|
||||
private:
|
||||
|
@ -82,6 +82,7 @@ private:
|
|||
|
||||
// Helper for creation of DOM storage objects
|
||||
nsresult GetStorageInternal(bool aCreate,
|
||||
nsIDOMWindow* aWindow,
|
||||
nsIPrincipal* aPrincipal,
|
||||
const nsAString& aDocumentURI,
|
||||
bool aPrivate,
|
||||
|
@ -89,7 +90,7 @@ private:
|
|||
|
||||
// Scope->cache map
|
||||
nsTHashtable<DOMStorageCacheHashKey> mCaches;
|
||||
const nsPIDOMStorage::StorageType mType;
|
||||
const DOMStorage::StorageType mType;
|
||||
|
||||
// If mLowDiskSpace is true it indicates a low device storage situation and
|
||||
// so no localStorage writes are allowed. sessionStorage writes are still
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
EXPORTS.mozilla.dom += [
|
||||
'DOMStorage.h',
|
||||
'DOMStorageIPC.h',
|
||||
]
|
||||
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<div id="status"></div>
|
||||
</body>
|
||||
<script>
|
||||
addEventListener('message', function(e) {
|
||||
if (e.data == 'clear') {
|
||||
navigator.mozApps.getSelf().onsuccess = function() {
|
||||
this.result.clearBrowserData();
|
||||
document.body.innerHTML = "<done></done>";
|
||||
document.getElementById('status').textContent = 'done';
|
||||
};
|
||||
}
|
||||
});
|
||||
|
|
|
@ -164,13 +164,14 @@ function browserLoadEvent() {
|
|||
|
||||
function waitForClearBrowserData() {
|
||||
SimpleTest.executeSoon(function() {
|
||||
if (frames[1].document.getElementsByTagName('done').length == 0) {
|
||||
if (frames[1].document.getElementById('status').textContent != 'done') {
|
||||
waitForClearBrowserData();
|
||||
} else {
|
||||
checks();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function checks() {
|
||||
navigator.mozApps.mgmt.getAll().onsuccess = function() {
|
||||
for (i in this.result) {
|
||||
|
|
|
@ -204,14 +204,12 @@ function startTest()
|
|||
is(localStorage.getItem(null), "test");
|
||||
is(localStorage["null"], "test");
|
||||
localStorage.removeItem(null, "test");
|
||||
// bug 350023
|
||||
todo_is("null" in localStorage, false);
|
||||
is("null" in localStorage, false);
|
||||
|
||||
localStorage.setItem(null, "test");
|
||||
is("null" in localStorage, true);
|
||||
localStorage.removeItem("null", "test");
|
||||
// bug 350023
|
||||
todo_is("null" in localStorage, false);
|
||||
is("null" in localStorage, false);
|
||||
|
||||
// Clear the storage
|
||||
localStorage.clear();
|
||||
|
|
|
@ -207,14 +207,12 @@ function doTest() {
|
|||
is(privateWin.content.localStorage.getItem(null), "test");
|
||||
is(privateWin.content.localStorage["null"], "test");
|
||||
privateWin.content.localStorage.removeItem(null, "test");
|
||||
// bug 350023
|
||||
todo_is("null" in privateWin.content.localStorage, false);
|
||||
is("null" in privateWin.content.localStorage, false);
|
||||
|
||||
privateWin.content.localStorage.setItem(null, "test");
|
||||
is("null" in privateWin.content.localStorage, true);
|
||||
privateWin.content.localStorage.removeItem("null", "test");
|
||||
// bug 350023
|
||||
todo_is("null" in privateWin.content.localStorage, false);
|
||||
is("null" in privateWin.content.localStorage, false);
|
||||
|
||||
// Clear the storage
|
||||
privateWin.content.localStorage.clear();
|
||||
|
|
|
@ -169,14 +169,12 @@ function test1() {
|
|||
is(localStorage.getItem(null), "test");
|
||||
is(localStorage["null"], "test");
|
||||
localStorage.removeItem(null, "test");
|
||||
// bug 350023
|
||||
todo_is("null" in localStorage, false);
|
||||
is("null" in localStorage, false);
|
||||
|
||||
localStorage.setItem(null, "test");
|
||||
is("null" in localStorage, true);
|
||||
localStorage.removeItem("null", "test");
|
||||
// bug 350023
|
||||
todo_is("null" in localStorage, false);
|
||||
is("null" in localStorage, false);
|
||||
|
||||
// Clear the storage
|
||||
localStorage.clear();
|
||||
|
|
|
@ -19,7 +19,7 @@ function startTest()
|
|||
|
||||
var uri = ios.newURI(url, "", null);
|
||||
var principal = ssm.getNoAppCodebasePrincipal(uri);
|
||||
var storage = dsm.createStorage(principal, "");
|
||||
var storage = dsm.createStorage(window, principal, "");
|
||||
|
||||
storage.setItem("chromekey", "chromevalue");
|
||||
|
||||
|
|
|
@ -191,14 +191,12 @@ function test1() {
|
|||
is(sessionStorage.getItem(null), "test");
|
||||
is(sessionStorage["null"], "test");
|
||||
sessionStorage.removeItem(null, "test");
|
||||
// bug 350023
|
||||
todo_is("null" in sessionStorage, false);
|
||||
is("null" in sessionStorage, false);
|
||||
|
||||
sessionStorage.setItem(null, "test");
|
||||
is("null" in sessionStorage, true);
|
||||
sessionStorage.removeItem("null", "test");
|
||||
// bug 350023
|
||||
todo_is("null" in sessionStorage, false);
|
||||
is("null" in sessionStorage, false);
|
||||
|
||||
// Clear the storage
|
||||
sessionStorage.clear();
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* The origin of this IDL file is
|
||||
* http://www.whatwg.org/html/#the-storage-interface
|
||||
*
|
||||
* © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and
|
||||
* Opera Software ASA. You are granted a license to use, reproduce
|
||||
* and create derivative works of this document.
|
||||
*/
|
||||
|
||||
interface Storage {
|
||||
[Throws]
|
||||
readonly attribute unsigned long length;
|
||||
|
||||
[Throws]
|
||||
DOMString? key(unsigned long index);
|
||||
|
||||
[Throws]
|
||||
getter DOMString? getItem(DOMString key);
|
||||
|
||||
[Throws]
|
||||
setter creator void setItem(DOMString key, DOMString value);
|
||||
|
||||
[Throws]
|
||||
deleter void removeItem(DOMString key);
|
||||
|
||||
[Throws]
|
||||
void clear();
|
||||
};
|
|
@ -9,7 +9,6 @@
|
|||
*
|
||||
* Event sent to a window when a storage area changes.
|
||||
*/
|
||||
interface Storage;
|
||||
|
||||
[Constructor(DOMString type, optional StorageEventInit eventInitDict)]
|
||||
interface StorageEvent : Event
|
||||
|
|
|
@ -325,6 +325,7 @@ WEBIDL_FILES = [
|
|||
'SimpleGestureEvent.webidl',
|
||||
'SourceBuffer.webidl',
|
||||
'SourceBufferList.webidl',
|
||||
'Storage.webidl',
|
||||
'StorageEvent.webidl',
|
||||
'StorageType.webidl',
|
||||
'StyleSheet.webidl',
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
#include "nsIWindowProvider.h"
|
||||
#include "nsIMutableArray.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsIDOMStorage.h"
|
||||
#include "nsIDOMStorageManager.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsFocusManager.h"
|
||||
|
@ -60,6 +59,7 @@
|
|||
#include "nsIPrefService.h"
|
||||
#include "nsSandboxFlags.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/dom/DOMStorage.h"
|
||||
|
||||
#ifdef USEWEAKREFS
|
||||
#include "nsIWeakReference.h"
|
||||
|
@ -951,9 +951,17 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow *aParent,
|
|||
|
||||
if (parentStorageManager && newStorageManager) {
|
||||
nsCOMPtr<nsIDOMStorage> storage;
|
||||
parentStorageManager->GetStorage(subjectPrincipal, isPrivateBrowsingWindow, getter_AddRefs(storage));
|
||||
if (storage)
|
||||
nsCOMPtr<nsPIDOMWindow> pWin = do_QueryInterface(aParent);
|
||||
nsCOMPtr<nsPIDOMWindow> pInnerWin = pWin->IsInnerWindow()
|
||||
? pWin.get()
|
||||
: pWin->GetCurrentInnerWindow();
|
||||
|
||||
parentStorageManager->GetStorage(pInnerWin, subjectPrincipal,
|
||||
isPrivateBrowsingWindow,
|
||||
getter_AddRefs(storage));
|
||||
if (storage) {
|
||||
newStorageManager->CloneStorage(storage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,14 +32,6 @@ members = [
|
|||
#'nsIDOMLocation.hostname',
|
||||
#'nsIDOMLocation.href',
|
||||
|
||||
# dom/interfaces/storage
|
||||
'nsIDOMStorage.setItem',
|
||||
'nsIDOMStorage.length',
|
||||
'nsIDOMStorage.getItem',
|
||||
'nsIDOMStorage.key',
|
||||
'nsIDOMStorage.removeItem',
|
||||
'nsIDOMStorage.clear',
|
||||
|
||||
# dom/interfaces/xpath
|
||||
'nsIDOMXPathNSResolver.lookupNamespaceURI',
|
||||
|
||||
|
@ -70,18 +62,6 @@ customIncludes = [
|
|||
'mozilla/dom/WindowBinding.h',
|
||||
]
|
||||
|
||||
nsIDOMStorage_Clear_customMethodCallCode = """
|
||||
rv = self->Clear();
|
||||
if (NS_SUCCEEDED(rv))
|
||||
JS_ClearNonGlobalObject(cx, obj);
|
||||
"""
|
||||
|
||||
customMethodCalls = {
|
||||
'nsIDOMStorage_Clear': {
|
||||
'code': nsIDOMStorage_Clear_customMethodCallCode
|
||||
},
|
||||
}
|
||||
|
||||
newBindingProperties = {
|
||||
# Once the last entry here goes away, we can make the sNativePropertyHooks
|
||||
# of bindings static.
|
||||
|
|
|
@ -97,7 +97,7 @@ FrameWorker.prototype = {
|
|||
|
||||
// Bug 798660 - XHR, WebSocket and Worker have issues in a sandbox and need
|
||||
// to be unwrapped to work
|
||||
let needsWaive = ['XMLHttpRequest', 'WebSocket', 'Worker'];
|
||||
let needsWaive = ['XMLHttpRequest', 'WebSocket', 'Worker' ];
|
||||
// Methods need to be bound with the proper |this|.
|
||||
let needsBind = ['atob', 'btoa', 'dump', 'setInterval', 'clearInterval',
|
||||
'setTimeout', 'clearTimeout'];
|
||||
|
|
|
@ -106,6 +106,10 @@ function markOutMatched(toBeEmptied, data, deleted) {
|
|||
ok(toBeEmptied[storageType][host], "Host " + host + " found");
|
||||
if (!deleted) {
|
||||
for (let item of data[storageType][host]) {
|
||||
if ([ 'length', 'key', 'getItem', 'setItem',
|
||||
'removeItem', 'clear'].indexOf(item) != -1) {
|
||||
continue;
|
||||
}
|
||||
let index = toBeEmptied[storageType][host].indexOf(item);
|
||||
ok(index > -1, "Item found - " + item);
|
||||
if (index > -1) {
|
||||
|
|
|
@ -10,6 +10,8 @@ const {StorageFront} = require("devtools/server/actors/storage");
|
|||
let {Task} = require("resource://gre/modules/Task.jsm");
|
||||
let gWindow = null;
|
||||
|
||||
const domStorageProperties = ['length', 'key', 'getItem','setItem', 'removeItem', 'clear'];
|
||||
|
||||
const storeMap = {
|
||||
cookies: {
|
||||
"test1.example.org": [
|
||||
|
@ -419,9 +421,13 @@ function testLocalStorage(localStorageActor) {
|
|||
let testLocalStorageObjects = Task.async(function*(index, hosts, localStorageActor) {
|
||||
let host = Object.keys(hosts)[index];
|
||||
let matchItems = data => {
|
||||
is(data.total, storeMap.localStorage[host].length,
|
||||
is(data.total - domStorageProperties.length, storeMap.localStorage[host].length,
|
||||
"Number of local storage items in host " + host + " matches");
|
||||
for (let item of data.data) {
|
||||
if (domStorageProperties.indexOf(item.name) != -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let found = false;
|
||||
for (let toMatch of storeMap.localStorage[host]) {
|
||||
if (item.name == toMatch.name) {
|
||||
|
@ -456,9 +462,13 @@ function testSessionStorage(sessionStorageActor) {
|
|||
let testSessionStorageObjects = Task.async(function*(index, hosts, sessionStorageActor) {
|
||||
let host = Object.keys(hosts)[index];
|
||||
let matchItems = data => {
|
||||
is(data.total, storeMap.sessionStorage[host].length,
|
||||
is(data.total - domStorageProperties.length, storeMap.sessionStorage[host].length,
|
||||
"Number of session storage items in host " + host + " matches");
|
||||
for (let item of data.data) {
|
||||
if (domStorageProperties.indexOf(item.name) != -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let found = false;
|
||||
for (let toMatch of storeMap.sessionStorage[host]) {
|
||||
if (item.name == toMatch.name) {
|
||||
|
|
|
@ -673,7 +673,7 @@ function test_storage_cleared()
|
|||
getNoAppCodebasePrincipal(aURI);
|
||||
let dsm = Cc["@mozilla.org/dom/localStorage-manager;1"].
|
||||
getService(Ci.nsIDOMStorageManager);
|
||||
return dsm.createStorage(principal, "");
|
||||
return dsm.createStorage(null, principal, "");
|
||||
}
|
||||
|
||||
let s = [
|
||||
|
|
Загрузка…
Ссылка в новой задаче