merge m-c to fx-team

This commit is contained in:
Tim Taubert 2012-04-01 18:52:12 +02:00
commit 895f7fcd35
4 changed files with 103 additions and 18 deletions

View File

@ -8530,17 +8530,12 @@ nsGlobalWindow::Observe(nsISupports* aSubject, const char* aTopic,
nsCOMPtr<nsPIDOMStorage> pistorage = do_QueryInterface(changingStorage);
nsPIDOMStorage::nsDOMStorageType storageType = pistorage->StorageType();
bool fireMozStorageChanged = false;
principal = GetPrincipal();
switch (storageType)
{
case nsPIDOMStorage::SessionStorage:
{
if (SameCOMIdentity(mSessionStorage, changingStorage)) {
// Do not fire any events for the same storage object, it's not shared
// among windows, see nsGlobalWindow::GetSessionStoarge()
return NS_OK;
}
nsCOMPtr<nsIDOMStorage> storage = mSessionStorage;
if (!storage) {
nsIDocShell* docShell = GetDocShell();
@ -8566,16 +8561,11 @@ nsGlobalWindow::Observe(nsISupports* aSubject, const char* aTopic,
}
#endif
fireMozStorageChanged = SameCOMIdentity(mSessionStorage, changingStorage);
break;
}
case nsPIDOMStorage::LocalStorage:
{
if (SameCOMIdentity(mLocalStorage, changingStorage)) {
// Do not fire any events for the same storage object, it's not shared
// among windows, see nsGlobalWindow::GetLocalStoarge()
return NS_OK;
}
// Allow event fire only for the same principal storages
// XXX We have to use EqualsIgnoreDomain after bug 495337 lands
nsIPrincipal *storagePrincipal = pistorage->Principal();
@ -8587,12 +8577,31 @@ nsGlobalWindow::Observe(nsISupports* aSubject, const char* aTopic,
if (!equals)
return NS_OK;
fireMozStorageChanged = SameCOMIdentity(mLocalStorage, changingStorage);
break;
}
default:
return NS_OK;
}
// Clone the storage event included in the observer notification. We want
// to dispatch clones rather than the original event.
rv = CloneStorageEvent(fireMozStorageChanged ?
NS_LITERAL_STRING("MozStorageChanged") :
NS_LITERAL_STRING("storage"),
event);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(event, &rv);
NS_ENSURE_SUCCESS(rv, rv);
privateEvent->SetTrusted(true);
if (fireMozStorageChanged) {
nsEvent *internalEvent = privateEvent->GetInternalNSEvent();
internalEvent->flags |= NS_EVENT_FLAG_ONLY_CHROME_DISPATCH;
}
if (IsFrozen()) {
// This window is frozen, rather than firing the events here,
// store the domain in which the change happened and fire the
@ -8628,6 +8637,38 @@ nsGlobalWindow::Observe(nsISupports* aSubject, const char* aTopic,
return NS_ERROR_FAILURE;
}
nsresult
nsGlobalWindow::CloneStorageEvent(const nsAString& aType,
nsCOMPtr<nsIDOMStorageEvent>& aEvent)
{
nsresult rv;
bool canBubble;
bool cancelable;
nsAutoString key;
nsAutoString oldValue;
nsAutoString newValue;
nsAutoString url;
nsCOMPtr<nsIDOMStorage> storageArea;
nsCOMPtr<nsIDOMEvent> domEvent = do_QueryInterface(aEvent, &rv);
NS_ENSURE_SUCCESS(rv, rv);
domEvent->GetBubbles(&canBubble);
domEvent->GetCancelable(&cancelable);
aEvent->GetKey(key);
aEvent->GetOldValue(oldValue);
aEvent->GetNewValue(newValue);
aEvent->GetUrl(url);
aEvent->GetStorageArea(getter_AddRefs(storageArea));
aEvent = new nsDOMStorageEvent();
return aEvent->InitStorageEvent(aType, canBubble, cancelable,
key, oldValue, newValue,
url, storageArea);
}
static PLDHashOperator
FirePendingStorageEvents(const nsAString& aKey, bool aData, void *userArg)
{

View File

@ -806,6 +806,8 @@ protected:
nsresult CreateOuterObject(nsGlobalWindow* aNewInner);
nsresult SetOuterObject(JSContext* aCx, JSObject* aOuterObject);
nsresult CloneStorageEvent(const nsAString& aType,
nsCOMPtr<nsIDOMStorageEvent>& aEvent);
// When adding new member variables, be careful not to create cycles
// through JavaScript. If there is any chance that a member variable

View File

@ -7,6 +7,8 @@
<script type="text/javascript">
var MOZ_STORAGE_CHANGED_COUNT = 14;
function startTest()
{
// Initially check the localStorage is empty
@ -26,6 +28,17 @@ function startTest()
is(typeof localStorage["nonexisting2"], "object", "['nonexisting2'] is object");
is(typeof localStorage.nonexisting2, "object", "nonexisting2 is object");
var mozStorageChangedReceived = 0;
var localStorageCopy = localStorage;
function onStorageChanged(e) {
if (e.storageArea == localStorageCopy)
mozStorageChangedReceived++;
}
// Listen for MozStorageChanged
SpecialPowers.addChromeEventListener("MozStorageChanged", onStorageChanged, false);
// add an empty-value key
localStorage.setItem("empty", "");
is(localStorage.getItem("empty"), "", "Empty value (getItem())");
@ -161,8 +174,14 @@ function startTest()
localStorage.removeItem("key1"); // Just check there is no exception
localStorage.removeItem("key2"); // Just check there is no exception
localStorage.clear();
SimpleTest.finish();
SimpleTest.executeSoon(function () {
SpecialPowers.removeChromeEventListener("MozStorageChanged", onStorageChanged, false);
is(mozStorageChangedReceived, MOZ_STORAGE_CHANGED_COUNT,
"received the correct number of events");
localStorage.clear();
SimpleTest.finish();
});
}
SimpleTest.waitForExplicitFinish();

View File

@ -7,10 +7,15 @@
<script type="text/javascript">
var MOZ_STORAGE_CHANGED_COUNT = 8;
function setup() {
sessionStorage.clear();
SimpleTest.executeSoon(startTest);
}
function startTest()
{
sessionStorage.clear();
// Initially check the sessionStorage is empty
is(sessionStorage.length, 0, "The storage is empty [1]");
is(sessionStorage.key(0), null, "key() should return null for out-of-bounds access");
@ -28,6 +33,17 @@ function startTest()
is(typeof sessionStorage["nonexisting2"], "object", "['nonexisting2'] is object");
is(typeof sessionStorage.nonexisting2, "object", "nonexisting2 is object");
var mozStorageChangedReceived = 0;
var sessionStorageCopy = sessionStorage;
function onStorageChanged(e) {
if (e.storageArea == sessionStorageCopy)
mozStorageChangedReceived++;
}
// Listen for MozStorageChanged
SpecialPowers.addChromeEventListener("MozStorageChanged", onStorageChanged, false);
// add an empty-value key
sessionStorage.setItem("empty", "");
is(sessionStorage.getItem("empty"), "", "Empty value (getItem())");
@ -130,7 +146,14 @@ function startTest()
sessionStorage.removeItem("key1"); // Just check there is no exception
sessionStorage.removeItem("key2"); // Just check there is no exception
SimpleTest.finish();
SimpleTest.executeSoon(function () {
SpecialPowers.removeChromeEventListener("MozStorageChanged", onStorageChanged, false);
is(mozStorageChangedReceived, MOZ_STORAGE_CHANGED_COUNT,
"received the correct number of events");
sessionStorage.clear();
SimpleTest.finish();
});
}
SimpleTest.waitForExplicitFinish();
@ -139,7 +162,7 @@ SimpleTest.waitForExplicitFinish();
</head>
<body onload="startTest();">
<body onload="setup();">
</body>
</html>