/* 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/. */ #import #include "nsIXPConnect.h" #include "nsIObserver.h" #include "nsIDOMWindow.h" #include "nsIJSContextStack.h" #include "nsServiceManagerUtils.h" @interface ObserverPair : NSObject { @public nsIObserver *observer; nsIDOMWindow *window; } - (id) initWithObserver:(nsIObserver *)aObserver window:(nsIDOMWindow *)aWindow; - (void) dealloc; @end /** * Returns the DOM window that owns the given observer in the case that the * observer is implemented in JS and was created in a DOM window's scope. * * We need this so that we can properly clean up in cases where the window gets * closed before the growl timeout/click notifications have fired. Otherwise we * leak those windows. */ static already_AddRefed __attribute__((unused)) GetWindowOfObserver(nsIObserver* aObserver) { nsCOMPtr wrappedJS(do_QueryInterface(aObserver)); if (!wrappedJS) { // We can't do anything with objects that aren't implemented in JS... return nullptr; } JSObject* obj; nsresult rv = wrappedJS->GetJSObject(&obj); NS_ENSURE_SUCCESS(rv, nullptr); nsCOMPtr stack = do_GetService("@mozilla.org/js/xpc/ContextStack;1", &rv); NS_ENSURE_SUCCESS(rv, nullptr); JSContext* cx = stack->GetSafeJSContext(); NS_ENSURE_TRUE(cx, nullptr); JSAutoRequest ar(cx); JSAutoCompartment ac(cx, obj); JSObject* global = JS_GetGlobalForObject(cx, obj); NS_ENSURE_TRUE(global, nullptr); nsCOMPtr xpc(do_GetService(nsIXPConnect::GetCID())); NS_ENSURE_TRUE(xpc, nullptr); nsCOMPtr wrapper; rv = xpc->GetWrappedNativeOfJSObject(cx, global, getter_AddRefs(wrapper)); NS_ENSURE_SUCCESS(rv, nullptr); nsCOMPtr window = do_QueryWrappedNative(wrapper); NS_ENSURE_TRUE(window, nullptr); return window.forget(); }