forked from mirrors/gecko-dev
		
	 fde06f6d21
			
		
	
	
		fde06f6d21
		
	
	
	
	
		
			
			Also add some missing namespace qualifications
Done with:
./mach static-analysis check --checks="-*,modernize-concat-nested-namespaces" --fix dom/
./mach clang-format -p $(hg status dom/|grep ^M|awk '{print $2}')
Differential Revision: https://phabricator.services.mozilla.com/D95456
		
	
			
		
			
				
	
	
		
			147 lines
		
	
	
	
		
			4.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			147 lines
		
	
	
	
		
			4.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | |
| /* vim: set ts=8 sts=2 et sw=2 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/. */
 | |
| 
 | |
| #include "DebuggerNotificationObserver.h"
 | |
| 
 | |
| #include "DebuggerNotification.h"
 | |
| #include "nsIGlobalObject.h"
 | |
| #include "WrapperFactory.h"
 | |
| 
 | |
| namespace mozilla::dom {
 | |
| 
 | |
| NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DebuggerNotificationObserver,
 | |
|                                       mOwnerGlobal, mEventListenerCallbacks)
 | |
| 
 | |
| NS_IMPL_CYCLE_COLLECTING_ADDREF(DebuggerNotificationObserver)
 | |
| NS_IMPL_CYCLE_COLLECTING_RELEASE(DebuggerNotificationObserver)
 | |
| 
 | |
| NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DebuggerNotificationObserver)
 | |
|   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
 | |
| NS_INTERFACE_MAP_END
 | |
| 
 | |
| /* static */ already_AddRefed<DebuggerNotificationObserver>
 | |
| DebuggerNotificationObserver::Constructor(GlobalObject& aGlobal,
 | |
|                                           ErrorResult& aRv) {
 | |
|   nsCOMPtr<nsIGlobalObject> globalInterface(
 | |
|       do_QueryInterface(aGlobal.GetAsSupports()));
 | |
|   if (NS_WARN_IF(!globalInterface)) {
 | |
|     aRv.Throw(NS_ERROR_FAILURE);
 | |
|     return nullptr;
 | |
|   }
 | |
| 
 | |
|   RefPtr<DebuggerNotificationObserver> observer(
 | |
|       new DebuggerNotificationObserver(globalInterface));
 | |
|   return observer.forget();
 | |
| }
 | |
| 
 | |
| DebuggerNotificationObserver::DebuggerNotificationObserver(
 | |
|     nsIGlobalObject* aOwnerGlobal)
 | |
|     : mEventListenerCallbacks(), mOwnerGlobal(aOwnerGlobal) {}
 | |
| 
 | |
| JSObject* DebuggerNotificationObserver::WrapObject(
 | |
|     JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
 | |
|   return DebuggerNotificationObserver_Binding::Wrap(aCx, this, aGivenProto);
 | |
| }
 | |
| 
 | |
| static already_AddRefed<DebuggerNotificationManager> GetManager(
 | |
|     JSContext* aCx, JS::Handle<JSObject*> aDebuggeeGlobal) {
 | |
|   // The debuggee global here is likely a debugger-compartment cross-compartment
 | |
|   // wrapper for the debuggee global object, so we need to unwrap it to get
 | |
|   // the real debuggee-compartment global object.
 | |
|   JS::Rooted<JSObject*> debuggeeGlobalRooted(
 | |
|       aCx, js::UncheckedUnwrap(aDebuggeeGlobal, false));
 | |
| 
 | |
|   if (!debuggeeGlobalRooted) {
 | |
|     return nullptr;
 | |
|   }
 | |
| 
 | |
|   nsCOMPtr<nsIGlobalObject> debuggeeGlobalObject(
 | |
|       xpc::NativeGlobal(debuggeeGlobalRooted));
 | |
|   if (!debuggeeGlobalObject) {
 | |
|     return nullptr;
 | |
|   }
 | |
| 
 | |
|   RefPtr<DebuggerNotificationManager> manager(
 | |
|       debuggeeGlobalObject->GetOrCreateDebuggerNotificationManager());
 | |
|   return manager.forget();
 | |
| }
 | |
| 
 | |
| bool DebuggerNotificationObserver::Connect(
 | |
|     JSContext* aCx, JS::Handle<JSObject*> aDebuggeeGlobal, ErrorResult& aRv) {
 | |
|   RefPtr<DebuggerNotificationManager> manager(GetManager(aCx, aDebuggeeGlobal));
 | |
| 
 | |
|   if (!manager) {
 | |
|     aRv.Throw(NS_ERROR_FAILURE);
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   return manager->Attach(this);
 | |
| }
 | |
| 
 | |
| bool DebuggerNotificationObserver::Disconnect(
 | |
|     JSContext* aCx, JS::Handle<JSObject*> aDebuggeeGlobal, ErrorResult& aRv) {
 | |
|   RefPtr<DebuggerNotificationManager> manager(GetManager(aCx, aDebuggeeGlobal));
 | |
| 
 | |
|   if (!manager) {
 | |
|     aRv.Throw(NS_ERROR_FAILURE);
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   return manager->Detach(this);
 | |
| }
 | |
| 
 | |
| bool DebuggerNotificationObserver::AddListener(
 | |
|     DebuggerNotificationCallback& aHandlerFn) {
 | |
|   const auto [begin, end] = mEventListenerCallbacks.NonObservingRange();
 | |
|   if (std::any_of(begin, end,
 | |
|                   [&](const RefPtr<DebuggerNotificationCallback>& callback) {
 | |
|                     return *callback == aHandlerFn;
 | |
|                   })) {
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   RefPtr<DebuggerNotificationCallback> handlerFn(&aHandlerFn);
 | |
|   mEventListenerCallbacks.AppendElement(handlerFn);
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| bool DebuggerNotificationObserver::RemoveListener(
 | |
|     DebuggerNotificationCallback& aHandlerFn) {
 | |
|   for (nsTObserverArray<RefPtr<DebuggerNotificationCallback>>::ForwardIterator
 | |
|            iter(mEventListenerCallbacks);
 | |
|        iter.HasMore();) {
 | |
|     if (*iter.GetNext().get() == aHandlerFn) {
 | |
|       iter.Remove();
 | |
|       return true;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return false;
 | |
| }
 | |
| 
 | |
| bool DebuggerNotificationObserver::HasListeners() {
 | |
|   return !mEventListenerCallbacks.IsEmpty();
 | |
| }
 | |
| 
 | |
| void DebuggerNotificationObserver::NotifyListeners(
 | |
|     DebuggerNotification* aNotification) {
 | |
|   if (!HasListeners()) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   // Since we want the notification objects to live in the same compartment
 | |
|   // as the observer, we create a new instance of the notification before
 | |
|   // an observer dispatches the event listeners.
 | |
|   RefPtr<DebuggerNotification> debuggerNotification(
 | |
|       aNotification->CloneInto(mOwnerGlobal));
 | |
| 
 | |
|   for (RefPtr<DebuggerNotificationCallback> callback :
 | |
|        mEventListenerCallbacks.ForwardRange()) {
 | |
|     callback->Call(*debuggerNotification);
 | |
|   }
 | |
| }
 | |
| 
 | |
| }  // namespace mozilla::dom
 |